@cryptotaxi247 / netdata-1 / commits / 5f2514675

propagate netdata version with streaming; add netdata version to prometheus metrics; fixes #3519

Costa Tsaousis (ktsaou) committed Mar 11, 2018 at 23:46 UTC 5f2514675334e52cabd9fe5677f44d325e3b9b37
9 files changed +103 -16
src/backend_prometheus.c
+3
@@ -110,12 +110,15 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
110
111 char labels[PROMETHEUS_LABELS_MAX + 1] = "";
112 if(allhosts) {
113 + buffer_sprintf(wb, "netdata_info{instance=\"%s\",application=\"%s\",version=\"%s\"}\n", hostname, host->program_name, host->program_version);
114 if(host->tags && *(host->tags))
115 buffer_sprintf(wb, "netdata_host_tags{instance=\"%s\",%s} 1 %llu\n", hostname, host->tags, now_realtime_usec() / USEC_PER_MS);
116
117 snprintfz(labels, PROMETHEUS_LABELS_MAX, ",instance=\"%s\"", hostname);
118 }
119 else {
120 + buffer_sprintf(wb, "netdata_info{application=\"%s\",version=\"%s\"}\n", host->program_name, host->program_version);
121 +
122 if(host->tags && *(host->tags))
123 buffer_sprintf(wb, "netdata_host_tags{%s} 1 %llu\n", host->tags, now_realtime_usec() / USEC_PER_MS);
124 }
src/health.c
+1 -4
@@ -348,7 +348,6 @@ static void health_main_cleanup(void *ptr) {
348 }
349
350 void *health_main(void *ptr) {
351 - BUFFER *wb = buffer_create(100);
351 netdata_thread_cleanup_push(health_main_cleanup, ptr);
352
353 int min_run_every = (int)config_get_number(CONFIG_SECTION_HEALTH, "run at least every seconds", 10);
@@ -421,7 +420,7 @@ void *health_main(void *ptr) {
420 int value_is_null = 0;
421
422 int ret = rrdset2value_api_v1(rc->rrdset
424 - , wb
423 + , NULL
424 , &rc->value
425 , rc->dimensions
426 , 1
@@ -733,8 +732,6 @@ void *health_main(void *ptr) {
732
733 } // forever
734
736 - buffer_free(wb);
737 -
735 netdata_thread_cleanup_pop(1);
736 return NULL;
737 }
src/rrd.h
+4
@@ -432,6 +432,8 @@ struct rrdhost {
432 char *cache_dir; // the directory to save RRD cache files
433 char *varlib_dir; // the directory to save health log
434
435 + char *program_name; // the program name that collects metrics for this host
436 + char *program_version; // the program version that collects metrics for this host
437
438 // ------------------------------------------------------------------------
439 // streaming of data to remote hosts - rrdpush
@@ -557,6 +559,8 @@ extern RRDHOST *rrdhost_find_or_create(
559 , const char *os
560 , const char *timezone
561 , const char *tags
562 + , const char *program_name
563 + , const char *program_version
564 , int update_every
565 , long history
566 , RRD_MEMORY_MODE mode
src/rrd2json.c
+7 -5
@@ -128,7 +128,7 @@ void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb) {
128 ",\n\t\"custom_info\": \"%s\""
129 ",\n\t\"charts\": {"
130 , host->hostname
131 - , program_version
131 + , host->program_version
132 , host->os
133 , host->timezone
134 , host->rrd_update_every
@@ -1849,10 +1849,12 @@ int rrdset2value_api_v1(
1849 return 400;
1850 }
1851
1852 - if(r->result_options & RRDR_RESULT_OPTION_RELATIVE)
1853 - buffer_no_cacheable(wb);
1854 - else if(r->result_options & RRDR_RESULT_OPTION_ABSOLUTE)
1855 - buffer_cacheable(wb);
1852 + if(wb) {
1853 + if (r->result_options & RRDR_RESULT_OPTION_RELATIVE)
1854 + buffer_no_cacheable(wb);
1855 + else if (r->result_options & RRDR_RESULT_OPTION_ABSOLUTE)
1856 + buffer_cacheable(wb);
1857 + }
1858
1859 options = rrdr_check_options(r, options, dimensions);
1860
src/rrdhost.c
+32
@@ -111,6 +111,8 @@ RRDHOST *rrdhost_create(const char *hostname,
111 const char *os,
112 const char *timezone,
113 const char *tags,
114 + const char *program_name,
115 + const char *program_version,
116 int update_every,
117 long entries,
118 RRD_MEMORY_MODE memory_mode,
@@ -146,6 +148,9 @@ RRDHOST *rrdhost_create(const char *hostname,
148 rrdhost_init_os(host, os);
149 rrdhost_init_timezone(host, timezone);
150 rrdhost_init_tags(host, tags);
151 +
152 + host->program_name = strdupz((program_name && *program_name)?program_name:"unknown");
153 + host->program_version = strdupz((program_version && *program_version)?program_version:"unknown");
154 host->registry_hostname = strdupz((registry_hostname && *registry_hostname)?registry_hostname:hostname);
155
156 avl_init_lock(&(host->rrdset_root_index), rrdset_compare);
@@ -265,6 +270,8 @@ RRDHOST *rrdhost_create(const char *hostname,
270 ", os '%s'"
271 ", timezone '%s'"
272 ", tags '%s'"
273 + ", program_name '%s'"
274 + ", program_version '%s'"
275 ", update every %d"
276 ", memory mode %s"
277 ", history entries %ld"
@@ -282,6 +289,8 @@ RRDHOST *rrdhost_create(const char *hostname,
289 , host->os
290 , host->timezone
291 , (host->tags)?host->tags:""
292 + , host->program_name
293 + , host->program_version
294 , host->rrd_update_every
295 , rrd_memory_mode_name(host->rrd_memory_mode)
296 , host->rrd_history_entries
@@ -309,6 +318,8 @@ RRDHOST *rrdhost_find_or_create(
318 , const char *os
319 , const char *timezone
320 , const char *tags
321 + , const char *program_name
322 + , const char *program_version
323 , int update_every
324 , long history
325 , RRD_MEMORY_MODE mode
@@ -329,6 +340,8 @@ RRDHOST *rrdhost_find_or_create(
340 , os
341 , timezone
342 , tags
343 + , program_name
344 + , program_version
345 , update_every
346 , history
347 , mode
@@ -343,12 +356,27 @@ RRDHOST *rrdhost_find_or_create(
356 host->health_enabled = health_enabled;
357
358 if(strcmp(host->hostname, hostname) != 0) {
359 + info("Host '%s' has been renamed to '%s'. If this is not intentional it may mean multiple hosts are using the same machine_guid.", host->hostname, hostname);
360 char *t = host->hostname;
361 host->hostname = strdupz(hostname);
362 host->hash_hostname = simple_hash(host->hostname);
363 freez(t);
364 }
365
366 + if(strcmp(host->program_name, program_name) != 0) {
367 + info("Host '%s' switched program name from '%s' to '%s'", host->hostname, host->program_name, program_name);
368 + char *t = host->program_name;
369 + host->program_name = strdupz(program_name);
370 + freez(t);
371 + }
372 +
373 + if(strcmp(host->program_version, program_version) != 0) {
374 + info("Host '%s' switched program version from '%s' to '%s'", host->hostname, host->program_version, program_version);
375 + char *t = host->program_version;
376 + host->program_version = strdupz(program_version);
377 + freez(t);
378 + }
379 +
380 if(host->rrd_update_every != update_every)
381 error("Host '%s' has an update frequency of %d seconds, but the wanted one is %d seconds. Restart netdata here to apply the new settings.", host->hostname, host->rrd_update_every, update_every);
382
@@ -424,6 +452,8 @@ void rrd_init(char *hostname) {
452 , os_type
453 , netdata_configured_timezone
454 , config_get(CONFIG_SECTION_BACKEND, "host tags", "")
455 + , program_name
456 + , program_version
457 , default_rrd_update_every
458 , default_rrd_history_entries
459 , default_rrd_memory_mode
@@ -533,6 +563,8 @@ void rrdhost_free(RRDHOST *host) {
563 freez((void *)host->tags);
564 freez((void *)host->os);
565 freez((void *)host->timezone);
566 + freez(host->program_version);
567 + freez(host->program_name);
568 freez(host->cache_dir);
569 freez(host->varlib_dir);
570 freez(host->rrdpush_send_api_key);
src/rrdpush.c
+38 -4
@@ -364,7 +364,7 @@ static int rrdpush_sender_thread_connect_to_master(RRDHOST *host, int default_po
364 char http[HTTP_HEADER_SIZE + 1];
365 snprintfz(http, HTTP_HEADER_SIZE,
366 "STREAM key=%s&hostname=%s&registry_hostname=%s&machine_guid=%s&update_every=%d&os=%s&timezone=%s&tags=%s HTTP/1.1\r\n"
367 - "User-Agent: netdata-push-service/%s\r\n"
367 + "User-Agent: %s/%s\r\n"
368 "Accept: */*\r\n\r\n"
369 , host->rrdpush_send_api_key
370 , host->hostname
@@ -374,7 +374,8 @@ static int rrdpush_sender_thread_connect_to_master(RRDHOST *host, int default_po
374 , host->os
375 , host->timezone
376 , (host->tags)?host->tags:""
377 - , program_version
377 + , host->program_name
378 + , host->program_version
379 );
380
381 if(send_timeout(host->rrdpush_sender_socket, http, strlen(http), 0, timeout) == -1) {
@@ -721,7 +722,20 @@ static RRDPUSH_MULTIPLE_CONNECTIONS_STRATEGY get_multiple_connections_strategy(s
722 return ret;
723 }
724
724 -static int rrdpush_receive(int fd, const char *key, const char *hostname, const char *registry_hostname, const char *machine_guid, const char *os, const char *timezone, const char *tags, int update_every, char *client_ip, char *client_port) {
725 +static int rrdpush_receive(int fd
726 + , const char *key
727 + , const char *hostname
728 + , const char *registry_hostname
729 + , const char *machine_guid
730 + , const char *os
731 + , const char *timezone
732 + , const char *tags
733 + , const char *program_name
734 + , const char *program_version
735 + , int update_every
736 + , char *client_ip
737 + , char *client_port
738 +) {
739 RRDHOST *host;
740 int history = default_rrd_history_entries;
741 RRD_MEMORY_MODE mode = default_rrd_memory_mode;
@@ -773,6 +787,8 @@ static int rrdpush_receive(int fd, const char *key, const char *hostname, const
787 , os
788 , timezone
789 , tags
790 + , program_name
791 + , program_version
792 , update_every
793 , history
794 , mode
@@ -911,6 +927,8 @@ struct rrdpush_thread {
927 char *tags;
928 char *client_ip;
929 char *client_port;
930 + char *program_name;
931 + char *program_version;
932 int update_every;
933 };
934
@@ -931,6 +949,8 @@ static void rrdpush_receiver_thread_cleanup(void *ptr) {
949 freez(rpt->tags);
950 freez(rpt->client_ip);
951 freez(rpt->client_port);
952 + freez(rpt->program_name);
953 + freez(rpt->program_version);
954 freez(rpt);
955 }
956 }
@@ -950,6 +970,8 @@ static void *rrdpush_receiver_thread(void *ptr) {
970 , rpt->os
971 , rpt->timezone
972 , rpt->tags
973 + , rpt->program_name
974 + , rpt->program_version
975 , rpt->update_every
976 , rpt->client_ip
977 , rpt->client_port
@@ -1088,7 +1110,7 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url
1110 }
1111 }
1112
1091 - struct rrdpush_thread *rpt = mallocz(sizeof(struct rrdpush_thread));
1113 + struct rrdpush_thread *rpt = callocz(1, sizeof(struct rrdpush_thread));
1114 rpt->fd = w->ifd;
1115 rpt->key = strdupz(key);
1116 rpt->hostname = strdupz(hostname);
@@ -1100,6 +1122,18 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url
1122 rpt->client_ip = strdupz(w->client_ip);
1123 rpt->client_port = strdupz(w->client_port);
1124 rpt->update_every = update_every;
1125 +
1126 + if(w->user_agent && w->user_agent[0]) {
1127 + char *t = strchr(w->user_agent, '/');
1128 + if(t && *t) {
1129 + *t = '\0';
1130 + t++;
1131 + }
1132 +
1133 + rpt->program_name = strdupz(w->user_agent);
1134 + if(t && *t) rpt->program_version = strdupz(t);
1135 + }
1136 +
1137 netdata_thread_t thread;
1138
1139 debug(D_SYSTEM, "starting STREAM receive thread.");
src/web_client.c
+11 -3
@@ -142,6 +142,8 @@ void web_client_request_done(struct web_client *w) {
142 w->origin[0] = '*';
143 w->origin[1] = '\0';
144
145 + freez(w->user_agent); w->user_agent = NULL;
146 +
147 w->mode = WEB_CLIENT_MODE_NORMAL;
148
149 w->tcp_cork = 0;
@@ -722,14 +724,15 @@ const char *web_response_code_to_string(int code) {
724 }
725 }
726
725 -static inline char *http_header_parse(struct web_client *w, char *s) {
726 - static uint32_t hash_origin = 0, hash_connection = 0, hash_accept_encoding = 0, hash_donottrack = 0;
727 +static inline char *http_header_parse(struct web_client *w, char *s, int parse_useragent) {
728 + static uint32_t hash_origin = 0, hash_connection = 0, hash_accept_encoding = 0, hash_donottrack = 0, hash_useragent = 0;
729
730 if(unlikely(!hash_origin)) {
731 hash_origin = simple_uhash("Origin");
732 hash_connection = simple_uhash("Connection");
733 hash_accept_encoding = simple_uhash("Accept-Encoding");
734 hash_donottrack = simple_uhash("DNT");
735 + hash_useragent = simple_uhash("User-Agent");
736 }
737
738 char *e = s;
@@ -772,6 +775,9 @@ static inline char *http_header_parse(struct web_client *w, char *s) {
775 if(*v == '0') web_client_disable_donottrack(w);
776 else if(*v == '1') web_client_enable_donottrack(w);
777 }
778 + else if(parse_useragent && hash == hash_useragent && !strcasecmp(s, "User-Agent")) {
779 + w->user_agent = strdupz(v);
780 + }
781 #ifdef NETDATA_WITH_ZLIB
782 else if(hash == hash_accept_encoding && !strcasecmp(s, "Accept-Encoding")) {
783 if(web_enable_gzip) {
@@ -871,7 +877,9 @@ static inline HTTP_VALIDATION http_request_validate(struct web_client *w) {
877 }
878
879 // another header line
874 - s = http_header_parse(w, s);
880 + s = http_header_parse(w, s,
881 + (w->mode == WEB_CLIENT_MODE_STREAM) // parse user agent
882 + );
883 }
884 }
885
src/web_client.h
+1
@@ -144,6 +144,7 @@ struct web_client {
144 char cookie1[NETDATA_WEB_REQUEST_COOKIE_SIZE+1];
145 char cookie2[NETDATA_WEB_REQUEST_COOKIE_SIZE+1];
146 char origin[NETDATA_WEB_REQUEST_ORIGIN_HEADER_SIZE+1];
147 + char *user_agent;
148
149 struct response response;
150
src/web_server.c
+6
@@ -106,6 +106,8 @@ static void web_client_zero(struct web_client *w) {
106 buffer_flush(b2);
107 buffer_flush(b3);
108
109 + freez(w->user_agent);
110 +
111 // zero everything
112 memset(w, 0, sizeof(struct web_client));
113
@@ -119,6 +121,7 @@ static void web_client_free(struct web_client *w) {
121 buffer_free(w->response.header_output);
122 buffer_free(w->response.header);
123 buffer_free(w->response.data);
124 + freez(w->user_agent);
125 freez(w);
126 }
127
@@ -342,6 +345,9 @@ static void web_client_initialize_connection(struct web_client *w) {
345 web_client_update_acl_matches(w);
346
347 w->origin[0] = '*'; w->origin[1] = '\0';
348 + w->cookie1[0] = '\0'; w->cookie2[0] = '\0';
349 + freez(w->user_agent); w->user_agent = NULL;
350 +
351 web_client_enable_wait_receive(w);
352
353 log_connection(w, "CONNECTED");