From 81581f9719bc56f01d5aa08952671d65fda9867a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 8 May 2023 18:27:08 +0200 Subject: Merging upstream version 1.39.0. Signed-off-by: Daniel Baumann --- web/api/formatters/json/json.c | 170 +++++++++++++++++++++++++++-------------- 1 file changed, 112 insertions(+), 58 deletions(-) (limited to 'web/api/formatters/json/json.c') diff --git a/web/api/formatters/json/json.c b/web/api/formatters/json/json.c index 3cad3e914..d5b8c7570 100644 --- a/web/api/formatters/json/json.c +++ b/web/api/formatters/json/json.c @@ -42,7 +42,7 @@ void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) { strcpy(post_value, "}"); strcpy(post_line, "]}"); snprintfz(data_begin, 100, "\n ],\n %srows%s:\n [\n", kq, kq); - strcpy(finish, "\n]\n}"); + strcpy(finish, "\n ]\n }"); snprintfz(overflow_annotation, 200, ",{%sv%s:%sRESET OR OVERFLOW%s},{%sv%s:%sThe counters have been wrapped.%s}", kq, kq, sq, sq, kq, kq, sq, sq); snprintfz(normal_annotation, 200, ",{%sv%s:null},{%sv%s:null}", kq, kq, kq, kq); @@ -69,9 +69,9 @@ void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) { dates_with_new = 0; } if( options & RRDR_OPTION_OBJECTSROWS ) - strcpy(pre_date, " { "); + strcpy(pre_date, " {"); else - strcpy(pre_date, " [ "); + strcpy(pre_date, " ["); strcpy(pre_label, ",\""); strcpy(post_label, "\""); strcpy(pre_value, ","); @@ -79,10 +79,10 @@ void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) { strcpy(post_line, "}"); else strcpy(post_line, "]"); - snprintfz(data_begin, 100, "],\n %sdata%s:\n [\n", kq, kq); - strcpy(finish, "\n]\n}"); + snprintfz(data_begin, 100, "],\n %sdata%s:[\n", kq, kq); + strcpy(finish, "\n ]\n }"); - buffer_sprintf(wb, "{\n %slabels%s: [", kq, kq); + buffer_sprintf(wb, "{\n %slabels%s:[", kq, kq); buffer_sprintf(wb, "%stime%s", sq, sq); if( options & RRDR_OPTION_OBJECTSROWS ) @@ -104,18 +104,16 @@ void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) { // ------------------------------------------------------------------------- // print the JSON header - QUERY_TARGET *qt = r->internal.qt; long c, i; - const long used = qt->query.used; + const long used = (long)r->d; // print the header lines for(c = 0, i = 0; c < used ; c++) { - if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue; - if(unlikely(!(r->od[c] & RRDR_DIMENSION_QUERIED))) continue; - if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue; + if(!rrdr_dimension_should_be_exposed(r->od[c], options)) + continue; buffer_fast_strcat(wb, pre_label, pre_label_len); - buffer_strcat(wb, string2str(qt->query.array[c].dimension.name)); + buffer_strcat(wb, string2str(r->dn[c])); buffer_fast_strcat(wb, post_label, post_label_len); i++; } @@ -151,7 +149,6 @@ void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) { ); // for each line in the array - NETDATA_DOUBLE total = 1; for(i = start; i != end ;i += step) { NETDATA_DOUBLE *cn = &r->v[ i * r->d ]; RRDR_VALUE_FLAGS *co = &r->o[ i * r->d ]; @@ -203,7 +200,7 @@ void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) { if(unlikely( options & RRDR_OPTION_OBJECTSROWS )) buffer_fast_strcat(wb, object_rows_time, object_rows_time_len); - buffer_rrd_value(wb, (NETDATA_DOUBLE)r->t[i]); + buffer_print_netdata_double(wb, (NETDATA_DOUBLE) r->t[i]); // in ms if(unlikely(options & RRDR_OPTION_MILLISECONDS)) @@ -212,33 +209,10 @@ void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) { buffer_fast_strcat(wb, post_date, post_date_len); } - int set_min_max = 0; - if(unlikely(options & RRDR_OPTION_PERCENTAGE)) { - total = 0; - for(c = 0; c < used ;c++) { - if(unlikely(!(r->od[c] & RRDR_DIMENSION_QUERIED))) continue; - - NETDATA_DOUBLE n; - if(unlikely(options & RRDR_OPTION_INTERNAL_AR)) - n = ar[c]; - else - n = cn[c]; - - if(likely((options & RRDR_OPTION_ABSOLUTE) && n < 0)) - n = -n; - - total += n; - } - // prevent a division by zero - if(total == 0) total = 1; - set_min_max = 1; - } - // for each dimension for(c = 0; c < used ;c++) { - if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue; - if(unlikely(!(r->od[c] & RRDR_DIMENSION_QUERIED))) continue; - if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue; + if(!rrdr_dimension_should_be_exposed(r->od[c], options)) + continue; NETDATA_DOUBLE n; if(unlikely(options & RRDR_OPTION_INTERNAL_AR)) @@ -249,39 +223,119 @@ void rrdr2json(RRDR *r, BUFFER *wb, RRDR_OPTIONS options, int datatable) { buffer_fast_strcat(wb, pre_value, pre_value_len); if(unlikely( options & RRDR_OPTION_OBJECTSROWS )) - buffer_sprintf(wb, "%s%s%s: ", kq, string2str(qt->query.array[c].dimension.name), kq); + buffer_sprintf(wb, "%s%s%s: ", kq, string2str(r->dn[c]), kq); - if(co[c] & RRDR_VALUE_EMPTY && !(options & RRDR_OPTION_INTERNAL_AR)) { + if(co[c] & RRDR_VALUE_EMPTY && !(options & (RRDR_OPTION_INTERNAL_AR))) { if(unlikely(options & RRDR_OPTION_NULL2ZERO)) buffer_fast_strcat(wb, "0", 1); else buffer_fast_strcat(wb, "null", 4); } - else { - if(unlikely((options & RRDR_OPTION_ABSOLUTE) && n < 0)) - n = -n; + else + buffer_print_netdata_double(wb, n); - if(unlikely(options & RRDR_OPTION_PERCENTAGE)) { - n = n * 100 / total; + buffer_fast_strcat(wb, post_value, post_value_len); + } - if(unlikely(set_min_max)) { - r->min = r->max = n; - set_min_max = 0; - } + buffer_fast_strcat(wb, post_line, post_line_len); + } + + buffer_strcat(wb, finish); + //info("RRD2JSON(): %s: END", r->st->id); +} + + +void rrdr2json_v2(RRDR *r, BUFFER *wb) { + QUERY_TARGET *qt = r->internal.qt; + RRDR_OPTIONS options = qt->window.options; + + bool expose_gbc = query_target_aggregatable(qt); + + buffer_json_member_add_object(wb, "result"); - if(n < r->min) r->min = n; - if(n > r->max) r->max = n; + buffer_json_member_add_array(wb, "labels"); + buffer_json_add_array_item_string(wb, "time"); + long d, i; + const long used = (long)r->d; + for(d = 0, i = 0; d < used ; d++) { + if(!rrdr_dimension_should_be_exposed(r->od[d], options)) + continue; + + buffer_json_add_array_item_string(wb, string2str(r->di[d])); + i++; + } + buffer_json_array_close(wb); // labels + + buffer_json_member_add_object(wb, "point"); + buffer_json_member_add_uint64(wb, "value", 0); + buffer_json_member_add_uint64(wb, "arp", 1); + buffer_json_member_add_uint64(wb, "pa", 2); + if(expose_gbc) + buffer_json_member_add_uint64(wb, "count", 3); + buffer_json_object_close(wb); + + buffer_json_member_add_array(wb, "data"); + if(i) { + long start = 0, end = rrdr_rows(r), step = 1; + if (!(options & RRDR_OPTION_REVERSED)) { + start = rrdr_rows(r) - 1; + end = -1; + step = -1; + } + + // for each line in the array + for (i = start; i != end; i += step) { + NETDATA_DOUBLE *cn = &r->v[ i * r->d ]; + RRDR_VALUE_FLAGS *co = &r->o[ i * r->d ]; + NETDATA_DOUBLE *ar = &r->ar[ i * r->d ]; + uint32_t *gbc = &r->gbc [ i * r->d ]; + time_t now = r->t[i]; + + buffer_json_add_array_item_array(wb); // row + + if (options & RRDR_OPTION_MILLISECONDS) + buffer_json_add_array_item_time_ms(wb, now); // the time + else + buffer_json_add_array_item_time_t(wb, now); // the time + + for (d = 0; d < used; d++) { + if (!rrdr_dimension_should_be_exposed(r->od[d], options)) + continue; + + RRDR_VALUE_FLAGS o = co[d]; + + buffer_json_add_array_item_array(wb); // point + + // add the value + NETDATA_DOUBLE n = cn[d]; + + if(o & RRDR_VALUE_EMPTY) { + if (unlikely(options & RRDR_OPTION_NULL2ZERO)) + buffer_json_add_array_item_double(wb, 0); + else + buffer_json_add_array_item_double(wb, NAN); } + else + buffer_json_add_array_item_double(wb, n); + + // add the anomaly + buffer_json_add_array_item_double(wb, ar[d]); - buffer_rrd_value(wb, n); + // add the point annotations + buffer_json_add_array_item_uint64(wb, o); + + // add the count + if(expose_gbc) + buffer_json_add_array_item_uint64(wb, gbc[d]); + + buffer_json_array_close(wb); // point } - buffer_fast_strcat(wb, post_value, post_value_len); + buffer_json_array_close(wb); // row } - - buffer_fast_strcat(wb, post_line, post_line_len); } - buffer_strcat(wb, finish); - //info("RRD2JSON(): %s: END", r->st->id); + buffer_json_array_close(wb); // data + + buffer_json_object_close(wb); // annotations } -- cgit v1.2.3