@cryptotaxi247 / netdata-1 / commits / ef0c0432a

added configuration options for controlling web compression level and strategy and chart to show the savings of the compression used

Costa Tsaousis committed May 31, 2016 at 22:57 UTC ef0c0432a2425e086712b53f4b417fb89764aa29
6 files changed +119 -45
src/global_statistics.c
+1 -1
@@ -5,7 +5,7 @@
5
6 #include "global_statistics.h"
7
8 -struct global_statistics global_statistics = { 0, 0ULL, 0ULL, 0ULL, 0ULL};
8 +struct global_statistics global_statistics = { 0, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL};
9
10 pthread_mutex_t global_statistics_mutex = PTHREAD_MUTEX_INITIALIZER;
11
src/global_statistics.h
+7 -5
@@ -5,11 +5,13 @@
5 // global statistics
6
7 struct global_statistics {
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;
8 + volatile unsigned long volatile connected_clients;
9 + volatile unsigned long long volatile web_requests;
10 + volatile unsigned long long volatile web_usec;
11 + volatile unsigned long long volatile bytes_received;
12 + volatile unsigned long long volatile bytes_sent;
13 + volatile unsigned long long volatile content_size;
14 + volatile unsigned long long volatile compressed_content_size;
15 };
16
17 extern struct global_statistics global_statistics;
src/main.c
+30 -1
@@ -101,7 +101,36 @@ void web_server_threading_selection(void) {
101 }
102
103 web_client_timeout = (int) config_get_number("global", "disconnect idle web clients after seconds", DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS);
104 +
105 +#ifdef NETDATA_WITH_ZLIB
106 web_enable_gzip = config_get_boolean("global", "enable web responses gzip compression", web_enable_gzip);
107 +
108 + char *s = config_get("global", "web compression strategy", "default");
109 + if(!strcmp(s, "default"))
110 + web_gzip_strategy = Z_DEFAULT_STRATEGY;
111 + else if(!strcmp(s, "filtered"))
112 + web_gzip_strategy = Z_FILTERED;
113 + else if(!strcmp(s, "huffman only"))
114 + web_gzip_strategy = Z_HUFFMAN_ONLY;
115 + else if(!strcmp(s, "rle"))
116 + web_gzip_strategy = Z_RLE;
117 + else if(!strcmp(s, "fixed"))
118 + web_gzip_strategy = Z_FIXED;
119 + else {
120 + error("Invalid compression strategy '%s'. Valid strategies are 'default', 'filtered', 'huffman only', 'rle' and 'fixed'. Proceeding with 'default'.");
121 + web_gzip_strategy = Z_DEFAULT_STRATEGY;
122 + }
123 +
124 + web_gzip_level = (int)config_get_number("global", "web compression level", 3);
125 + if(web_gzip_level < 1) {
126 + error("Invalid compression level %d. Valid levels are 1 (fastest) to 9 (best ratio). Proceeding with level 1 (fastest compression).");
127 + web_gzip_level = 1;
128 + }
129 + else if(web_gzip_level > 9) {
130 + error("Invalid compression level %d. Valid levels are 1 (fastest) to 9 (best ratio). Proceeding with level 9 (best compression).");
131 + web_gzip_level = 9;
132 + }
133 +#endif /* NETDATA_WITH_ZLIB */
134 }
135
136
@@ -481,7 +510,7 @@ int main(int argc, char **argv)
510 error_log_throttle_period = config_get_number("global", "errors flood protection period", error_log_throttle_period);
511 setenv("NETDATA_ERRORS_THROTTLE_PERIOD", config_get("global", "errors flood protection period" , ""), 1);
512
484 - error_log_errors_per_period = config_get_number("global", "errors to trigger flood protection", error_log_errors_per_period);
513 + error_log_errors_per_period = (unsigned long)config_get_number("global", "errors to trigger flood protection", error_log_errors_per_period);
514 setenv("NETDATA_ERRORS_PER_PERIOD" , config_get("global", "errors to trigger flood protection", ""), 1);
515
516 // --------------------------------------------------------------------
src/plugin_proc.c
+39 -4
@@ -18,9 +18,13 @@
18
19 void *proc_main(void *ptr)
20 {
21 - static unsigned long long old_web_requests = 0, old_web_usec = 0;
21 (void)ptr;
22
23 + unsigned long long old_web_requests = 0, old_web_usec = 0,
24 + old_content_size = 0, old_compressed_content_size = 0;
25 +
26 + collected_number compression_ratio = -1, average_response_time = -1;
27 +
28 info("PROC Plugin thread created with task id %d", gettid());
29
30 if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
@@ -78,7 +82,8 @@ void *proc_main(void *ptr)
82 unsigned long long sunext = (time(NULL) - (time(NULL) % rrd_update_every) + rrd_update_every) * 1000000ULL;
83 unsigned long long sunow;
84
81 - RRDSET *stcpu = NULL, *stcpu_thread = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL, *stduration = NULL;
85 + RRDSET *stcpu = NULL, *stcpu_thread = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL, *stduration = NULL,
86 + *stcompression = NULL;
87
88 for(;1;) {
89 if(unlikely(netdata_exit)) break;
@@ -328,13 +333,43 @@ void *proc_main(void *ptr)
333 old_web_usec = gweb_usec;
334 old_web_requests = gweb_requests;
335
331 - if(!web_requests) web_requests = 1;
336 + if(web_requests)
337 + average_response_time = web_usec / web_requests;
338 +
339 + if(average_response_time != -1)
340 + rrddim_set(stduration, "response_time", average_response_time);
341
333 - rrddim_set(stduration, "response_time", web_usec / web_requests);
342 rrdset_done(stduration);
343
344 // ----------------------------------------------------------------
345
346 + if(!stcompression) stcompression = rrdset_find("netdata.compression_ratio");
347 + if(!stcompression) {
348 + stcompression = rrdset_create("netdata", "compression_ratio", NULL, "netdata", NULL, "NetData API Responses Compression Savings Ratio", "percentage", 130500, rrd_update_every, RRDSET_TYPE_LINE);
349 +
350 + rrddim_add(stcompression, "savings", NULL, 1, 1000, RRDDIM_ABSOLUTE);
351 + }
352 + else rrdset_next(stcompression);
353 +
354 + unsigned long long gcontent_size = global_statistics.content_size;
355 + unsigned long long gcompressed_content_size = global_statistics.compressed_content_size;
356 +
357 + unsigned long long content_size = gcontent_size - old_content_size;
358 + unsigned long long compressed_content_size = gcompressed_content_size - old_compressed_content_size;
359 +
360 + old_content_size = gcontent_size;
361 + old_compressed_content_size = gcompressed_content_size;
362 +
363 + if(content_size)
364 + compression_ratio = (content_size - compressed_content_size) * 100 * 1000 / content_size;
365 +
366 + if(compression_ratio != -1)
367 + rrddim_set(stcompression, "savings", compression_ratio);
368 +
369 + rrdset_done(stcompression);
370 +
371 + // ----------------------------------------------------------------
372 +
373 registry_statistics();
374 }
375 }
src/web_client.c
+37 -32
@@ -36,7 +36,10 @@
36 #define TOO_BIG_REQUEST 16384
37
38 int web_client_timeout = DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS;
39 -int web_enable_gzip = 1;
39 +
40 +#ifdef NETDATA_WITH_ZLIB
41 +int web_enable_gzip = 1, web_gzip_level = 3, web_gzip_strategy = Z_DEFAULT_STRATEGY;
42 +#endif /* NETDATA_WITH_ZLIB */
43
44 extern int netdata_exit;
45
@@ -178,16 +181,24 @@ struct web_client *web_client_create(int listener)
181 return(w);
182 }
183
181 -void web_client_reset(struct web_client *w)
182 -{
184 +void web_client_reset(struct web_client *w) {
185 web_client_uncrock_socket(w);
186
185 - struct timeval tv;
186 - gettimeofday(&tv, NULL);
187 -
187 debug(D_WEB_CLIENT, "%llu: Reseting client.", w->id);
188
190 - if(w->stats_received_bytes || w->stats_sent_bytes) {
189 + if(likely(w->last_url[0])) {
190 + struct timeval tv;
191 + gettimeofday(&tv, NULL);
192 +
193 + size_t size = (w->mode == WEB_CLIENT_MODE_FILECOPY)?w->response.rlen:w->response.data->len;
194 + size_t sent = size;
195 +#ifdef NETDATA_WITH_ZLIB
196 + if(likely(w->response.zoutput)) sent = (size_t)w->response.zstream.total_out;
197 +#endif
198 +
199 + // --------------------------------------------------------------------
200 + // global statistics
201 +
202 if(web_server_mode == WEB_SERVER_MODE_MULTI_THREADED)
203 global_statistics_lock();
204
@@ -195,32 +206,31 @@ void web_client_reset(struct web_client *w)
206 global_statistics.web_usec += usecdiff(&tv, &w->tv_in);
207 global_statistics.bytes_received += w->stats_received_bytes;
208 global_statistics.bytes_sent += w->stats_sent_bytes;
209 + global_statistics.content_size += size;
210 + global_statistics.compressed_content_size += sent;
211
212 if(web_server_mode == WEB_SERVER_MODE_MULTI_THREADED)
213 global_statistics_unlock();
201 - }
202 - w->stats_received_bytes = 0;
203 - w->stats_sent_bytes = 0;
214
205 - size_t sent = (w->mode == WEB_CLIENT_MODE_FILECOPY)?w->response.rlen:w->response.data->len;
215 + w->stats_received_bytes = 0;
216 + w->stats_sent_bytes = 0;
217
207 -#ifdef NETDATA_WITH_ZLIB
208 - if(likely(w->response.zoutput)) sent = (size_t)w->response.zstream.total_out;
209 -#endif
218
211 - size_t size = (w->mode == WEB_CLIENT_MODE_FILECOPY)?w->response.rlen:w->response.data->len;
219 + // --------------------------------------------------------------------
220 + // access log
221
213 - if(likely(w->last_url[0]))
222 log_access("%llu: (sent/all = %zu/%zu bytes %0.0f%%, prep/sent/total = %0.2f/%0.2f/%0.2f ms) %s: %d '%s'",
215 - w->id,
216 - sent, size, -((size>0)?((float)(size-sent)/(float)size * 100.0):0.0),
217 - (float)usecdiff(&w->tv_ready, &w->tv_in) / 1000.0,
218 - (float)usecdiff(&tv, &w->tv_ready) / 1000.0,
219 - (float)usecdiff(&tv, &w->tv_in) / 1000.0,
220 - (w->mode == WEB_CLIENT_MODE_FILECOPY)?"filecopy":((w->mode == WEB_CLIENT_MODE_OPTIONS)?"options":"data"),
221 - w->response.code,
222 - w->last_url
223 + w->id,
224 + sent, size, -((size > 0) ? ((float) (size - sent) / (float) size * 100.0) : 0.0),
225 + (float) usecdiff(&w->tv_ready, &w->tv_in) / 1000.0,
226 + (float) usecdiff(&tv, &w->tv_ready) / 1000.0,
227 + (float) usecdiff(&tv, &w->tv_in) / 1000.0,
228 + (w->mode == WEB_CLIENT_MODE_FILECOPY) ? "filecopy" : ((w->mode == WEB_CLIENT_MODE_OPTIONS)
229 + ? "options" : "data"),
230 + w->response.code,
231 + w->last_url
232 );
233 + }
234
235 if(unlikely(w->mode == WEB_CLIENT_MODE_FILECOPY)) {
236 if(w->ifd != w->ofd) {
@@ -256,7 +266,7 @@ void web_client_reset(struct web_client *w)
266 // if we had enabled compression, release it
267 #ifdef NETDATA_WITH_ZLIB
268 if(w->response.zinitialized) {
259 - debug(D_DEFLATE, "%llu: Reseting compression.", w->id);
269 + debug(D_DEFLATE, "%llu: Freeing compression resources.", w->id);
270 deflateEnd(&w->response.zstream);
271 w->response.zsent = 0;
272 w->response.zhave = 0;
@@ -270,18 +280,13 @@ void web_client_reset(struct web_client *w)
280 }
281
282 struct web_client *web_client_free(struct web_client *w) {
273 - web_client_uncrock_socket(w);
283 + web_client_reset(w);
284
285 struct web_client *n = w->next;
286 if(w == web_clients) web_clients = n;
287
288 debug(D_WEB_CLIENT_ACCESS, "%llu: Closing web client from %s port %s.", w->id, w->client_ip, w->client_port);
289
280 -#ifdef NETDATA_WITH_ZLIB
281 - if(w->response.zinitialized)
282 - deflateEnd(&w->response.zstream);
283 -#endif // NETDATA_WITH_ZLIB
284 -
290 if(w->prev) w->prev->next = w->next;
291 if(w->next) w->next->prev = w->prev;
292 if(w->response.header_output) buffer_free(w->response.header_output);
@@ -505,7 +510,7 @@ void web_client_enable_deflate(struct web_client *w, int gzip) {
510 // }
511
512 // Select GZIP compression: windowbits = 15 + 16 = 31
508 - if(deflateInit2(&w->response.zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + ((gzip)?16:0), 8, Z_DEFAULT_STRATEGY) != Z_OK) {
513 + if(deflateInit2(&w->response.zstream, web_gzip_level, Z_DEFLATED, 15 + ((gzip)?16:0), 8, web_gzip_strategy) != Z_OK) {
514 error("%llu: Failed to initialize zlib. Proceeding without compression.", w->id);
515 return;
516 }
src/web_client.h
+5 -2
@@ -16,7 +16,10 @@
16
17 #define DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS 60
18 extern int web_client_timeout;
19 -extern int web_enable_gzip;
19 +
20 +#ifdef NETDATA_WITH_ZLIB
21 +extern int web_enable_gzip, web_gzip_level, web_gzip_strategy;
22 +#endif /* NETDATA_WITH_ZLIB */
23
24 #ifndef NETDATA_WEB_CLIENT_H
25 #define NETDATA_WEB_CLIENT_H 1
@@ -48,7 +51,7 @@ struct response {
51 size_t zsent; // the compressed bytes we have sent to the client
52 size_t zhave; // the compressed bytes that we have received from zlib
53 int zinitialized:1;
51 -#endif
54 +#endif /* NETDATA_WITH_ZLIB */
55
56 };
57