From d4c1c51fb6819c789d08107c249b895a83a61740 Mon Sep 17 00:00:00 2001 From: "Costa Tsaousis (ktsaou)" Date: Fri, 20 May 2016 23:16:39 +0300 Subject: [PATCH] prevent multiple locks per web requests --- src/global_statistics.c | 2 +- src/global_statistics.h | 10 +++++----- src/plugin_proc.c | 29 +++++++++++++++++++++++++++-- src/web_client.c | 37 +++++++++++++++++++------------------ src/web_client.h | 3 +++ 5 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/global_statistics.c b/src/global_statistics.c index d4a04efd..d813f66c 100644 --- a/src/global_statistics.c +++ b/src/global_statistics.c @@ -5,7 +5,7 @@ #include "global_statistics.h" -struct global_statistics global_statistics = { 0ULL, 0ULL, 0ULL, 0ULL }; +struct global_statistics global_statistics = { 0, 0ULL, 0ULL, 0ULL, 0ULL}; pthread_mutex_t global_statistics_mutex = PTHREAD_MUTEX_INITIALIZER; diff --git a/src/global_statistics.h b/src/global_statistics.h index ce3c3490..b6181916 100644 --- a/src/global_statistics.h +++ b/src/global_statistics.h @@ -5,11 +5,11 @@ // global statistics struct global_statistics { - unsigned long long connected_clients; - unsigned long long web_requests; - unsigned long long bytes_received; - unsigned long long bytes_sent; - + unsigned long volatile connected_clients; + unsigned long long volatile web_requests; + unsigned long long volatile web_usec; + unsigned long long volatile bytes_received; + unsigned long long volatile bytes_sent; }; extern struct global_statistics global_statistics; diff --git a/src/plugin_proc.c b/src/plugin_proc.c index a147d971..5ecd7b9e 100644 --- a/src/plugin_proc.c +++ b/src/plugin_proc.c @@ -18,7 +18,8 @@ void *proc_main(void *ptr) { - if(ptr) { ; } + static unsigned long long old_web_requests = 0, old_web_usec = 0; + (void)ptr; info("PROC Plugin thread created with task id %d", gettid()); @@ -77,7 +78,7 @@ void *proc_main(void *ptr) unsigned long long sunext = (time(NULL) - (time(NULL) % rrd_update_every) + rrd_update_every) * 1000000ULL; unsigned long long sunow; - RRDSET *stcpu = NULL, *stcpu_thread = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL; + RRDSET *stcpu = NULL, *stcpu_thread = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL, *stduration = NULL; for(;1;) { if(unlikely(netdata_exit)) break; @@ -310,6 +311,30 @@ void *proc_main(void *ptr) // ---------------------------------------------------------------- + if(!stduration) stduration = rrdset_find("netdata.response_time"); + if(!stduration) { + stduration = rrdset_create("netdata", "response_time", NULL, "netdata", NULL, "NetData Average API Response Time", "ms/request", 130400, rrd_update_every, RRDSET_TYPE_LINE); + + rrddim_add(stduration, "response_time", "response time", 1, 1000, RRDDIM_ABSOLUTE); + } + else rrdset_next(stduration); + + unsigned long long gweb_usec = global_statistics.web_usec; + unsigned long long gweb_requests = global_statistics.web_requests; + + unsigned long long web_usec = gweb_usec - old_web_usec; + unsigned long long web_requests = gweb_requests - old_web_requests; + + old_web_usec = gweb_usec; + old_web_requests = gweb_requests; + + if(!web_requests) web_requests = 1; + + rrddim_set(stduration, "response_time", web_usec / web_requests); + rrdset_done(stduration); + + // ---------------------------------------------------------------- + registry_statistics(); } } diff --git a/src/web_client.c b/src/web_client.c index 601dda08..f9223117 100644 --- a/src/web_client.c +++ b/src/web_client.c @@ -146,6 +146,19 @@ void web_client_reset(struct web_client *w) struct timeval tv; gettimeofday(&tv, NULL); + debug(D_WEB_CLIENT, "%llu: Reseting client.", w->id); + + if(w->stats_received_bytes || w->stats_sent_bytes) { + global_statistics_lock(); + global_statistics.web_requests++; + global_statistics.web_usec += usecdiff(&tv, &w->tv_in); + global_statistics.bytes_received += w->stats_received_bytes; + global_statistics.bytes_sent += w->stats_sent_bytes; + global_statistics_unlock(); + } + w->stats_received_bytes = 0; + w->stats_sent_bytes = 0; + long sent = (w->mode == WEB_CLIENT_MODE_FILECOPY)?w->response.rlen:w->response.data->len; #ifdef NETDATA_WITH_ZLIB @@ -166,8 +179,6 @@ void web_client_reset(struct web_client *w) w->last_url ); - debug(D_WEB_CLIENT, "%llu: Reseting client.", w->id); - if(unlikely(w->mode == WEB_CLIENT_MODE_FILECOPY)) { debug(D_WEB_CLIENT, "%llu: Closing filecopy input file.", w->id); close(w->ifd); @@ -1341,10 +1352,6 @@ void web_client_process(struct web_client *w) { else { // what_to_do == 0 gettimeofday(&w->tv_in, NULL); - global_statistics_lock(); - global_statistics.web_requests++; - global_statistics_unlock(); - // copy the URL - we are going to overwrite parts of it // FIXME -- we should avoid it strncpyz(w->last_url, w->decoded_url, URL_MAX); @@ -1736,11 +1743,8 @@ void web_client_process(struct web_client *w) { , w->id , buffer_strlen(w->response.header_output) , bytes); - else { - global_statistics_lock(); - global_statistics.bytes_sent += bytes; - global_statistics_unlock(); - } + else + w->stats_sent_bytes += bytes; // enable TCP_NODELAY, to send all data immediately at the next send() flag = 1; @@ -2107,10 +2111,8 @@ void *web_client_main(void *ptr) errno = 0; break; } - - global_statistics_lock(); - global_statistics.bytes_sent += bytes; - global_statistics_unlock(); + else + w->stats_sent_bytes += bytes; } if(w->wait_receive && FD_ISSET(w->ifd, &ifds)) { @@ -2120,6 +2122,8 @@ void *web_client_main(void *ptr) errno = 0; break; } + else + w->stats_received_bytes += bytes; if(w->mode == WEB_CLIENT_MODE_NORMAL) { 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) web_client_process(w); } - global_statistics_lock(); - global_statistics.bytes_received += bytes; - global_statistics_unlock(); } } diff --git a/src/web_client.h b/src/web_client.h index f663be4a..559c4459 100644 --- a/src/web_client.h +++ b/src/web_client.h @@ -83,6 +83,9 @@ struct web_client { int wait_receive; int wait_send; + unsigned long stats_received_bytes; + unsigned long stats_sent_bytes; + struct web_client *prev; struct web_client *next; }; -- 2.39.2