@cryptotaxi247 / netdata-1 / commits / 56983e750

added backend timeout and thread resource usage chart

Costa Tsaousis (ktsaou) committed Nov 20, 2016 at 16:07 UTC 56983e7505af6aac3b1f1084751157138bd9ee71
1 file changed +53 -16
src/backends.c
+53 -16
@@ -4,7 +4,7 @@
4 #define BACKEND_SOURCE_DATA_AVERAGE 0x00000002
5 #define BACKEND_SOURCE_DATA_SUM 0x00000004
6
7 -int connect_to_socket4(const char *ip, int port) {
7 +int connect_to_socket4(const char *ip, int port, struct timeval *timeout) {
8 int sock;
9
10 debug(D_LISTENER, "IPv4 connecting to ip '%s' port %d", ip, port);
@@ -15,6 +15,9 @@ int connect_to_socket4(const char *ip, int port) {
15 return -1;
16 }
17
18 + if(setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)timeout, sizeof(struct timeval)) < 0)
19 + error("Failed to set timeout on the socket to ip '%s' port %d", ip, port);
20 +
21 struct sockaddr_in name;
22 memset(&name, 0, sizeof(struct sockaddr_in));
23 name.sin_family = AF_INET;
@@ -37,7 +40,7 @@ int connect_to_socket4(const char *ip, int port) {
40 return sock;
41 }
42
40 -int connect_to_socket6(const char *ip, int port) {
43 +int connect_to_socket6(const char *ip, int port, struct timeval *timeout) {
44 int sock = -1;
45 int ipv6only = 1;
46
@@ -49,6 +52,9 @@ int connect_to_socket6(const char *ip, int port) {
52 return -1;
53 }
54
55 + if(setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)timeout, sizeof(struct timeval)) < 0)
56 + error("Failed to set timeout on the socket to ip '%s' port %d", ip, port);
57 +
58 /* IPv6 only */
59 if(setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&ipv6only, sizeof(ipv6only)) != 0)
60 error("Cannot set IPV6_V6ONLY on ip '%s' port's %d.", ip, port);
@@ -78,7 +84,7 @@ int connect_to_socket6(const char *ip, int port) {
84 }
85
86
81 -static inline int connect_to_one(const char *definition, int default_port) {
87 +static inline int connect_to_one(const char *definition, int default_port, struct timeval *timeout) {
88 struct addrinfo hints;
89 struct addrinfo *result = NULL, *rp = NULL;
90
@@ -139,7 +145,7 @@ static inline int connect_to_one(const char *definition, int default_port) {
145 struct sockaddr_in *sin = (struct sockaddr_in *) rp->ai_addr;
146 inet_ntop(AF_INET, &sin->sin_addr, rip, INET_ADDRSTRLEN);
147 rport = ntohs(sin->sin_port);
142 - fd = connect_to_socket4(rip, rport);
148 + fd = connect_to_socket4(rip, rport, timeout);
149 break;
150 }
151
@@ -147,7 +153,7 @@ static inline int connect_to_one(const char *definition, int default_port) {
153 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) rp->ai_addr;
154 inet_ntop(AF_INET6, &sin6->sin6_addr, rip, INET6_ADDRSTRLEN);
155 rport = ntohs(sin6->sin6_port);
150 - fd = connect_to_socket6(rip, rport);
156 + fd = connect_to_socket6(rip, rport, timeout);
157 break;
158 }
159 }
@@ -265,9 +271,13 @@ void *backends_main(void *ptr) {
271 // ------------------------------------------------------------------------
272 // collect configuration options
273
274 + struct timeval timeout = {
275 + .tv_sec = 0,
276 + .tv_usec = 0
277 + };
278 int default_port = 0;
279 int sock = -1;
270 - uint32_t options = BACKEND_SOURCE_DATA_AVERAGE;
280 + uint32_t options;
281 int enabled = config_get_boolean("backend", "enable", 0);
282 const char *source = config_get("backend", "data source", "average");
283 const char *type = config_get("backend", "type", "graphite");
@@ -276,6 +286,7 @@ void *backends_main(void *ptr) {
286 const char *hostname = config_get("backend", "hostname", localhost.hostname);
287 int frequency = (int)config_get_number("backend", "update every", 10);
288 int buffer_on_failures = (int)config_get_number("backend", "buffer on failures", 10);
289 + long timeoutms = config_get_number("backend", "timeout ms", frequency * 2 * 1000);
290
291 // ------------------------------------------------------------------------
292 // validate configuration options
@@ -316,9 +327,18 @@ void *backends_main(void *ptr) {
327 goto cleanup;
328 }
329
330 + if(timeoutms < 1) {
331 + error("BACKED invalid timeout %ld ms given. Assuming %d ms.", timeoutms, frequency * 2 * 1000);
332 + timeoutms = frequency * 2 * 1000;
333 + }
334 + timeout.tv_sec = (timeoutms * 1000) / 1000000;
335 + timeout.tv_usec = (timeoutms * 1000) % 1000000;
336 +
337 // ------------------------------------------------------------------------
338 // prepare the charts for monitoring the backend
339
340 + struct rusage thread;
341 +
342 collected_number
343 chart_buffered_metrics = 0,
344 chart_lost_metrics = 0,
@@ -363,6 +383,13 @@ void *backends_main(void *ptr) {
383 rrddim_add(chart_latency, "latency", NULL, 1, 1000, RRDDIM_ABSOLUTE);
384 }
385
386 + RRDSET *chart_rusage = rrdset_find("netdata.backend_thread_cpu");
387 + if(!chart_rusage) {
388 + chart_rusage = rrdset_create("netdata", "backend_thread_cpu", NULL, "backend", NULL, "NetData Backend Thread CPU usage", "milliseconds/s", 130630, frequency, RRDSET_TYPE_STACKED);
389 + rrddim_add(chart_rusage, "user", NULL, 1, 1000, RRDDIM_INCREMENTAL);
390 + rrddim_add(chart_rusage, "system", NULL, 1, 1000, RRDDIM_INCREMENTAL);
391 + }
392 +
393 // ------------------------------------------------------------------------
394 // prepare the backend main loop
395
@@ -455,7 +482,7 @@ void *backends_main(void *ptr) {
482 char buf[e - s + 1];
483 strncpyz(buf, s, e - s);
484 chart_backend_reconnects++;
458 - sock = connect_to_one(buf, default_port);
485 + sock = connect_to_one(buf, default_port, &timeout);
486 if(sock != -1) break;
487 s = e;
488 }
@@ -470,7 +497,11 @@ void *backends_main(void *ptr) {
497 if(likely(sock != -1)) {
498 size_t len = buffer_strlen(b);
499 unsigned long long start_ut = time_usec();
473 - ssize_t written = write(sock, buffer_tostring(b), len);
500 + int flags = 0;
501 +#ifdef MSG_NOSIGNAL
502 + flags += MSG_NOSIGNAL;
503 +#endif
504 + ssize_t written = send(sock, buffer_tostring(b), len, flags);
505 chart_backend_latency += time_usec() - start_ut;
506 if(written != -1 && (size_t)written == len) {
507 // we sent the data successfully
@@ -530,10 +561,10 @@ void *backends_main(void *ptr) {
561 // update the monitoring charts
562
563 if(chart_ops->counter_done) rrdset_next(chart_ops);
533 - rrddim_set(chart_ops, "write", chart_transmission_successes);
534 - rrddim_set(chart_ops, "discard", chart_data_lost_events);
535 - rrddim_set(chart_ops, "failure", chart_transmission_failures);
536 - rrddim_set(chart_ops, "reconnect", chart_backend_reconnects);
564 + rrddim_set(chart_ops, "write", chart_transmission_successes);
565 + rrddim_set(chart_ops, "discard", chart_data_lost_events);
566 + rrddim_set(chart_ops, "failure", chart_transmission_failures);
567 + rrddim_set(chart_ops, "reconnect", chart_backend_reconnects);
568 rrdset_done(chart_ops);
569
570 if(chart_metrics->counter_done) rrdset_next(chart_metrics);
@@ -543,15 +574,21 @@ void *backends_main(void *ptr) {
574 rrdset_done(chart_metrics);
575
576 if(chart_bytes->counter_done) rrdset_next(chart_bytes);
546 - rrddim_set(chart_bytes, "buffered", chart_buffered_bytes);
547 - rrddim_set(chart_bytes, "lost", chart_lost_bytes);
548 - rrddim_set(chart_bytes, "sent", chart_sent_bytes);
577 + rrddim_set(chart_bytes, "buffered", chart_buffered_bytes);
578 + rrddim_set(chart_bytes, "lost", chart_lost_bytes);
579 + rrddim_set(chart_bytes, "sent", chart_sent_bytes);
580 rrdset_done(chart_bytes);
581
582 if(chart_latency->counter_done) rrdset_next(chart_latency);
552 - rrddim_set(chart_latency, "latency", chart_backend_latency);
583 + rrddim_set(chart_latency, "latency", chart_backend_latency);
584 rrdset_done(chart_latency);
585
586 + getrusage(RUSAGE_THREAD, &thread);
587 + if(chart_rusage->counter_done) rrdset_next(chart_rusage);
588 + rrddim_set(chart_rusage, "user", thread.ru_utime.tv_sec * 1000000ULL + thread.ru_utime.tv_usec);
589 + rrddim_set(chart_rusage, "system", thread.ru_stime.tv_sec * 1000000ULL + thread.ru_stime.tv_usec);
590 + rrdset_done(chart_rusage);
591 +
592 if(likely(buffer_strlen(b) == 0))
593 chart_buffered_metrics = 0;
594