|
@@ -2,6 +2,12 @@
|
2
|
2
|
|
3
|
3
|
static pyfcgi_stats_t pyfcgi_stats;
|
4
|
4
|
|
|
5
|
+static void pyfcgi_stats_add_sample(pyfcgi_stats_sample_t* samples, int sample)
|
|
6
|
+{
|
|
7
|
+ samples->samples[samples->cur] = sample;
|
|
8
|
+ samples->cur++;
|
|
9
|
+}
|
|
10
|
+
|
5
|
11
|
int pyfcgi_stats_init()
|
6
|
12
|
{
|
7
|
13
|
struct sigaction act;
|
|
@@ -54,18 +60,26 @@ void pyfcgi_stats_collector(int signum)
|
54
|
60
|
{
|
55
|
61
|
int ret;
|
56
|
62
|
pyfcgi_stats_t *stats;
|
|
63
|
+ pyfcgi_stats_shm_t shm_data;
|
57
|
64
|
|
58
|
65
|
stats = &pyfcgi_stats;
|
59
|
66
|
|
60
|
|
- stats->reqs[stats->cur_req] = 0;
|
|
67
|
+ stats->reqs.samples[stats->reqs.cur] = 0;
|
61
|
68
|
while( !(ret = sem_trywait(PyFCGI_SEM(SEM_WREQS).sem)) )
|
62
|
69
|
{
|
63
|
|
- stats->reqs[stats->cur_req]++;
|
|
70
|
+ stats->reqs.samples[stats->reqs.cur]++;
|
|
71
|
+ }
|
|
72
|
+ stats->reqs.cur++;
|
|
73
|
+ stats->reqs.cur %= PYFCGI_STATS_SZ;
|
|
74
|
+
|
|
75
|
+ if(pyfcgi_stats_get_shm(&shm_data) < 0)
|
|
76
|
+ {
|
|
77
|
+ kill(getpid(), SIGTERM);
|
64
|
78
|
}
|
65
|
|
- pyfcgi_log(LOG_DEBUG, "s#%d %d req/s", pyfcgi_stats.cur_req,
|
66
|
|
- pyfcgi_stats.reqs[stats->cur_req]);
|
67
|
|
- stats->cur_req++;
|
68
|
|
- stats->cur_req %= PYFCGI_STATS_SZ;
|
|
79
|
+
|
|
80
|
+ pyfcgi_stats_add_sample(&(stats->wcount), shm_data.nworker);
|
|
81
|
+ pyfcgi_stats_add_sample(&(stats->load),
|
|
82
|
+ shm_data.nworker - shm_data.pool_load);
|
69
|
83
|
|
70
|
84
|
return;
|
71
|
85
|
}
|
|
@@ -113,11 +127,37 @@ size_t pyfcgi_stats_format()
|
113
|
127
|
|
114
|
128
|
do
|
115
|
129
|
{
|
116
|
|
- ret = pyfcgi_stats_avg(pyfcgi_stats.reqs,
|
117
|
|
- &(pyfcgi_stats.cur_req), &last_rs, avgs);
|
|
130
|
+ last_rs = pyfcgi_stats.reqs.cur;
|
|
131
|
+ ret = pyfcgi_stats_avg(pyfcgi_stats.reqs.samples,
|
|
132
|
+ &(pyfcgi_stats.reqs.cur), &last_rs, avgs);
|
118
|
133
|
} while(ret < 0 && errno == EINTR);
|
|
134
|
+
|
119
|
135
|
pyfcgi_stats_buffprintf("Requests stats :\n1s:%dr/s 1m:%.2fr/s 5m:%.2fr/s 10m:%.2fr/s 15m:%.2fr/s\n",
|
120
|
136
|
last_rs, avgs[0], avgs[1], avgs[2], avgs[3]);
|
|
137
|
+
|
|
138
|
+ // Worker counter stats formating
|
|
139
|
+ do
|
|
140
|
+ {
|
|
141
|
+ last_rs = pyfcgi_stats.wcount.cur;
|
|
142
|
+ pyfcgi_stats_avg(pyfcgi_stats.wcount.samples,&(pyfcgi_stats.wcount.cur),
|
|
143
|
+ &(last_rs), avgs);
|
|
144
|
+ } while(ret < 0 && errno == EINTR);
|
|
145
|
+
|
|
146
|
+ pyfcgi_stats_buffprintf("Worker count :\n1s:%d 1m:%.2f 5m:%.2f 10m:%.2f 15m:%.2f\n",
|
|
147
|
+ last_rs, avgs[0], avgs[1], avgs[2], avgs[3]);
|
|
148
|
+
|
|
149
|
+ // Load stats formating
|
|
150
|
+ do
|
|
151
|
+ {
|
|
152
|
+ last_rs = pyfcgi_stats.load.cur;
|
|
153
|
+ pyfcgi_stats_avg(pyfcgi_stats.load.samples,&(pyfcgi_stats.load.cur),
|
|
154
|
+ &(last_rs), avgs);
|
|
155
|
+ } while(ret < 0 && errno == EINTR);
|
|
156
|
+
|
|
157
|
+ pyfcgi_stats_buffprintf("Load average :\n1s:%d 1m:%.2f 5m:%.2f 10m:%.2f 15m:%.2f\n",
|
|
158
|
+ last_rs, avgs[0], avgs[1], avgs[2], avgs[3]);
|
|
159
|
+
|
|
160
|
+
|
121
|
161
|
return pyfcgi_stats.buff_ptr;
|
122
|
162
|
}
|
123
|
163
|
|
|
@@ -155,6 +195,7 @@ int pyfcgi_stats_avg(const int data[PYFCGI_STATS_SZ], int *idx_nxt, int *last,
|
155
|
195
|
if(i<=15*60) { r15 += rtmp; }
|
156
|
196
|
stmp = cur;
|
157
|
197
|
}
|
|
198
|
+ r15 += (long double)stmp / 60;
|
158
|
199
|
//Restore interrupt/ALARM ??
|
159
|
200
|
r5 /= 5;
|
160
|
201
|
r10 /= 10;
|
|
@@ -273,3 +314,52 @@ const char *pyfcgi_stats_buff(const char **buff, size_t* len)
|
273
|
314
|
*len = pyfcgi_stats.buff_ptr;
|
274
|
315
|
return *buff;
|
275
|
316
|
}
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+int pyfcgi_stats_get_shm(pyfcgi_stats_shm_t *res)
|
|
320
|
+{
|
|
321
|
+ short retry;
|
|
322
|
+ int err;
|
|
323
|
+ struct timespec req;
|
|
324
|
+
|
|
325
|
+ req.tv_sec = 0;
|
|
326
|
+ req.tv_nsec = 10000000; //0.01s
|
|
327
|
+
|
|
328
|
+ retry = 0;
|
|
329
|
+
|
|
330
|
+ while(1)
|
|
331
|
+ {
|
|
332
|
+ if(sem_trywait(PyFCGI_SEM(SEM_STATS).sem) < 0)
|
|
333
|
+ {
|
|
334
|
+ err = errno;
|
|
335
|
+ if(err == EAGAIN)
|
|
336
|
+ {
|
|
337
|
+ if(retry >= 5)
|
|
338
|
+ {
|
|
339
|
+ pyfcgi_log(LOG_ALERT,
|
|
340
|
+ "Deadlock on SEM_STATS");
|
|
341
|
+ return -1;
|
|
342
|
+ }
|
|
343
|
+ nanosleep(&req, NULL);
|
|
344
|
+ continue;
|
|
345
|
+ }
|
|
346
|
+ pyfcgi_log(LOG_ALERT,
|
|
347
|
+ "Unable to wait stats semaphore : %s",
|
|
348
|
+ strerror(err));
|
|
349
|
+ return -1;
|
|
350
|
+ }
|
|
351
|
+ break;
|
|
352
|
+ }
|
|
353
|
+
|
|
354
|
+ *res = *(pyfcgi_stats_shm_t*)PyFCGI_conf.shm.ptr;
|
|
355
|
+
|
|
356
|
+ if(sem_post(PyFCGI_SEM(SEM_STATS).sem) < 0)
|
|
357
|
+ {
|
|
358
|
+ pyfcgi_log(LOG_ALERT, "Unable to post sem at shm update : %s",
|
|
359
|
+ strerror(errno));
|
|
360
|
+ return -1;
|
|
361
|
+ }
|
|
362
|
+ return 0;
|
|
363
|
+}
|
|
364
|
+
|
|
365
|
+
|