summaryrefslogtreecommitdiffstats
path: root/src/web/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/web/api')
-rw-r--r--src/web/api/formatters/value/value.c68
-rw-r--r--src/web/api/queries/query.c4
-rw-r--r--src/web/api/queries/query.h2
-rw-r--r--src/web/api/queries/rrdr.h51
-rw-r--r--src/web/api/web_api_v1.c21
-rw-r--r--src/web/api/web_api_v1.h1
6 files changed, 85 insertions, 62 deletions
diff --git a/src/web/api/formatters/value/value.c b/src/web/api/formatters/value/value.c
index 1d07f62f6a..84faff4011 100644
--- a/src/web/api/formatters/value/value.c
+++ b/src/web/api/formatters/value/value.c
@@ -2,7 +2,6 @@
#include "value.h"
-
inline NETDATA_DOUBLE rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all_values_are_null, NETDATA_DOUBLE *anomaly_rate) {
size_t c;
@@ -10,61 +9,64 @@ inline NETDATA_DOUBLE rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all
RRDR_VALUE_FLAGS *co = &r->o[ i * r->d ];
NETDATA_DOUBLE *ar = &r->ar[ i * r->d ];
- NETDATA_DOUBLE sum = 0, min = 0, max = 0, v;
- int all_null = 1, init = 1;
+ NETDATA_DOUBLE sum = NAN, min = NAN, max = NAN, v = NAN;
+ size_t dims = 0;
NETDATA_DOUBLE total_anomaly_rate = 0;
// for each dimension
for (c = 0; c < r->d ; c++) {
- if(!rrdr_dimension_should_be_exposed(r->od[c], options))
+ if(unlikely(!rrdr_dimension_should_be_exposed(r->od[c], options)))
+ continue;
+
+ if(unlikely((co[c] & RRDR_VALUE_EMPTY)))
continue;
NETDATA_DOUBLE n = cn[c];
- if(unlikely(init)) {
- if(n > 0) {
- min = 0;
- max = n;
- }
- else {
- min = n;
- max = 0;
- }
- init = 0;
- }
+ if(unlikely(!dims))
+ min = max = n;
- if(likely(!(co[c] & RRDR_VALUE_EMPTY))) {
- all_null = 0;
- sum += n;
- }
+ sum += n;
- if(n < min) min = n;
- if(n > max) max = n;
+ if (n < min) min = n;
+ if (n > max) max = n;
total_anomaly_rate += ar[c];
- }
- if(anomaly_rate) {
- if(!r->d) *anomaly_rate = 0;
- else *anomaly_rate = total_anomaly_rate / (NETDATA_DOUBLE)r->d;
+ dims++;
}
- if(unlikely(all_null)) {
- if(likely(all_values_are_null))
+ if(!dims) {
+ if(anomaly_rate)
+ *anomaly_rate = 0;
+
+ if(all_values_are_null)
*all_values_are_null = 1;
- return 0;
- }
- else {
- if(likely(all_values_are_null))
- *all_values_are_null = 0;
+
+ return (options & RRDR_OPTION_NULL2ZERO) ? 0 : NAN;
}
- if(options & RRDR_OPTION_MIN2MAX)
+ if(anomaly_rate)
+ *anomaly_rate = total_anomaly_rate / (NETDATA_DOUBLE)dims;
+
+ if(all_values_are_null)
+ *all_values_are_null = 0;
+
+ if(options & RRDR_OPTION_DIMS_MIN2MAX)
v = max - min;
+ else if(options & RRDR_OPTION_DIMS_AVERAGE)
+ v = sum / (NETDATA_DOUBLE)dims;
+ else if(options & RRDR_OPTION_DIMS_MIN)
+ v = min;
+ else if(options & RRDR_OPTION_DIMS_MAX)
+ v = max;
else
v = sum;
+ if((options & RRDR_OPTION_NULL2ZERO) && (isnan(v) || isinf(v)))
+ v = 0;
+
return v;
}
diff --git a/src/web/api/queries/query.c b/src/web/api/queries/query.c
index 5b94948435..fe1664068f 100644
--- a/src/web/api/queries/query.c
+++ b/src/web/api/queries/query.c
@@ -276,7 +276,7 @@ static struct {
},
{.name = "trimmed-median5",
.hash = 0,
- .value = RRDR_GROUPING_TRIMMED_MEDIAN5,
+ .value = RRDR_GROUPING_TRIMMED_MEDIAN,
.add_flush = RRDR_GROUPING_MEDIAN,
.init = NULL,
.create= tg_median_create_trimmed_5,
@@ -336,7 +336,7 @@ static struct {
},
{.name = "trimmed-median",
.hash = 0,
- .value = RRDR_GROUPING_TRIMMED_MEDIAN5,
+ .value = RRDR_GROUPING_TRIMMED_MEDIAN,
.add_flush = RRDR_GROUPING_MEDIAN,
.init = NULL,
.create= tg_median_create_trimmed_5,
diff --git a/src/web/api/queries/query.h b/src/web/api/queries/query.h
index c47930d480..37202a0bad 100644
--- a/src/web/api/queries/query.h
+++ b/src/web/api/queries/query.h
@@ -26,7 +26,7 @@ typedef enum rrdr_time_grouping {
RRDR_GROUPING_TRIMMED_MEDIAN1,
RRDR_GROUPING_TRIMMED_MEDIAN2,
RRDR_GROUPING_TRIMMED_MEDIAN3,
- RRDR_GROUPING_TRIMMED_MEDIAN5,
+ RRDR_GROUPING_TRIMMED_MEDIAN,
RRDR_GROUPING_TRIMMED_MEDIAN10,
RRDR_GROUPING_TRIMMED_MEDIAN15,
RRDR_GROUPING_TRIMMED_MEDIAN20,
diff --git a/src/web/api/queries/rrdr.h b/src/web/api/queries/rrdr.h
index a86b15e3af..d36d3f5b3b 100644
--- a/src/web/api/queries/rrdr.h
+++ b/src/web/api/queries/rrdr.h
@@ -21,30 +21,33 @@ typedef enum rrdr_options {
RRDR_OPTION_NONZERO = (1 << 0), // don't output dimensions with just zero values
RRDR_OPTION_REVERSED = (1 << 1), // output the rows in reverse order (oldest to newest)
RRDR_OPTION_ABSOLUTE = (1 << 2), // values positive, for DATASOURCE_SSV before summing
- RRDR_OPTION_MIN2MAX = (1 << 3), // when adding dimensions, use max - min, instead of sum
- RRDR_OPTION_SECONDS = (1 << 4), // output seconds, instead of dates
- RRDR_OPTION_MILLISECONDS = (1 << 5), // output milliseconds, instead of dates
- RRDR_OPTION_NULL2ZERO = (1 << 6), // do not show nulls, convert them to zeros
- RRDR_OPTION_OBJECTSROWS = (1 << 7), // each row of values should be an object, not an array
- RRDR_OPTION_GOOGLE_JSON = (1 << 8), // comply with google JSON/JSONP specs
- RRDR_OPTION_JSON_WRAP = (1 << 9), // wrap the response in a JSON header with info about the result
- RRDR_OPTION_LABEL_QUOTES = (1 << 10), // in CSV output, wrap header labels in double quotes
- RRDR_OPTION_PERCENTAGE = (1 << 11), // give values as percentage of total
- RRDR_OPTION_NOT_ALIGNED = (1 << 12), // do not align charts for persistent timeframes
- RRDR_OPTION_DISPLAY_ABS = (1 << 13), // for badges, display the absolute value, but calculate colors with sign
- RRDR_OPTION_MATCH_IDS = (1 << 14), // when filtering dimensions, match only IDs
- RRDR_OPTION_MATCH_NAMES = (1 << 15), // when filtering dimensions, match only names
- RRDR_OPTION_NATURAL_POINTS = (1 << 16), // return the natural points of the database
- RRDR_OPTION_VIRTUAL_POINTS = (1 << 17), // return virtual points
- RRDR_OPTION_ANOMALY_BIT = (1 << 18), // Return the anomaly bit stored in each collected_number
- RRDR_OPTION_RETURN_RAW = (1 << 19), // Return raw data for aggregating across multiple nodes
- RRDR_OPTION_RETURN_JWAR = (1 << 20), // Return anomaly rates in jsonwrap
- RRDR_OPTION_SELECTED_TIER = (1 << 21), // Use the selected tier for the query
- RRDR_OPTION_ALL_DIMENSIONS = (1 << 22), // Return the full dimensions list
- RRDR_OPTION_SHOW_DETAILS = (1 << 23), // v2 returns detailed object tree
- RRDR_OPTION_DEBUG = (1 << 24), // v2 returns request description
- RRDR_OPTION_MINIFY = (1 << 25), // remove JSON spaces and newlines from JSON output
- RRDR_OPTION_GROUP_BY_LABELS = (1 << 26), // v2 returns flattened labels per dimension of the chart
+ RRDR_OPTION_DIMS_MIN2MAX = (1 << 3), // when adding dimensions, use max - min, instead of sum
+ RRDR_OPTION_DIMS_AVERAGE = (1 << 4), // when adding dimensions, use average, instead of sum
+ RRDR_OPTION_DIMS_MIN = (1 << 5), // when adding dimensions, use minimum, instead of sum
+ RRDR_OPTION_DIMS_MAX = (1 << 6), // when adding dimensions, use maximum, instead of sum
+ RRDR_OPTION_SECONDS = (1 << 7), // output seconds, instead of dates
+ RRDR_OPTION_MILLISECONDS = (1 << 8), // output milliseconds, instead of dates
+ RRDR_OPTION_NULL2ZERO = (1 << 9), // do not show nulls, convert them to zeros
+ RRDR_OPTION_OBJECTSROWS = (1 << 10), // each row of values should be an object, not an array
+ RRDR_OPTION_GOOGLE_JSON = (1 << 11), // comply with google JSON/JSONP specs
+ RRDR_OPTION_JSON_WRAP = (1 << 12), // wrap the response in a JSON header with info about the result
+ RRDR_OPTION_LABEL_QUOTES = (1 << 13), // in CSV output, wrap header labels in double quotes
+ RRDR_OPTION_PERCENTAGE = (1 << 14), // give values as percentage of total
+ RRDR_OPTION_NOT_ALIGNED = (1 << 15), // do not align charts for persistent timeframes
+ RRDR_OPTION_DISPLAY_ABS = (1 << 16), // for badges, display the absolute value, but calculate colors with sign
+ RRDR_OPTION_MATCH_IDS = (1 << 17), // when filtering dimensions, match only IDs
+ RRDR_OPTION_MATCH_NAMES = (1 << 18), // when filtering dimensions, match only names
+ RRDR_OPTION_NATURAL_POINTS = (1 << 19), // return the natural points of the database
+ RRDR_OPTION_VIRTUAL_POINTS = (1 << 20), // return virtual points
+ RRDR_OPTION_ANOMALY_BIT = (1 << 21), // Return the anomaly bit stored in each collected_number
+ RRDR_OPTION_RETURN_RAW = (1 << 22), // Return raw data for aggregating across multiple nodes
+ RRDR_OPTION_RETURN_JWAR = (1 << 23), // Return anomaly rates in jsonwrap
+ RRDR_OPTION_SELECTED_TIER = (1 << 24), // Use the selected tier for the query
+ RRDR_OPTION_ALL_DIMENSIONS = (1 << 25), // Return the full dimensions list
+ RRDR_OPTION_SHOW_DETAILS = (1 << 26), // v2 returns detailed object tree
+ RRDR_OPTION_DEBUG = (1 << 27), // v2 returns request description
+ RRDR_OPTION_MINIFY = (1 << 28), // remove JSON spaces and newlines from JSON output
+ RRDR_OPTION_GROUP_BY_LABELS = (1 << 29), // v2 returns flattened labels per dimension of the chart
// internal ones - not to be exposed to the API
RRDR_OPTION_INTERNAL_AR = (1 << 31), // internal use only, to let the formatters know we want to render the anomaly rate
diff --git a/src/web/api/web_api_v1.c b/src/web/api/web_api_v1.c
index 0dd913492f..386221d619 100644
--- a/src/web/api/web_api_v1.c
+++ b/src/web/api/web_api_v1.c
@@ -14,11 +14,14 @@ static struct {
, {"reversed" , 0 , RRDR_OPTION_REVERSED}
, {"reverse" , 0 , RRDR_OPTION_REVERSED}
, {"jsonwrap" , 0 , RRDR_OPTION_JSON_WRAP}
- , {"min2max" , 0 , RRDR_OPTION_MIN2MAX}
+ , {"min2max" , 0 , RRDR_OPTION_DIMS_MIN2MAX} // rrdr2value() only
+ , {"average" , 0 , RRDR_OPTION_DIMS_AVERAGE} // rrdr2value() only
+ , {"min" , 0 , RRDR_OPTION_DIMS_MIN} // rrdr2value() only
+ , {"max" , 0 , RRDR_OPTION_DIMS_MAX} // rrdr2value() only
, {"ms" , 0 , RRDR_OPTION_MILLISECONDS}
, {"milliseconds" , 0 , RRDR_OPTION_MILLISECONDS}
- , {"abs" , 0 , RRDR_OPTION_ABSOLUTE}
, {"absolute" , 0 , RRDR_OPTION_ABSOLUTE}
+ , {"abs" , 0 , RRDR_OPTION_ABSOLUTE}
, {"absolute_sum" , 0 , RRDR_OPTION_ABSOLUTE}
, {"absolute-sum" , 0 , RRDR_OPTION_ABSOLUTE}
, {"display_absolute" , 0 , RRDR_OPTION_DISPLAY_ABS}
@@ -328,6 +331,20 @@ void rrdr_options_to_buffer_json_array(BUFFER *wb, const char *key, RRDR_OPTIONS
buffer_json_array_close(wb);
}
+void rrdr_options_to_buffer(BUFFER *wb, RRDR_OPTIONS options) {
+ RRDR_OPTIONS used = 0; // to prevent adding duplicates
+ size_t added = 0;
+ for(int i = 0; rrdr_options[i].name ; i++) {
+ if (unlikely((rrdr_options[i].value & options) && !(rrdr_options[i].value & used))) {
+ const char *name = rrdr_options[i].name;
+ used |= rrdr_options[i].value;
+
+ if(added++) buffer_strcat(wb, " ");
+ buffer_strcat(wb, name);
+ }
+ }
+}
+
void web_client_api_request_v1_data_options_to_string(char *buf, size_t size, RRDR_OPTIONS options) {
char *write = buf;
char *end = &buf[size - 1];
diff --git a/src/web/api/web_api_v1.h b/src/web/api/web_api_v1.h
index bf67ef752f..cf0efbd13c 100644
--- a/src/web/api/web_api_v1.h
+++ b/src/web/api/web_api_v1.h
@@ -15,6 +15,7 @@ void web_client_api_request_v2_contexts_alerts_status_to_buffer_json_array(BUFFE
RRDR_OPTIONS rrdr_options_parse(char *o);
RRDR_OPTIONS rrdr_options_parse_one(const char *o);
+void rrdr_options_to_buffer(BUFFER *wb, RRDR_OPTIONS options);
void rrdr_options_to_buffer_json_array(BUFFER *wb, const char *key, RRDR_OPTIONS options);
void web_client_api_request_v1_data_options_to_string(char *buf, size_t size, RRDR_OPTIONS options);