@cryptotaxi247 / netdata-1 / commits / 238cb2979

/api/v2 part 10 (#14904)

/api/v2/weights nonzero output

Costa Tsaousis committed Apr 13, 2023 at 15:27 UTC 238cb29793398cb258efb9a56bf031e9c00a858e
3 files changed +107 -45
libnetdata/libnetdata.h
+1
@@ -405,6 +405,7 @@ typedef struct storage_point {
405
406 #define storage_point_is_unset(x) (!(x).count)
407 #define storage_point_is_gap(x) (!netdata_double_isnumber((x).sum))
408 +#define storage_point_is_zero(x) (!(x).count || (netdata_double_is_zero((x).min) && netdata_double_is_zero((x).max) && netdata_double_is_zero((x).sum) && (x).anomaly_count == 0))
409
410 #define storage_point_merge_to(dst, src) do { \
411 if(storage_point_is_unset(dst)) \
libnetdata/storage_number/storage_number.h
+3
@@ -70,6 +70,9 @@ typedef long long collected_number;
70 #define netdata_double_isnumber(a) (fpclassify(a) != FP_NAN && fpclassify(a) != FP_INFINITE)
71 #endif
72
73 +#define netdata_double_is_zero(a) (!netdata_double_isnumber(a) || considered_equal_ndd(a, 0.0))
74 +#define netdata_double_is_nonzero(a) (!netdata_double_is_zero(a))
75 +
76 typedef uint32_t storage_number;
77
78 typedef struct storage_number_tier1 {
web/api/queries/weights.c
+103 -45
@@ -443,10 +443,10 @@ static void results_header_to_json_v2(DICTIONARY *results __maybe_unused, BUFFER
443
444 if(method == WEIGHTS_METHOD_MC_KS2 || method == WEIGHTS_METHOD_MC_VOLUME) {
445 buffer_json_member_add_object(wb, "baseline");
446 - buffer_json_member_add_time_t(wb, "baseline_after", baseline_after);
447 - buffer_json_member_add_time_t(wb, "baseline_before", baseline_before);
448 - buffer_json_member_add_time_t(wb, "baseline_duration", baseline_before - baseline_after);
449 - buffer_json_member_add_uint64(wb, "baseline_points", points << shifts);
446 + buffer_json_member_add_time_t(wb, "after", baseline_after);
447 + buffer_json_member_add_time_t(wb, "before", baseline_before);
448 + buffer_json_member_add_time_t(wb, "duration", baseline_before - baseline_after);
449 + buffer_json_member_add_uint64(wb, "points", points << shifts);
450 buffer_json_object_close(wb);
451 }
452
@@ -454,7 +454,6 @@ static void results_header_to_json_v2(DICTIONARY *results __maybe_unused, BUFFER
454
455 buffer_json_member_add_object(wb, "db");
456 {
457 - buffer_json_member_add_double(wb, "query_time_ms", (double) duration / (double) USEC_PER_MS);
457 buffer_json_member_add_uint64(wb, "db_queries", stats->db_queries);
458 buffer_json_member_add_uint64(wb, "query_result_points", stats->result_points);
459 buffer_json_member_add_uint64(wb, "binary_searches", stats->binary_searches);
@@ -671,6 +670,7 @@ static void multinode_data_schema(BUFFER *wb, RRDR_OPTIONS options __maybe_unuse
670
671 struct dict_unique_node {
672 bool existing;
673 + bool exposed;
674 uint32_t i;
675 RRDHOST *host;
676 usec_t duration_ut;
@@ -678,12 +678,14 @@ struct dict_unique_node {
678
679 struct dict_unique_name_units {
680 bool existing;
681 + bool exposed;
682 uint32_t i;
683 const char *units;
684 };
685
686 struct dict_unique_id_name {
687 bool existing;
688 + bool exposed;
689 uint32_t i;
690 const char *id;
691 const char *name;
@@ -701,7 +703,7 @@ static inline struct dict_unique_node *dict_unique_node_add(DICTIONARY *dict, RR
703 return dun;
704 }
705
704 -static inline ssize_t dict_unique_name_units_add(DICTIONARY *dict, const char *name, const char *units, ssize_t *max_id) {
706 +static inline struct dict_unique_name_units *dict_unique_name_units_add(DICTIONARY *dict, const char *name, const char *units, ssize_t *max_id) {
707 struct dict_unique_name_units *dun = dictionary_set(dict, name, NULL, sizeof(struct dict_unique_name_units));
708 if(!dun->existing) {
709 dun->units = units;
@@ -710,10 +712,10 @@ static inline ssize_t dict_unique_name_units_add(DICTIONARY *dict, const char *n
712 (*max_id)++;
713 }
714
713 - return (ssize_t)dun->i;
715 + return dun;
716 }
717
716 -static inline ssize_t dict_unique_id_name_add(DICTIONARY *dict, const char *id, const char *name, ssize_t *max_id) {
718 +static inline struct dict_unique_id_name *dict_unique_id_name_add(DICTIONARY *dict, const char *id, const char *name, ssize_t *max_id) {
719 char key[1024 + 1];
720 snprintfz(key, 1024, "%s:%s", id, name);
721 struct dict_unique_id_name *dun = dictionary_set(dict, key, NULL, sizeof(struct dict_unique_id_name));
@@ -725,8 +727,17 @@ static inline ssize_t dict_unique_id_name_add(DICTIONARY *dict, const char *id,
727 dun->name = name;
728 }
729
728 - return (ssize_t)dun->i;
730 + return dun;
731 }
732 +
733 +static inline bool storage_point_should_be_exposed(struct aggregated_weight *aw, RRDR_OPTIONS options, bool baseline) {
734 + if((options & RRDR_OPTION_NONZERO) && netdata_double_is_zero(aw->min) && netdata_double_is_zero(aw->max) && netdata_double_is_zero(aw->sum) &&
735 + storage_point_is_zero(aw->hsp) && (!baseline || storage_point_is_zero(aw->bsp)))
736 + return false;
737 +
738 + return true;
739 +}
740 +
741 static size_t registered_results_to_json_multinode_no_group_by(
742 DICTIONARY *results, BUFFER *wb,
743 time_t after, time_t before,
@@ -760,7 +771,10 @@ static size_t registered_results_to_json_multinode_no_group_by(
771 RRDHOST *last_host = NULL;
772 RRDCONTEXT_ACQUIRED *last_rca = NULL;
773 RRDINSTANCE_ACQUIRED *last_ria = NULL;
774 + struct dict_unique_name_units *context_dun = NULL;
775 struct dict_unique_node *node_dun = NULL;
776 + struct dict_unique_id_name *instance_dun = NULL;
777 + struct dict_unique_id_name *dimension_dun = NULL;
778 ssize_t di = -1, ii = -1, ci = -1, ni = -1;
779 ssize_t di_max = 0, ii_max = 0, ci_max = 0, ni_max = 0;
780 size_t total_dimensions = 0;
@@ -768,21 +782,31 @@ static size_t registered_results_to_json_multinode_no_group_by(
782
783 // close instance
784 if(t->ria != last_ria && last_ria) {
771 - storage_point_to_json(wb, WPT_INSTANCE, di, ii, ci, ni, &instance_aw, options, baseline);
785 + if(storage_point_should_be_exposed(&instance_aw, options, baseline)) {
786 + storage_point_to_json(wb, WPT_INSTANCE, di, ii, ci, ni, &instance_aw, options, baseline);
787 + instance_dun->exposed = true;
788 + }
789 +
790 last_ria = NULL;
791 instance_aw = AGGREGATED_WEIGHT_EMPTY;
792 }
793
794 // close context
795 if(t->rca != last_rca && last_rca) {
778 - storage_point_to_json(wb, WPT_CONTEXT, di, ii, ci, ni, &context_aw, options, baseline);
796 + if(storage_point_should_be_exposed(&context_aw, options, baseline)) {
797 + storage_point_to_json(wb, WPT_CONTEXT, di, ii, ci, ni, &context_aw, options, baseline);
798 + context_dun->exposed = true;
799 + }
800 last_rca = NULL;
801 context_aw = AGGREGATED_WEIGHT_EMPTY;
802 }
803
804 // close node
805 if(t->host != last_host && last_host) {
785 - storage_point_to_json(wb, WPT_NODE, di, ii, ci, ni, &node_aw, options, baseline);
806 + if(storage_point_should_be_exposed(&node_aw, options, baseline)) {
807 + storage_point_to_json(wb, WPT_NODE, di, ii, ci, ni, &node_aw, options, baseline);
808 + node_dun->exposed = true;
809 + }
810 last_host = NULL;
811 node_aw = AGGREGATED_WEIGHT_EMPTY;
812 }
@@ -797,17 +821,20 @@ static size_t registered_results_to_json_multinode_no_group_by(
821 // open context
822 if(t->rca != last_rca) {
823 last_rca = t->rca;
800 - ci = dict_unique_name_units_add(dict_contexts, rrdcontext_acquired_id(t->rca),
801 - rrdcontext_acquired_units(t->rca), &ci_max);
824 + context_dun = dict_unique_name_units_add(dict_contexts, rrdcontext_acquired_id(t->rca),
825 + rrdcontext_acquired_units(t->rca), &ci_max);
826 + ci = context_dun->i;
827 }
828
829 // open instance
830 if(t->ria != last_ria) {
831 last_ria = t->ria;
807 - ii = dict_unique_id_name_add(dict_instances, rrdinstance_acquired_id(t->ria), rrdinstance_acquired_name(t->ria), &ii_max);
832 + instance_dun = dict_unique_id_name_add(dict_instances, rrdinstance_acquired_id(t->ria), rrdinstance_acquired_name(t->ria), &ii_max);
833 + ii = instance_dun->i;
834 }
835
810 - di = dict_unique_id_name_add(dict_dimensions, rrdmetric_acquired_id(t->rma), rrdmetric_acquired_name(t->rma), &di_max);
836 + dimension_dun = dict_unique_id_name_add(dict_dimensions, rrdmetric_acquired_id(t->rma), rrdmetric_acquired_name(t->rma), &di_max);
837 + di = dimension_dun->i;
838
839 struct aggregated_weight aw = {
840 .min = t->value,
@@ -817,7 +844,14 @@ static size_t registered_results_to_json_multinode_no_group_by(
844 .hsp = t->highlighted,
845 .bsp = t->baseline,
846 };
820 - storage_point_to_json(wb, WPT_DIMENSION, di, ii, ci, ni, &aw, options, baseline);
847 +
848 + if(storage_point_should_be_exposed(&aw, options, baseline)) {
849 + storage_point_to_json(wb, WPT_DIMENSION, di, ii, ci, ni, &aw, options, baseline);
850 + node_dun->exposed = true;
851 + context_dun->exposed = true;
852 + instance_dun->exposed = true;
853 + dimension_dun->exposed = true;
854 + }
855
856 merge_into_aw(instance_aw, t);
857 merge_into_aw(context_aw, t);
@@ -829,16 +863,22 @@ static size_t registered_results_to_json_multinode_no_group_by(
863 dfe_done(t);
864
865 // close instance
832 - if(last_ria)
866 + if(last_ria && storage_point_should_be_exposed(&instance_aw, options, baseline)) {
867 storage_point_to_json(wb, WPT_INSTANCE, di, ii, ci, ni, &instance_aw, options, baseline);
868 + instance_dun->exposed = true;
869 + }
870
871 // close context
836 - if(last_rca)
872 + if(last_rca && storage_point_should_be_exposed(&context_aw, options, baseline)) {
873 storage_point_to_json(wb, WPT_CONTEXT, di, ii, ci, ni, &context_aw, options, baseline);
874 + context_dun->exposed = true;
875 + }
876
877 // close node
840 - if(last_host)
878 + if(last_host && storage_point_should_be_exposed(&node_aw, options, baseline)) {
879 storage_point_to_json(wb, WPT_NODE, di, ii, ci, ni, &node_aw, options, baseline);
880 + node_dun->exposed = true;
881 + }
882
883 buffer_json_array_close(wb); // points
884
@@ -847,9 +887,12 @@ static size_t registered_results_to_json_multinode_no_group_by(
887 {
888 struct dict_unique_node *dun;
889 dfe_start_read(dict_nodes, dun) {
850 - buffer_json_add_array_item_object(wb);
851 - buffer_json_node_add_v2(wb, dun->host, dun->i, dun->duration_ut);
852 - buffer_json_object_close(wb);
890 + if(!dun->exposed)
891 + continue;
892 +
893 + buffer_json_add_array_item_object(wb);
894 + buffer_json_node_add_v2(wb, dun->host, dun->i, dun->duration_ut);
895 + buffer_json_object_close(wb);
896 }
897 dfe_done(dun);
898 }
@@ -859,12 +902,15 @@ static size_t registered_results_to_json_multinode_no_group_by(
902 {
903 struct dict_unique_name_units *dun;
904 dfe_start_read(dict_contexts, dun) {
862 - buffer_json_add_array_item_object(wb);
863 - buffer_json_member_add_string(wb, "id", dun_dfe.name);
864 - buffer_json_member_add_string(wb, "units", dun->units);
865 - buffer_json_member_add_int64(wb, "ci", dun->i);
866 - buffer_json_object_close(wb);
867 - }
905 + if(!dun->exposed)
906 + continue;
907 +
908 + buffer_json_add_array_item_object(wb);
909 + buffer_json_member_add_string(wb, "id", dun_dfe.name);
910 + buffer_json_member_add_string(wb, "units", dun->units);
911 + buffer_json_member_add_int64(wb, "ci", dun->i);
912 + buffer_json_object_close(wb);
913 + }
914 dfe_done(dun);
915 }
916 buffer_json_array_close(wb);
@@ -873,13 +919,16 @@ static size_t registered_results_to_json_multinode_no_group_by(
919 {
920 struct dict_unique_id_name *dun;
921 dfe_start_read(dict_instances, dun) {
876 - buffer_json_add_array_item_object(wb);
877 - buffer_json_member_add_string(wb, "id", dun->id);
878 - if(dun->id != dun->name)
879 - buffer_json_member_add_string(wb, "nm", dun->name);
880 - buffer_json_member_add_int64(wb, "ii", dun->i);
881 - buffer_json_object_close(wb);
882 - }
922 + if(!dun->exposed)
923 + continue;
924 +
925 + buffer_json_add_array_item_object(wb);
926 + buffer_json_member_add_string(wb, "id", dun->id);
927 + if(dun->id != dun->name)
928 + buffer_json_member_add_string(wb, "nm", dun->name);
929 + buffer_json_member_add_int64(wb, "ii", dun->i);
930 + buffer_json_object_close(wb);
931 + }
932 dfe_done(dun);
933 }
934 buffer_json_array_close(wb);
@@ -888,13 +937,16 @@ static size_t registered_results_to_json_multinode_no_group_by(
937 {
938 struct dict_unique_id_name *dun;
939 dfe_start_read(dict_dimensions, dun) {
891 - buffer_json_add_array_item_object(wb);
892 - buffer_json_member_add_string(wb, "id", dun->id);
893 - if(dun->id != dun->name)
894 - buffer_json_member_add_string(wb, "nm", dun->name);
895 - buffer_json_member_add_int64(wb, "di", dun->i);
896 - buffer_json_object_close(wb);
897 - }
940 + if(!dun->exposed)
941 + continue;
942 +
943 + buffer_json_add_array_item_object(wb);
944 + buffer_json_member_add_string(wb, "id", dun->id);
945 + if(dun->id != dun->name)
946 + buffer_json_member_add_string(wb, "nm", dun->name);
947 + buffer_json_member_add_int64(wb, "di", dun->i);
948 + buffer_json_object_close(wb);
949 + }
950 dfe_done(dun);
951 }
952 buffer_json_array_close(wb);
@@ -1018,9 +1070,15 @@ static size_t registered_results_to_json_multinode_group_by(
1070 const char *k = aw_dfe.name;
1071 const char *n = aw->name;
1072
1073 + if(!storage_point_should_be_exposed(aw, options, baseline))
1074 + continue;
1075 +
1076 buffer_json_add_array_item_object(wb);
1077 buffer_json_member_add_string(wb, "id", k);
1023 - buffer_json_member_add_string(wb, "nm", n);
1078 +
1079 + if(strcmp(k, n) != 0)
1080 + buffer_json_member_add_string(wb, "nm", n);
1081 +
1082 storage_point_to_json(wb, WPT_GROUP, 0, 0, 0, 0, aw, options, baseline);
1083 buffer_json_object_close(wb);
1084
@@ -1934,7 +1992,7 @@ int web_api_v12_weights(BUFFER *wb, QUERY_WEIGHTS_REQUEST *qwr) {
1992 break;
1993 }
1994
1937 - if(!added_dimensions) {
1995 + if(!added_dimensions && qwr->version < 2) {
1996 error = "no results produced.";
1997 resp = HTTP_RESP_NOT_FOUND;
1998 }