prevent multiple locks per web requests
Costa Tsaousis (ktsaou) committed
May 20, 2016 at 23:16 UTC
d4c1c51fb6819c789d08107c249b895a83a61740
5 files changed
+55
-26
src/global_statistics.c
+1
-1
@@ -5,7 +5,7 @@
5
6
#include "global_statistics.h"
7
8
-struct global_statistics global_statistics = { 0ULL, 0ULL, 0ULL, 0ULL };
8
+struct global_statistics global_statistics = { 0, 0ULL, 0ULL, 0ULL, 0ULL};
9
10
pthread_mutex_t global_statistics_mutex = PTHREAD_MUTEX_INITIALIZER;
11
src/global_statistics.h
+5
-5
@@ -5,11 +5,11 @@
5
// global statistics
6
7
struct global_statistics {
8
- unsigned long long connected_clients;
9
- unsigned long long web_requests;
10
- unsigned long long bytes_received;
11
- unsigned long long bytes_sent;
12
-
8
+ unsigned long volatile connected_clients;
9
+ unsigned long long volatile web_requests;
10
+ unsigned long long volatile web_usec;
11
+ unsigned long long volatile bytes_received;
12
+ unsigned long long volatile bytes_sent;
13
};
14
15
extern struct global_statistics global_statistics;
src/plugin_proc.c
+27
-2
@@ -18,7 +18,8 @@
18
19
void *proc_main(void *ptr)
20
{
21
- if(ptr) { ; }
21
+ static unsigned long long old_web_requests = 0, old_web_usec = 0;
22
+ (void)ptr;
23
24
info("PROC Plugin thread created with task id %d", gettid());
25
@@ -77,7 +78,7 @@ void *proc_main(void *ptr)
78
unsigned long long sunext = (time(NULL) - (time(NULL) % rrd_update_every) + rrd_update_every) * 1000000ULL;
79
unsigned long long sunow;
80
80
- RRDSET *stcpu = NULL, *stcpu_thread = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL;
81
+ RRDSET *stcpu = NULL, *stcpu_thread = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL, *stduration = NULL;
82
83
for(;1;) {
84
if(unlikely(netdata_exit)) break;
@@ -310,6 +311,30 @@ void *proc_main(void *ptr)
311
312
// ----------------------------------------------------------------
313
314
+ if(!stduration) stduration = rrdset_find("netdata.response_time");
315
+ if(!stduration) {
316
+ stduration = rrdset_create("netdata", "response_time", NULL, "netdata", NULL, "NetData Average API Response Time", "ms/request", 130400, rrd_update_every, RRDSET_TYPE_LINE);
317
+
318
+ rrddim_add(stduration, "response_time", "response time", 1, 1000, RRDDIM_ABSOLUTE);
319
+ }
320
+ else rrdset_next(stduration);
321
+
322
+ unsigned long long gweb_usec = global_statistics.web_usec;
323
+ unsigned long long gweb_requests = global_statistics.web_requests;
324
+
325
+ unsigned long long web_usec = gweb_usec - old_web_usec;
326
+ unsigned long long web_requests = gweb_requests - old_web_requests;
327
+
328
+ old_web_usec = gweb_usec;
329
+ old_web_requests = gweb_requests;
330
+
331
+ if(!web_requests) web_requests = 1;
332
+
333
+ rrddim_set(stduration, "response_time", web_usec / web_requests);
334
+ rrdset_done(stduration);
335
+
336
+ // ----------------------------------------------------------------
337
+
338
registry_statistics();
339
}
340
}
src/web_client.c
+19
-18
@@ -146,6 +146,19 @@ void web_client_reset(struct web_client *w)
146
struct timeval tv;
147
gettimeofday(&tv, NULL);
148
149
+ debug(D_WEB_CLIENT, "%llu: Reseting client.", w->id);
150
+
151
+ if(w->stats_received_bytes || w->stats_sent_bytes) {
152
+ global_statistics_lock();
153
+ global_statistics.web_requests++;
154
+ global_statistics.web_usec += usecdiff(&tv, &w->tv_in);
155
+ global_statistics.bytes_received += w->stats_received_bytes;
156
+ global_statistics.bytes_sent += w->stats_sent_bytes;
157
+ global_statistics_unlock();
158
+ }
159
+ w->stats_received_bytes = 0;
160
+ w->stats_sent_bytes = 0;
161
+
162
long sent = (w->mode == WEB_CLIENT_MODE_FILECOPY)?w->response.rlen:w->response.data->len;
163
164
#ifdef NETDATA_WITH_ZLIB
@@ -166,8 +179,6 @@ void web_client_reset(struct web_client *w)
179
w->last_url
180
);
181
169
- debug(D_WEB_CLIENT, "%llu: Reseting client.", w->id);
170
-
182
if(unlikely(w->mode == WEB_CLIENT_MODE_FILECOPY)) {
183
debug(D_WEB_CLIENT, "%llu: Closing filecopy input file.", w->id);
184
close(w->ifd);
@@ -1341,10 +1352,6 @@ void web_client_process(struct web_client *w) {
1352
else { // what_to_do == 0
1353
gettimeofday(&w->tv_in, NULL);
1354
1344
- global_statistics_lock();
1345
- global_statistics.web_requests++;
1346
- global_statistics_unlock();
1347
-
1355
// copy the URL - we are going to overwrite parts of it
1356
// FIXME -- we should avoid it
1357
strncpyz(w->last_url, w->decoded_url, URL_MAX);
@@ -1736,11 +1743,8 @@ void web_client_process(struct web_client *w) {
1743
, w->id
1744
, buffer_strlen(w->response.header_output)
1745
, bytes);
1739
- else {
1740
- global_statistics_lock();
1741
- global_statistics.bytes_sent += bytes;
1742
- global_statistics_unlock();
1743
- }
1746
+ else
1747
+ w->stats_sent_bytes += bytes;
1748
1749
// enable TCP_NODELAY, to send all data immediately at the next send()
1750
flag = 1;
@@ -2107,10 +2111,8 @@ void *web_client_main(void *ptr)
2111
errno = 0;
2112
break;
2113
}
2110
-
2111
- global_statistics_lock();
2112
- global_statistics.bytes_sent += bytes;
2113
- global_statistics_unlock();
2114
+ else
2115
+ w->stats_sent_bytes += bytes;
2116
}
2117
2118
if(w->wait_receive && FD_ISSET(w->ifd, &ifds)) {
@@ -2120,6 +2122,8 @@ void *web_client_main(void *ptr)
2122
errno = 0;
2123
break;
2124
}
2125
+ else
2126
+ w->stats_received_bytes += bytes;
2127
2128
if(w->mode == WEB_CLIENT_MODE_NORMAL) {
2129
debug(D_WEB_CLIENT, "%llu: Attempting to process received data (%ld bytes).", w->id, bytes);
@@ -2127,9 +2131,6 @@ void *web_client_main(void *ptr)
2131
web_client_process(w);
2132
}
2133
2130
- global_statistics_lock();
2131
- global_statistics.bytes_received += bytes;
2132
- global_statistics_unlock();
2134
}
2135
}
2136
src/web_client.h
+3
@@ -83,6 +83,9 @@ struct web_client {
83
int wait_receive;
84
int wait_send;
85
86
+ unsigned long stats_received_bytes;
87
+ unsigned long stats_sent_bytes;
88
+
89
struct web_client *prev;
90
struct web_client *next;
91
};