/* * Copyright (C) 2019 Weber Yann * * This file is part of PyFCGI. * * PyFCGI is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * PyFCGI is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with PyFCGI. If not, see . */ /**@defgroup stats PyFCGI statistics * @brief Information about statistics collection mechanism * @ingroup monitor_proc */ /**@file stats.h * @ingroup monitoring */ #ifndef _STATS__H___ #define _STATS__H___ #include "config.h" #include #include #include #include /**@brief Stats history size (900 = 900s = 15min) */ #define PYFCGI_STATS_SZ (900) /**@brief Signal used to wake up stats server in order to collect stats*/ #define PYFCGI_STATS_SIGALRM 30 typedef struct pyfcgi_stats_s pyfcgi_stats_t; typedef struct pyfcgi_stats_sample_s pyfcgi_stats_sample_t; typedef struct pyfcgi_stats_shm_s pyfcgi_stats_shm_t; #include "conf.h" #include "logger.h" /**@brief Stores data for stats on 15min (900s) * @ingroup stats */ struct pyfcgi_stats_sample_s { /**@brief One sample per seconds */ int samples[PYFCGI_STATS_SZ]; /**@brief Current sample */ int cur; }; /**@brief Stores statistics informations * @ingroup stats */ struct pyfcgi_stats_s { /**@brief Request per seconds on 15 minutes */ pyfcgi_stats_sample_t reqs; /**@brief Worker count */ pyfcgi_stats_sample_t wcount; /**@brief Load */ pyfcgi_stats_sample_t load; /**@brief Repeating 1s timer sending SIGALRM */ timer_t timerid; /**@brief Old SIGALRM handler */ struct sigaction oldact; /**@brief Buffer to format the statistics before sending them */ char *buff; size_t buff_ptr; size_t buff_len; }; /**@brief Stores stats information on worker count & load average * @note Data are updated by @ref work_master_proc */ struct pyfcgi_stats_shm_s { /**@brief Workers count */ int nworker; /**@brief Load average */ int pool_load; }; /**@brief Starts collecting statistics * * Set an handler for SIGALRM and set a repeating alarm each seconds * @warning designed to be called from monitor server process * @return -1 on error else 0 * @ingroup stats */ int pyfcgi_stats_init(); /**@brief SIGALRM signal handler * @param signum */ void pyfcgi_stats_collector(int signum); /**@brief Format all stats in a buffer * @note uses the pyfcgi_stats.statsbuff buffer */ size_t pyfcgi_stats_format(); /**@brief Print in buffer using buff_ptr index *@note exit on mem alloc failure */ void pyfcgi_stats_buffprintf(const char *fmt, ...); /**@brief Allocate the buffer with at least given space * @param sz the minimum buffer size * @note allocation size is rounded * @return 0 if OK else -1 */ int pyfcgi_stats_reqbuff(size_t sz); /**@brief Returns statistics about a 900s ringbuffer * * @param data a 900 ringbuffer stats samples * @param idx_nxt next data index in ring buffer (allow interrupt * detection : when *idx_nxt changes) * @param *last : last sample * @param avgs : average samples on 1, 5, 10 and 15 minutes * @return 0 if no error else -1 and set errno to EINTR */ int pyfcgi_stats_avg(const int data[PYFCGI_STATS_SZ], int* idx_nxt, int* last, double avgs[4]); /**@brief Same than @ref pyfcgi_stats_avg but normalize average when * uptime is bellow 900 * @see pyfcgi_stats_avg * @param data a 900 ringbuffer stats samples * @param idx_nxt next data index in ring buffer (allow interrupt * detection : when *idx_nxt changes) * @param *last : last sample * @param avgs : average samples on 1, 5, 10 and 15 minutes * @return 0 if no error else -1 and set errno to EINTR */ int pyfcgi_stats_avg_const(const int data[PYFCGI_STATS_SZ], int* idx_nxt, int* last, double avgs[4]); /**@brief Returns the formated buffer * @todo make @ref pyfcgi_stats_format() implement this functionnality * to remove this function... */ const char *pyfcgi_stats_buff(const char **, size_t*); /**@brief Fetch stats informations from dedicated SHM * @see pyfcgi_stats_shm_s */ int pyfcgi_stats_get_shm(pyfcgi_stats_shm_t*); #endif