@cryptotaxi247 / netdata-1 / commits / 51decad98

Add system info streaming (#5996)

* Add system info streaming * Fix segmentation fault in unit testing

Vladimir Kobal committed May 13, 2019 at 15:12 UTC 51decad9896131ed478681d90886d63bbd953b14
5 files changed +193 -27
daemon/main.c
+16 -9
@@ -650,7 +650,7 @@ static int load_netdata_conf(char *filename, char overwrite_used) {
650 return ret;
651 }
652
653 -int get_system_info () {
653 +int get_system_info(struct rrdhost_system_info *system_info) {
654 char *script;
655 script = mallocz(sizeof(char) * (strlen(netdata_configured_primary_plugins_dir) + strlen("system-info.sh") + 2));
656 sprintf(script, "%s/%s", netdata_configured_primary_plugins_dir, "system-info.sh");
@@ -679,10 +679,15 @@ int get_system_info () {
679 (*newline) = '\0';
680 }
681 char n[51], v[101];
682 - snprintfz(n,50,"%s",name);
683 - snprintfz(v,101,"%s",value);
684 - info("%s=%s", n, v);
685 - setenv(n, v, 1);
682 + snprintfz(n, 50,"%s",name);
683 + snprintfz(v, 101,"%s",value);
684 + if(unlikely(rrdhost_set_system_info_variable(system_info, n, v))) {
685 + info("Unexpected environment variable %s=%s", n, v);
686 + }
687 + else {
688 + info("%s=%s", n, v);
689 + setenv(n, v, 1);
690 + }
691 }
692 }
693 mypclose(fp, command_pid);
@@ -844,7 +849,7 @@ int main(int argc, char **argv) {
849 default_rrd_update_every = 1;
850 default_rrd_memory_mode = RRD_MEMORY_MODE_RAM;
851 default_health_enabled = 0;
847 - rrd_init("unittest");
852 + rrd_init("unittest", NULL);
853 default_rrdpush_enabled = 0;
854 if(run_all_mockup_tests()) return 1;
855 if(unit_test_storage()) return 1;
@@ -1093,8 +1098,10 @@ int main(int argc, char **argv) {
1098
1099 // initialize the log files
1100 open_all_log_files();
1101 +
1102 netdata_anonymous_statistics_enabled=-1;
1097 - if (get_system_info() == 0) send_statistics("START","-", "-");
1103 + struct rrdhost_system_info *system_info = calloc(1, sizeof(struct rrdhost_system_info));
1104 + if (get_system_info(system_info) == 0) send_statistics("START","-", "-");
1105
1106 #ifdef NETDATA_INTERNAL_CHECKS
1107 if(debug_flags != 0) {
@@ -1129,14 +1136,14 @@ int main(int argc, char **argv) {
1136 // ------------------------------------------------------------------------
1137 // initialize rrd, registry, health, rrdpush, etc.
1138
1132 - rrd_init(netdata_configured_hostname);
1139 + rrd_init(netdata_configured_hostname, system_info);
1140 + rrdhost_system_info_free(system_info);
1141
1142 // ------------------------------------------------------------------------
1143 // enable log flood protection
1144
1145 error_log_limit_reset();
1146
1139 -
1147 // ------------------------------------------------------------------------
1148 // spawn the threads
1149
database/rrd.h
+24 -1
@@ -490,6 +490,22 @@ typedef struct alarm_log {
490 // ----------------------------------------------------------------------------
491 // RRD HOST
492
493 +struct rrdhost_system_info {
494 + char *os_name;
495 + char *os_id;
496 + char *os_id_like;
497 + char *os_version;
498 + char *os_version_id;
499 + char *os_detection;
500 + char *kernel_name;
501 + char *kernel_version;
502 + char *architecture;
503 + char *virtualization;
504 + char *virt_detection;
505 + char *container;
506 + char *container_detection;
507 +};
508 +
509 struct rrdhost {
510 avl avl; // the index of hosts
511
@@ -520,6 +536,8 @@ struct rrdhost {
536 char *program_name; // the program name that collects metrics for this host
537 char *program_version; // the program version that collects metrics for this host
538
539 + struct rrdhost_system_info *system_info; // information collected from the host environment
540 +
541 // ------------------------------------------------------------------------
542 // streaming of data to remote hosts - rrdpush
543
@@ -634,7 +652,7 @@ extern netdata_rwlock_t rrd_rwlock;
652 extern size_t rrd_hosts_available;
653 extern time_t rrdhost_free_orphan_time;
654
637 -extern void rrd_init(char *hostname);
655 +extern void rrd_init(char *hostname, struct rrdhost_system_info *system_info);
656
657 extern RRDHOST *rrdhost_find_by_hostname(const char *hostname, uint32_t hash);
658 extern RRDHOST *rrdhost_find_by_guid(const char *guid, uint32_t hash);
@@ -656,8 +674,12 @@ extern RRDHOST *rrdhost_find_or_create(
674 , char *rrdpush_destination
675 , char *rrdpush_api_key
676 , char *rrdpush_send_charts_matching
677 + , struct rrdhost_system_info *system_info
678 );
679
680 +extern int rrdhost_set_system_info_variable(struct rrdhost_system_info *system_info, char *name, char *value);
681 +extern struct rrdhost_system_info *rrdhost_system_info_dup(struct rrdhost_system_info *system_info);
682 +
683 #if defined(NETDATA_INTERNAL_CHECKS) && defined(NETDATA_VERIFY_LOCKS)
684 extern void __rrdhost_check_wrlock(RRDHOST *host, const char *file, const char *function, const unsigned long line);
685 extern void __rrdhost_check_rdlock(RRDHOST *host, const char *file, const char *function, const unsigned long line);
@@ -714,6 +736,7 @@ extern void rrdhost_save_all(void);
736 extern void rrdhost_cleanup_all(void);
737
738 extern void rrdhost_cleanup_orphan_hosts_nolock(RRDHOST *protected);
739 +extern void rrdhost_system_info_free(struct rrdhost_system_info *system_info);
740 extern void rrdhost_free(RRDHOST *host);
741 extern void rrdhost_save_charts(RRDHOST *host);
742 extern void rrdhost_delete_charts(RRDHOST *host);
database/rrdhost.c
+99 -1
@@ -122,6 +122,7 @@ RRDHOST *rrdhost_create(const char *hostname,
122 char *rrdpush_destination,
123 char *rrdpush_api_key,
124 char *rrdpush_send_charts_matching,
125 + struct rrdhost_system_info *system_info,
126 int is_localhost
127 ) {
128 debug(D_RRDHOST, "Host '%s': adding with guid '%s'", hostname, guid);
@@ -157,6 +158,8 @@ RRDHOST *rrdhost_create(const char *hostname,
158 host->program_version = strdupz((program_version && *program_version)?program_version:"unknown");
159 host->registry_hostname = strdupz((registry_hostname && *registry_hostname)?registry_hostname:hostname);
160
161 + host->system_info = rrdhost_system_info_dup(system_info);
162 +
163 avl_init_lock(&(host->rrdset_root_index), rrdset_compare);
164 avl_init_lock(&(host->rrdset_root_index_name), rrdset_compare_name);
165 avl_init_lock(&(host->rrdfamily_root_index), rrdfamily_compare);
@@ -332,6 +335,7 @@ RRDHOST *rrdhost_find_or_create(
335 , char *rrdpush_destination
336 , char *rrdpush_api_key
337 , char *rrdpush_send_charts_matching
338 + , struct rrdhost_system_info *system_info
339 ) {
340 debug(D_RRDHOST, "Searching for host '%s' with guid '%s'", hostname, guid);
341
@@ -355,6 +359,7 @@ RRDHOST *rrdhost_find_or_create(
359 , rrdpush_destination
360 , rrdpush_api_key
361 , rrdpush_send_charts_matching
362 + , system_info
363 , 0
364 );
365 }
@@ -439,7 +444,7 @@ restart_after_removal:
444 // ----------------------------------------------------------------------------
445 // RRDHOST global / startup initialization
446
442 -void rrd_init(char *hostname) {
447 +void rrd_init(char *hostname, struct rrdhost_system_info *system_info) {
448 rrdset_free_obsolete_time = config_get_number(CONFIG_SECTION_GLOBAL, "cleanup obsolete charts after seconds", rrdset_free_obsolete_time);
449 gap_when_lost_iterations_above = (int)config_get_number(CONFIG_SECTION_GLOBAL, "gap when lost iterations above", gap_when_lost_iterations_above);
450 if (gap_when_lost_iterations_above < 1)
@@ -468,6 +473,7 @@ void rrd_init(char *hostname) {
473 , default_rrdpush_destination
474 , default_rrdpush_api_key
475 , default_rrdpush_send_charts_matching
476 + , system_info
477 , 1
478 );
479 rrd_unlock();
@@ -513,6 +519,27 @@ void __rrd_check_wrlock(const char *file, const char *function, const unsigned l
519 // ----------------------------------------------------------------------------
520 // RRDHOST - free
521
522 +void rrdhost_system_info_free(struct rrdhost_system_info *system_info) {
523 + info("SYSTEM_INFO: free %p", system_info);
524 +
525 + if(likely(system_info)) {
526 + freez(system_info->os_name);
527 + freez(system_info->os_id);
528 + freez(system_info->os_id_like);
529 + freez(system_info->os_version);
530 + freez(system_info->os_version_id);
531 + freez(system_info->os_detection);
532 + freez(system_info->kernel_name);
533 + freez(system_info->kernel_version);
534 + freez(system_info->architecture);
535 + freez(system_info->virtualization);
536 + freez(system_info->virt_detection);
537 + freez(system_info->container);
538 + freez(system_info->container_detection);
539 + freez(system_info);
540 + }
541 +}
542 +
543 void rrdhost_free(RRDHOST *host) {
544 if(!host) return;
545
@@ -573,6 +600,7 @@ void rrdhost_free(RRDHOST *host) {
600 freez((void *)host->timezone);
601 freez(host->program_version);
602 freez(host->program_name);
603 + rrdhost_system_info_free(host->system_info);
604 freez(host->cache_dir);
605 freez(host->varlib_dir);
606 freez(host->rrdpush_send_api_key);
@@ -744,3 +772,73 @@ restart_after_removal:
772 }
773 }
774 }
775 +
776 +// ----------------------------------------------------------------------------
777 +// RRDHOST - set system info from environment variables
778 +
779 +int rrdhost_set_system_info_variable(struct rrdhost_system_info *system_info, char *name, char *value) {
780 + if(!strcmp(name, "NETDATA_SYSTEM_OS_NAME")){
781 + system_info->os_name = strdupz(value);
782 + }
783 + else if(!strcmp(name, "NETDATA_SYSTEM_OS_ID")){
784 + system_info->os_id = strdupz(value);
785 + }
786 + else if(!strcmp(name, "NETDATA_SYSTEM_OS_ID_LIKE")){
787 + system_info->os_id_like = strdupz(value);
788 + }
789 + else if(!strcmp(name, "NETDATA_SYSTEM_OS_VERSION")){
790 + system_info->os_version = strdupz(value);
791 + }
792 + else if(!strcmp(name, "NETDATA_SYSTEM_OS_VERSION_ID")){
793 + system_info->os_version_id = strdupz(value);
794 + }
795 + else if(!strcmp(name, "NETDATA_SYSTEM_OS_DETECTION")){
796 + system_info->os_detection = strdupz(value);
797 + }
798 + else if(!strcmp(name, "NETDATA_SYSTEM_KERNEL_NAME")){
799 + system_info->kernel_name = strdupz(value);
800 + }
801 + else if(!strcmp(name, "NETDATA_SYSTEM_KERNEL_VERSION")){
802 + system_info->kernel_version = strdupz(value);
803 + }
804 + else if(!strcmp(name, "NETDATA_SYSTEM_ARCHITECTURE")){
805 + system_info->architecture = strdupz(value);
806 + }
807 + else if(!strcmp(name, "NETDATA_SYSTEM_VIRTUALIZATION")){
808 + system_info->virtualization = strdupz(value);
809 + }
810 + else if(!strcmp(name, "NETDATA_SYSTEM_VIRT_DETECTION")){
811 + system_info->virt_detection = strdupz(value);
812 + }
813 + else if(!strcmp(name, "NETDATA_SYSTEM_CONTAINER")){
814 + system_info->container = strdupz(value);
815 + }
816 + else if(!strcmp(name, "NETDATA_SYSTEM_CONTAINER_DETECTION")){
817 + system_info->container_detection = strdupz(value);
818 + }
819 + else return 1;
820 +
821 + return 0;
822 +}
823 +
824 +struct rrdhost_system_info *rrdhost_system_info_dup(struct rrdhost_system_info *system_info) {
825 + struct rrdhost_system_info *ret = callocz(1, sizeof(struct rrdhost_system_info));
826 +
827 + if(likely(system_info)) {
828 + ret->os_name = strdupz(system_info->os_name);
829 + ret->os_id = strdupz(system_info->os_id);
830 + ret->os_id_like = strdupz(system_info->os_id_like);
831 + ret->os_version = strdupz(system_info->os_version);
832 + ret->os_version_id = strdupz(system_info->os_version_id);
833 + ret->os_detection = strdupz(system_info->os_detection);
834 + ret->kernel_name = strdupz(system_info->kernel_name);
835 + ret->kernel_version = strdupz(system_info->kernel_version);
836 + ret->architecture = strdupz(system_info->architecture);
837 + ret->virtualization = strdupz(system_info->virtualization);
838 + ret->virt_detection = strdupz(system_info->virt_detection);
839 + ret->container = strdupz(system_info->container);
840 + ret->container_detection = strdupz(system_info->container_detection);
841 + }
842 +
843 + return ret;
844 +}
streaming/rrdpush.c
+40 -2
@@ -445,7 +445,21 @@ static int rrdpush_sender_thread_connect_to_master(RRDHOST *host, int default_po
445 #define HTTP_HEADER_SIZE 8192
446 char http[HTTP_HEADER_SIZE + 1];
447 snprintfz(http, HTTP_HEADER_SIZE,
448 - "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"
448 + "STREAM key=%s&hostname=%s&registry_hostname=%s&machine_guid=%s&update_every=%d&os=%s&timezone=%s&tags=%s"
449 + "&NETDATA_SYSTEM_OS_NAME=%s"
450 + "&NETDATA_SYSTEM_OS_ID=%s"
451 + "&NETDATA_SYSTEM_OS_ID_LIKE=%s"
452 + "&NETDATA_SYSTEM_OS_VERSION=%s"
453 + "&NETDATA_SYSTEM_OS_VERSION_ID=%s"
454 + "&NETDATA_SYSTEM_OS_DETECTION=%s"
455 + "&NETDATA_SYSTEM_KERNEL_NAME=%s"
456 + "&NETDATA_SYSTEM_KERNEL_VERSION=%s"
457 + "&NETDATA_SYSTEM_ARCHITECTURE=%s"
458 + "&NETDATA_SYSTEM_VIRTUALIZATION=%s"
459 + "&NETDATA_SYSTEM_VIRT_DETECTION=%s"
460 + "&NETDATA_SYSTEM_CONTAINER=%s"
461 + "&NETDATA_SYSTEM_CONTAINER_DETECTION=%s"
462 + " HTTP/1.1\r\n"
463 "User-Agent: %s/%s\r\n"
464 "Accept: */*\r\n\r\n"
465 , host->rrdpush_send_api_key
@@ -456,6 +470,19 @@ static int rrdpush_sender_thread_connect_to_master(RRDHOST *host, int default_po
470 , host->os
471 , host->timezone
472 , (host->tags)?host->tags:""
473 + , host->system_info->os_name
474 + , host->system_info->os_id
475 + , host->system_info->os_id_like
476 + , host->system_info->os_version
477 + , host->system_info->os_version_id
478 + , host->system_info->os_detection
479 + , host->system_info->kernel_name
480 + , host->system_info->kernel_version
481 + , host->system_info->architecture
482 + , host->system_info->virtualization
483 + , host->system_info->virt_detection
484 + , host->system_info->container
485 + , host->system_info->container_detection
486 , host->program_name
487 , host->program_version
488 );
@@ -821,6 +848,7 @@ static int rrdpush_receive(int fd
848 , const char *tags
849 , const char *program_name
850 , const char *program_version
851 + , struct rrdhost_system_info *system_info
852 , int update_every
853 , char *client_ip
854 , char *client_port
@@ -894,6 +922,7 @@ static int rrdpush_receive(int fd
922 , rrdpush_destination
923 , rrdpush_api_key
924 , rrdpush_send_charts_matching
925 + , system_info
926 );
927
928 if(!host) {
@@ -1027,6 +1056,7 @@ struct rrdpush_thread {
1056 char *client_port;
1057 char *program_name;
1058 char *program_version;
1059 + struct rrdhost_system_info *system_info;
1060 int update_every;
1061 };
1062
@@ -1049,6 +1079,7 @@ static void rrdpush_receiver_thread_cleanup(void *ptr) {
1079 freez(rpt->client_port);
1080 freez(rpt->program_name);
1081 freez(rpt->program_version);
1082 + rrdhost_system_info_free(rpt->system_info);
1083 freez(rpt);
1084 }
1085 }
@@ -1070,6 +1101,7 @@ static void *rrdpush_receiver_thread(void *ptr) {
1101 , rpt->tags
1102 , rpt->program_name
1103 , rpt->program_version
1104 + , rpt->system_info
1105 , rpt->update_every
1106 , rpt->client_ip
1107 , rpt->client_port
@@ -1120,6 +1152,8 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url
1152 int update_every = default_rrd_update_every;
1153 char buf[GUID_LEN + 1];
1154
1155 + struct rrdhost_system_info *system_info = callocz(1, sizeof(struct rrdhost_system_info));
1156 +
1157 while(url) {
1158 char *value = mystrsep(&url, "&");
1159 if(!value || !*value) continue;
@@ -1145,7 +1179,9 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url
1179 else if(!strcmp(name, "tags"))
1180 tags = value;
1181 else
1148 - info("STREAM [receive from [%s]:%s]: request has parameter '%s' = '%s', which is not used.", w->client_ip, w->client_port, key, value);
1182 + if(unlikely(rrdhost_set_system_info_variable(system_info, name, value))) {
1183 + info("STREAM [receive from [%s]:%s]: request has parameter '%s' = '%s', which is not used.", w->client_ip, w->client_port, key, value);
1184 + }
1185 }
1186
1187 if(!key || !*key) {
@@ -1248,6 +1284,7 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url
1284 rpt->client_ip = strdupz(w->client_ip);
1285 rpt->client_port = strdupz(w->client_port);
1286 rpt->update_every = update_every;
1287 + rpt->system_info = system_info;
1288
1289 if(w->user_agent && w->user_agent[0]) {
1290 char *t = strchr(w->user_agent, '/');
@@ -1260,6 +1297,7 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url
1297 if(t && *t) rpt->program_version = strdupz(t);
1298 }
1299
1300 +
1301 netdata_thread_t thread;
1302
1303 debug(D_SYSTEM, "starting STREAM receive thread.");
web/api/web_api_v1.c
+14 -14
@@ -736,20 +736,20 @@ inline int web_client_api_request_v1_info(RRDHOST *host, struct web_client *w, c
736 web_client_api_request_v1_info_summary_alarm_statuses(host, wb);
737 buffer_strcat(wb, "\t},\n");
738
739 - buffer_sprintf(wb, "\t\"os_name\": %s,\n", getenv("NETDATA_SYSTEM_OS_NAME"));
740 - buffer_sprintf(wb, "\t\"os_id\": \"%s\",\n", getenv("NETDATA_SYSTEM_OS_ID"));
741 - buffer_sprintf(wb, "\t\"os_id_like\": \"%s\",\n", getenv("NETDATA_SYSTEM_OS_ID_LIKE"));
742 - buffer_sprintf(wb, "\t\"os_version\": \"%s\",\n", getenv("NETDATA_SYSTEM_OS_VERSION"));
743 - buffer_sprintf(wb, "\t\"os_version_id\": \"%s\",\n", getenv("NETDATA_SYSTEM_OS_VERSION_ID"));
744 - buffer_sprintf(wb, "\t\"os_detection\": \"%s\",\n", getenv("NETDATA_SYSTEM_OS_DETECTION"));
745 - buffer_sprintf(wb, "\t\"kernel_name\": \"%s\",\n", getenv("NETDATA_SYSTEM_KERNEL_NAME"));
746 - buffer_sprintf(wb, "\t\"kernel_version\": \"%s\",\n", getenv("NETDATA_SYSTEM_KERNEL_VERSION"));
747 - buffer_sprintf(wb, "\t\"architecture\": \"%s\",\n", getenv("NETDATA_SYSTEM_ARCHITECTURE"));
748 - buffer_sprintf(wb, "\t\"virtualization\": \"%s\",\n", getenv("NETDATA_SYSTEM_VIRTUALIZATION"));
749 - buffer_sprintf(wb, "\t\"virt_detection\": \"%s\",\n", getenv("NETDATA_SYSTEM_VIRT_DETECTION"));
750 - buffer_sprintf(wb, "\t\"container\": \"%s\",\n", getenv("NETDATA_SYSTEM_CONTAINER"));
751 - buffer_sprintf(wb, "\t\"container_detection\": \"%s\",\n", getenv("NETDATA_SYSTEM_CONTAINER_DETECTION"));
752 -
739 + buffer_sprintf(wb, "\t\"os_name\": %s,\n", host->system_info->os_name);
740 + buffer_sprintf(wb, "\t\"os_id\": \"%s\",\n", host->system_info->os_id);
741 + buffer_sprintf(wb, "\t\"os_id_like\": \"%s\",\n", host->system_info->os_id_like);
742 + buffer_sprintf(wb, "\t\"os_version\": \"%s\",\n", host->system_info->os_version);
743 + buffer_sprintf(wb, "\t\"os_version_id\": \"%s\",\n", host->system_info->os_version_id);
744 + buffer_sprintf(wb, "\t\"os_detection\": \"%s\",\n", host->system_info->os_detection);
745 + buffer_sprintf(wb, "\t\"kernel_name\": \"%s\",\n", host->system_info->kernel_name);
746 + buffer_sprintf(wb, "\t\"kernel_version\": \"%s\",\n", host->system_info->kernel_version);
747 + buffer_sprintf(wb, "\t\"architecture\": \"%s\",\n", host->system_info->architecture);
748 + buffer_sprintf(wb, "\t\"virtualization\": \"%s\",\n", host->system_info->virtualization);
749 + buffer_sprintf(wb, "\t\"virt_detection\": \"%s\",\n", host->system_info->virt_detection);
750 + buffer_sprintf(wb, "\t\"container\": \"%s\",\n", host->system_info->container);
751 + buffer_sprintf(wb, "\t\"container_detection\": \"%s\",\n", host->system_info->container_detection);
752 +
753 buffer_strcat(wb, "\t\"collectors\": [");
754 chartcollectors2json(host, wb);
755 buffer_strcat(wb, "\n\t]\n");