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