@cryptotaxi247 / netdata-1 / commits / 7ee54c490

added alarm_variables API call that returns all the available variables for a chart

Costa Tsaousis (ktsaou) committed Nov 13, 2016 at 00:08 UTC 7ee54c4901ea66bd6f43dd04298449e5704ae6c0
7 files changed +95 -42
src/avl.c
+8 -8
@@ -283,18 +283,18 @@ avl *avl_remove(avl_tree *tree, avl *item) {
283 // ---------------------------
284 // traversing
285
286 -void avl_walker(avl *node, void (*callback)(void *)) {
286 +void avl_walker(avl *node, void (*callback)(void *entry, void *data), void *data) {
287 if(node->avl_link[0])
288 - avl_walker(node->avl_link[0], callback);
288 + avl_walker(node->avl_link[0], callback, data);
289
290 - callback(node);
290 + callback(node, data);
291
292 if(node->avl_link[1])
293 - avl_walker(node->avl_link[1], callback);
293 + avl_walker(node->avl_link[1], callback, data);
294 }
295
296 -void avl_traverse(avl_tree *t, void (*callback)(void *)) {
297 - avl_walker(t->root, callback);
296 +void avl_traverse(avl_tree *t, void (*callback)(void *entry, void *data), void *data) {
297 + avl_walker(t->root, callback, data);
298 }
299
300 // ---------------------------
@@ -372,9 +372,9 @@ avl *avl_insert_lock(avl_tree_lock *t, avl *a) {
372 return ret;
373 }
374
375 -void avl_traverse_lock(avl_tree_lock *t, void (*callback)(void *)) {
375 +void avl_traverse_lock(avl_tree_lock *t, void (*callback)(void *entry, void *data), void *data) {
376 avl_read_lock(t);
377 - avl_traverse(&t->avl_tree, callback);
377 + avl_traverse(&t->avl_tree, callback, data);
378 avl_unlock(t);
379 }
380
src/avl.h
+2 -2
@@ -80,7 +80,7 @@ void avl_init_lock(avl_tree_lock *t, int (*compar)(void *a, void *b));
80 void avl_init(avl_tree *t, int (*compar)(void *a, void *b));
81
82
83 -void avl_traverse_lock(avl_tree_lock *t, void (*callback)(void *));
84 -void avl_traverse(avl_tree *t, void (*callback)(void *));
83 +void avl_traverse_lock(avl_tree_lock *t, void (*callback)(void *entry, void *data), void *data);
84 +void avl_traverse(avl_tree *t, void (*callback)(void *entry, void *data), void *data);
85
86 #endif /* avl.h */
src/health.c
+38 -13
@@ -536,7 +536,7 @@ static inline RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *
536 // ----------------------------------------------------------------------------
537 // RRDVAR lookup
538
539 -calculated_number rrdvar2number(RRDVAR *rv) {
539 +static calculated_number rrdvar2number(RRDVAR *rv) {
540 switch(rv->type) {
541 case RRDVAR_TYPE_CALCULATED: {
542 calculated_number *n = (calculated_number *)rv->value;
@@ -569,11 +569,6 @@ calculated_number rrdvar2number(RRDVAR *rv) {
569 }
570 }
571
572 -void dump_variable(void *data) {
573 - RRDVAR *rv = (RRDVAR *)data;
574 - debug(D_HEALTH, "%50s : %20.5Lf", rv->name, rrdvar2number(rv));
575 -}
576 -
572 int health_variable_lookup(const char *variable, uint32_t hash, RRDCALC *rc, calculated_number *result) {
573 RRDSET *st = rc->rrdset;
574 RRDVAR *rv;
@@ -598,18 +593,48 @@ int health_variable_lookup(const char *variable, uint32_t hash, RRDCALC *rc, cal
593 return 1;
594 }
595
601 - debug(D_HEALTH, "Available local chart '%s' variables:", st->id);
602 - avl_traverse_lock(&st->variables_root_index, dump_variable);
596 + return 0;
597 +}
598
604 - debug(D_HEALTH, "Available family '%s' variables:", st->rrdfamily->family);
605 - avl_traverse_lock(&st->rrdfamily->variables_root_index, dump_variable);
599 +// ----------------------------------------------------------------------------
600 +// RRDVAR to JSON
601
607 - debug(D_HEALTH, "Available host '%s' variables:", st->rrdhost->hostname);
608 - avl_traverse_lock(&st->rrdhost->variables_root_index, dump_variable);
602 +struct variable2json_helper {
603 + BUFFER *buf;
604 + size_t counter;
605 +};
606
610 - return 0;
607 +static void single_variable2json(void *entry, void *data) {
608 + struct variable2json_helper *helper = (struct variable2json_helper *)data;
609 + RRDVAR *rv = (RRDVAR *)entry;
610 + calculated_number value = rrdvar2number(rv);
611 +
612 + if(unlikely(isnan(value) || isinf(value)))
613 + buffer_sprintf(helper->buf, "%s\n\t\t\"%s\": null", helper->counter?",":"", rv->name);
614 + else
615 + buffer_sprintf(helper->buf, "%s\n\t\t\"%s\": %0.5Lf", helper->counter?",":"", rv->name, (long double)value);
616 +
617 + helper->counter++;
618 }
619
620 +void health_api_v1_chart_variables2json(RRDSET *st, BUFFER *buf) {
621 + struct variable2json_helper helper = {
622 + .buf = buf,
623 + .counter = 0
624 + };
625 +
626 + buffer_sprintf(buf, "{\n\t\"chart\": \"%s.%s\",\n\t\"chart_name\": \"%s.%s\",\n\t\"chart_variables\": {", st->type, st->id, st->type, st->name);
627 + avl_traverse_lock(&st->variables_root_index, single_variable2json, (void *)&helper);
628 + buffer_sprintf(buf, "\n\t},\n\t\"family\": \"%s\",\n\t\"family_variables\": {", st->family);
629 + helper.counter = 0;
630 + avl_traverse_lock(&st->rrdfamily->variables_root_index, single_variable2json, (void *)&helper);
631 + buffer_sprintf(buf, "\n\t},\n\t\"host\": \"%s\",\n\t\"host_variables\": {", st->rrdhost->hostname);
632 + helper.counter = 0;
633 + avl_traverse_lock(&st->rrdhost->variables_root_index, single_variable2json, (void *)&helper);
634 + buffer_strcat(buf, "\n\t}\n}\n");
635 +}
636 +
637 +
638 // ----------------------------------------------------------------------------
639 // RRDDIMVAR management
640 // DIMENSION VARIABLES
src/health.h
+2
@@ -350,4 +350,6 @@ extern int health_variable_lookup(const char *variable, uint32_t hash, RRDCALC *
350 extern void health_alarms2json(RRDHOST *host, BUFFER *wb, int all);
351 extern void health_alarm_log2json(RRDHOST *host, BUFFER *wb, uint32_t after);
352
353 +void health_api_v1_chart_variables2json(RRDSET *st, BUFFER *buf);
354 +
355 #endif //NETDATA_HEALTH_H
src/rrd.c
+7 -1
@@ -353,6 +353,9 @@ char *rrdset_strncpyz_name(char *to, const char *from, size_t length)
353
354 void rrdset_set_name(RRDSET *st, const char *name)
355 {
356 + if(unlikely(st->name && !strcmp(st->name, name)))
357 + return;
358 +
359 debug(D_RRD_CALLS, "rrdset_set_name() old: %s, new: %s", st->name, name);
360
361 char b[CONFIG_MAX_VALUE + 1];
@@ -765,7 +768,10 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, long multiplier
768
769 void rrddim_set_name(RRDSET *st, RRDDIM *rd, const char *name)
770 {
768 - debug(D_RRD_CALLS, "rrddim_set_name() %s.%s", st->name, rd->name);
771 + if(unlikely(rd->name && !strcmp(rd->name, name)))
772 + return;
773 +
774 + debug(D_RRD_CALLS, "rrddim_set_name() from %s.%s to %s.%s", st->name, rd->name, st->name, name);
775
776 char varname[CONFIG_MAX_NAME + 1];
777 snprintfz(varname, CONFIG_MAX_NAME, "dim %s name", rd->id);
src/unit_test.c
+10 -4
@@ -975,9 +975,9 @@ int run_test(struct test *test)
975 return errors;
976 }
977
978 -void test_variable_renames(void) {
978 +static int test_variable_renames(void) {
979 fprintf(stderr, "Creating chart\n");
980 - RRDSET *st = rrdset_create("netdata", "CHARTID1", NULL, "netdata", NULL, "Unit Testing", "a value", 1, 1, RRDSET_TYPE_LINE);
980 + RRDSET *st = rrdset_create("chart", "ID", NULL, "family", "context", "Unit Testing", "a value", 1, 1, RRDSET_TYPE_LINE);
981 fprintf(stderr, "Created chart with id '%s', name '%s'\n", st->id, st->name);
982
983 fprintf(stderr, "Creating dimension DIM1\n");
@@ -1011,12 +1011,18 @@ void test_variable_renames(void) {
1011 fprintf(stderr, "Renaming dimension DIM2 to DIM2NAME2\n");
1012 rrddim_set_name(st, rd2, "DIM2NAME2");
1013 fprintf(stderr, "Renamed dimension with id '%s' to name '%s'\n", rd2->id, rd2->name);
1014 +
1015 + BUFFER *buf = buffer_create(1);
1016 + health_api_v1_chart_variables2json(st, buf);
1017 + fprintf(stderr, "%s", buffer_tostring(buf));
1018 + buffer_free(buf);
1019 + return 1;
1020 }
1021
1022 int run_all_mockup_tests(void)
1023 {
1018 - test_variable_renames();
1019 - exit(1);
1024 + if(!test_variable_renames())
1025 + return 1;
1026
1027 if(run_test(&test1))
1028 return 1;
src/web_client.c
+28 -14
@@ -700,17 +700,7 @@ int web_client_api_request_v1_alarm_log(struct web_client *w, char *url)
700 return 200;
701 }
702
703 -int web_client_api_request_v1_charts(struct web_client *w, char *url)
704 -{
705 - (void)url;
706 -
707 - buffer_flush(w->response.data);
708 - w->response.data->contenttype = CT_APPLICATION_JSON;
709 - rrd_stats_api_v1_charts(w->response.data);
710 - return 200;
711 -}
712 -
713 -int web_client_api_request_v1_chart(struct web_client *w, char *url)
703 +int web_client_api_request_single_chart(struct web_client *w, char *url, void callback(RRDSET *st, BUFFER *buf))
704 {
705 int ret = 400;
706 char *chart = NULL;
@@ -749,13 +739,33 @@ int web_client_api_request_v1_chart(struct web_client *w, char *url)
739 }
740
741 w->response.data->contenttype = CT_APPLICATION_JSON;
752 - rrd_stats_api_v1_chart(st, w->response.data);
742 + callback(st, w->response.data);
743 return 200;
744
755 -cleanup:
745 + cleanup:
746 return ret;
747 }
748
749 +int web_client_api_request_v1_alarm_variables(struct web_client *w, char *url)
750 +{
751 + return web_client_api_request_single_chart(w, url, health_api_v1_chart_variables2json);
752 +}
753 +
754 +int web_client_api_request_v1_charts(struct web_client *w, char *url)
755 +{
756 + (void)url;
757 +
758 + buffer_flush(w->response.data);
759 + w->response.data->contenttype = CT_APPLICATION_JSON;
760 + rrd_stats_api_v1_charts(w->response.data);
761 + return 200;
762 +}
763 +
764 +int web_client_api_request_v1_chart(struct web_client *w, char *url)
765 +{
766 + return web_client_api_request_single_chart(w, url, rrd_stats_api_v1_chart);
767 +}
768 +
769 int web_client_api_request_v1_badge(struct web_client *w, char *url) {
770 int ret = 400;
771 buffer_flush(w->response.data);
@@ -1405,7 +1415,7 @@ int web_client_api_request_v1_registry(struct web_client *w, char *url)
1415 }
1416
1417 int web_client_api_request_v1(struct web_client *w, char *url) {
1408 - static uint32_t hash_data = 0, hash_chart = 0, hash_charts = 0, hash_registry = 0, hash_badge = 0, hash_alarms = 0, hash_alarm_log = 0;
1418 + static uint32_t hash_data = 0, hash_chart = 0, hash_charts = 0, hash_registry = 0, hash_badge = 0, hash_alarms = 0, hash_alarm_log = 0, hash_alarm_variables = 0;
1419
1420 if(unlikely(hash_data == 0)) {
1421 hash_data = simple_hash("data");
@@ -1415,6 +1425,7 @@ int web_client_api_request_v1(struct web_client *w, char *url) {
1425 hash_badge = simple_hash("badge.svg");
1426 hash_alarms = simple_hash("alarms");
1427 hash_alarm_log = simple_hash("alarm_log");
1428 + hash_alarm_variables = simple_hash("alarm_variables");
1429 }
1430
1431 // get the command
@@ -1444,6 +1455,9 @@ int web_client_api_request_v1(struct web_client *w, char *url) {
1455 else if(hash == hash_alarm_log && !strcmp(tok, "alarm_log"))
1456 return web_client_api_request_v1_alarm_log(w, url);
1457
1458 + else if(hash == hash_alarm_variables && !strcmp(tok, "alarm_variables"))
1459 + return web_client_api_request_v1_alarm_variables(w, url);
1460 +
1461 else {
1462 buffer_flush(w->response.data);
1463 buffer_sprintf(w->response.data, "Unsupported v1 API command: %s", tok);