]> arthur.barton.de Git - netdata.git/commitdiff
prevent multiple locks per web requests
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Fri, 20 May 2016 20:16:39 +0000 (23:16 +0300)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Fri, 20 May 2016 20:16:39 +0000 (23:16 +0300)
src/global_statistics.c
src/global_statistics.h
src/plugin_proc.c
src/web_client.c
src/web_client.h

index d4a04efd2d067aa32c7bf6d085a998e3522c449c..d813f66c9b9d4d31838a6d7fb44f664cdd412b9a 100644 (file)
@@ -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;
 
index ce3c3490e95c30e179a4e26a851e80bd9430cb0b..b618191656fc3d9537002ded68e4e812da8836f1 100644 (file)
@@ -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;
index a147d971f8128609d1e9416309ef7e35138e8765..5ecd7b9e459a3e7e1daa4114bb63e3f626930061 100644 (file)
@@ -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();
                }
        }
index 601dda083ae0172e4b65be9d0e9ecd3f19cc6264..f9223117eff76c6820ef7fd8d638db9a4648a55c 100644 (file)
@@ -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();
                }
        }
 
index f663be4a1d28eec1279ae90cc8798bd642762782..559c4459d9be53eefe25f4f2241aa6701490fa97 100644 (file)
@@ -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;
 };