summaryrefslogtreecommitdiffstats
path: root/web/api
diff options
context:
space:
mode:
authorCosta Tsaousis <costa@tsaousis.gr>2018-10-24 23:06:46 +0300
committerGitHub <noreply@github.com>2018-10-24 23:06:46 +0300
commitc9234ccc8cea6023c190370ea7e7e95fb5433dab (patch)
tree955e51a3c95b461490623d30ccc0750a6357f084 /web/api
parent67f46998a42f0c534bd9860dece9547bb0ed8895 (diff)
query code cleanup (#4480)
* queries code cleanup; renaming of variables; user configurable; tuning for defaults * reformatted main queries array * added documentation about all queries * empty doc * changed resampling variable names * added documentation to query module functions * fixed typos * renames * identation * more renames * fixed a faulty function definition at backends
Diffstat (limited to 'web/api')
-rw-r--r--web/api/queries/README.md4
-rw-r--r--web/api/queries/average/README.md39
-rw-r--r--web/api/queries/average/average.c15
-rw-r--r--web/api/queries/average/average.h2
-rw-r--r--web/api/queries/des/README.md65
-rw-r--r--web/api/queries/des/des.c49
-rw-r--r--web/api/queries/des/des.h4
-rw-r--r--web/api/queries/incremental_sum/README.md34
-rw-r--r--web/api/queries/incremental_sum/incremental_sum.c11
-rw-r--r--web/api/queries/incremental_sum/incremental_sum.h2
-rw-r--r--web/api/queries/max/README.md31
-rw-r--r--web/api/queries/max/max.c11
-rw-r--r--web/api/queries/max/max.h2
-rw-r--r--web/api/queries/median/README.md37
-rw-r--r--web/api/queries/median/median.c15
-rw-r--r--web/api/queries/median/median.h2
-rw-r--r--web/api/queries/min/README.md31
-rw-r--r--web/api/queries/min/min.c11
-rw-r--r--web/api/queries/min/min.h2
-rw-r--r--web/api/queries/query.c336
-rw-r--r--web/api/queries/rrdr.h31
-rw-r--r--web/api/queries/ses/README.md21
-rw-r--r--web/api/queries/ses/ses.c44
-rw-r--r--web/api/queries/ses/ses.h4
-rw-r--r--web/api/queries/stddev/stddev.c49
-rw-r--r--web/api/queries/stddev/stddev.h2
-rw-r--r--web/api/queries/sum/README.md34
-rw-r--r--web/api/queries/sum/sum.c11
-rw-r--r--web/api/queries/sum/sum.h2
29 files changed, 725 insertions, 176 deletions
diff --git a/web/api/queries/README.md b/web/api/queries/README.md
index e69de29bb2..e0a5707581 100644
--- a/web/api/queries/README.md
+++ b/web/api/queries/README.md
@@ -0,0 +1,4 @@
+# Database Queries
+
+TBD
+
diff --git a/web/api/queries/average/README.md b/web/api/queries/average/README.md
index e69de29bb2..3be434f688 100644
--- a/web/api/queries/average/README.md
+++ b/web/api/queries/average/README.md
@@ -0,0 +1,39 @@
+# Average or Mean
+
+> This query is available as `average` and `mean`.
+
+An average is a single number taken as representative of a list of numbers.
+
+It is calculated as:
+
+```
+average = sum(numbers) / count(numbers)
+```
+
+## how to use
+
+Use it in alarms like this:
+
+```
+ alarm: my_alarm
+ on: my_chart
+lookup: average -1m unaligned of my_dimension
+ warn: $this > 1000
+```
+
+`average` does not change the units. For example, if the chart units is `requests/sec`, the result
+will be again expressed in the same units.
+
+It can also be used in APIs and badges as `&group=average` in the URL.
+
+## Examples
+
+Examining last 1 minute `successful` web server responses:
+
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=min&after=-60&label=min)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=average&after=-60&label=average&value_color=orange)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=max&after=-60&label=max)
+
+## References
+
+- [https://en.wikipedia.org/wiki/Average](https://en.wikipedia.org/wiki/Average).
diff --git a/web/api/queries/average/average.c b/web/api/queries/average/average.c
index 3f4d7fb369..c871b87788 100644
--- a/web/api/queries/average/average.c
+++ b/web/api/queries/average/average.c
@@ -10,7 +10,7 @@ struct grouping_average {
size_t count;
};
-void *grouping_init_average(RRDR *r) {
+void *grouping_create_average(RRDR *r) {
(void)r;
return callocz(1, sizeof(struct grouping_average));
}
@@ -18,25 +18,26 @@ void *grouping_init_average(RRDR *r) {
// resets when switches dimensions
// so, clear everything to restart
void grouping_reset_average(RRDR *r) {
- struct grouping_average *g = (struct grouping_average *)r->grouping_data;
+ struct grouping_average *g = (struct grouping_average *)r->internal.grouping_data;
g->sum = 0;
g->count = 0;
}
void grouping_free_average(RRDR *r) {
- freez(r->grouping_data);
+ freez(r->internal.grouping_data);
+ r->internal.grouping_data = NULL;
}
void grouping_add_average(RRDR *r, calculated_number value) {
if(!isnan(value)) {
- struct grouping_average *g = (struct grouping_average *)r->grouping_data;
+ struct grouping_average *g = (struct grouping_average *)r->internal.grouping_data;
g->sum += value;
g->count++;
}
}
calculated_number grouping_flush_average(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr) {
- struct grouping_average *g = (struct grouping_average *)r->grouping_data;
+ struct grouping_average *g = (struct grouping_average *)r->internal.grouping_data;
calculated_number value;
@@ -45,8 +46,8 @@ calculated_number grouping_flush_average(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_
*rrdr_value_options_ptr |= RRDR_VALUE_EMPTY;
}
else {
- if(unlikely(r->group_points != 1))
- value = g->sum / r->group_sum_divisor;
+ if(unlikely(r->internal.resampling_group != 1))
+ value = g->sum / r->internal.resampling_divisor;
else
value = g->sum / g->count;
}
diff --git a/web/api/queries/average/average.h b/web/api/queries/average/average.h
index 940c907d2e..9fb7de21ac 100644
--- a/web/api/queries/average/average.h
+++ b/web/api/queries/average/average.h
@@ -6,7 +6,7 @@
#include "../query.h"
#include "../rrdr.h"
-extern void *grouping_init_average(RRDR *r);
+extern void *grouping_create_average(RRDR *r);
extern void grouping_reset_average(RRDR *r);
extern void grouping_free_average(RRDR *r);
extern void grouping_add_average(RRDR *r, calculated_number value);
diff --git a/web/api/queries/des/README.md b/web/api/queries/des/README.md
index d2765ecc03..fa546a3389 100644
--- a/web/api/queries/des/README.md
+++ b/web/api/queries/des/README.md
@@ -1 +1,66 @@
# double exponential smoothing
+
+Exponential smoothing is one of many window functions commonly applied to smooth data in signal
+processing, acting as low-pass filters to remove high frequency noise.
+
+Simple exponential smoothing does not do well when there is a trend in the data.
+In such situations, several methods were devised under the name "double exponential smoothing"
+or "second-order exponential smoothing.", which is the recursive application of an exponential
+filter twice, thus being termed "double exponential smoothing".
+
+In simple terms, this is like an average value, but more recent values are given more weight
+and the trend of the values influences significantly the result.
+
+> **IMPORTANT**
+>
+> It is common for `des` to provide "average" values that far beyond the minimum or the maximum
+> values found in the time-series.
+> `des` estimates these values because of it takes into account the trend.
+
+This module implements the "Holt-Winters double exponential smoothing".
+
+Netdata automatically adjusts the weight (`alpha`) and the trend (`beta`) based on the number
+of values processed, using the formula:
+
+```
+window = max(number of values, 15)
+alpha = 2 / (window + 1)
+beta = 2 / (window + 1)
+```
+
+You can change the fixed value `15` by setting in `netdata.conf`:
+
+```
+[web]
+ des max window = 15
+```
+
+## how to use
+
+Use it in alarms like this:
+
+```
+ alarm: my_alarm
+ on: my_chart
+lookup: des -1m unaligned of my_dimension
+ warn: $this > 1000
+```
+
+`des` does not change the units. For example, if the chart units is `requests/sec`, the result
+will be again expressed in the same units.
+
+It can also be used in APIs and badges as `&group=des` in the URL.
+
+## Examples
+
+Examining last 1 minute `successful` web server responses:
+
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=min&after=-60&label=min)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=average&after=-60&label=average&value_color=yellow)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=ses&after=-60&label=single+exponential+smoothing&value_color=yellow)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=des&after=-60&label=double+exponential+smoothing&value_color=orange)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=max&after=-60&label=max)
+
+## References
+
+- [https://en.wikipedia.org/wiki/Exponential_smoothing](https://en.wikipedia.org/wiki/Exponential_smoothing).
diff --git a/web/api/queries/des/des.c b/web/api/queries/des/des.c
index bc9f6d81bb..93d7247235 100644
--- a/web/api/queries/des/des.c
+++ b/web/api/queries/des/des.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
+#include <web/api/queries/rrdr.h>
#include "des.h"
@@ -18,14 +19,41 @@ struct grouping_des {
size_t count;
};
-#define MAX_WINDOW_SIZE 10
+static size_t max_window_size = 15;
+
+void grouping_init_des(void) {
+ long long ret = config_get_number(CONFIG_SECTION_WEB, "des max window", (long long)max_window_size);
+ if(ret <= 1) {
+ config_set_number(CONFIG_SECTION_WEB, "des max window", (long long)max_window_size);
+ }
+ else {
+ max_window_size = (size_t) ret;
+ }
+}
+
+static inline calculated_number window(RRDR *r, struct grouping_des *g) {
+ (void)g;
+
+ calculated_number points;
+ if(r->group == 1) {
+ // provide a running DES
+ points = r->internal.points_wanted;
+ }
+ else {
+ // provide a SES with flush points
+ points = r->group;
+ }
+
+ // https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
+ // A commonly used value for alpha is 2 / (N + 1)
+ return (points > max_window_size) ? max_window_size : points;
+}
static inline void set_alpha(RRDR *r, struct grouping_des *g) {
// https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
// A commonly used value for alpha is 2 / (N + 1)
- calculated_number window = (r->group > MAX_WINDOW_SIZE) ? MAX_WINDOW_SIZE : r->group;
- g->alpha = 2.0 / ((calculated_number)window + 1.0);
+ g->alpha = 2.0 / (window(r, g) + 1.0);
g->alpha_other = 1.0 - g->alpha;
//info("alpha for chart '%s' is " CALCULATED_NUMBER_FORMAT, r->st->name, g->alpha);
@@ -34,15 +62,14 @@ static inline void set_alpha(RRDR *r, struct grouping_des *g) {
static inline void set_beta(RRDR *r, struct grouping_des *g) {
// https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
// A commonly used value for alpha is 2 / (N + 1)
- calculated_number window = (r->group > MAX_WINDOW_SIZE) ? MAX_WINDOW_SIZE : r->group;
- g->beta = 2.0 / ((calculated_number)window + 1.0);
+ g->beta = 2.0 / (window(r, g) + 1.0);
g->beta_other = 1.0 - g->beta;
//info("beta for chart '%s' is " CALCULATED_NUMBER_FORMAT, r->st->name, g->beta);
}
-void *grouping_init_des(RRDR *r) {
+void *grouping_create_des(RRDR *r) {
struct grouping_des *g = (struct grouping_des *)malloc(sizeof(struct grouping_des));
set_alpha(r, g);
set_beta(r, g);
@@ -55,7 +82,7 @@ void *grouping_init_des(RRDR *r) {
// resets when switches dimensions
// so, clear everything to restart
void grouping_reset_des(RRDR *r) {
- struct grouping_des *g = (struct grouping_des *)r->grouping_data;
+ struct grouping_des *g = (struct grouping_des *)r->internal.grouping_data;
g->level = 0.0;
g->trend = 0.0;
g->count = 0;
@@ -65,12 +92,12 @@ void grouping_reset_des(RRDR *r) {
}
void grouping_free_des(RRDR *r) {
- freez(r->grouping_data);
- r->grouping_data = NULL;
+ freez(r->internal.grouping_data);
+ r->internal.grouping_data = NULL;
}
void grouping_add_des(RRDR *r, calculated_number value) {
- struct grouping_des *g = (struct grouping_des *)r->grouping_data;
+ struct grouping_des *g = (struct grouping_des *)r->internal.grouping_data;
if(isnormal(value)) {
if(likely(g->count > 0)) {
@@ -99,7 +126,7 @@ void grouping_add_des(RRDR *r, calculated_number value) {
}
calculated_number grouping_flush_des(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr) {
- struct grouping_des *g = (struct grouping_des *)r->grouping_data;
+ struct grouping_des *g = (struct grouping_des *)r->internal.grouping_data;
if(unlikely(!g->count || !isnormal(g->level))) {
*rrdr_value_options_ptr |= RRDR_VALUE_EMPTY;
diff --git a/web/api/queries/des/des.h b/web/api/queries/des/des.h
index 83edd7ef63..360513e9c4 100644
--- a/web/api/queries/des/des.h
+++ b/web/api/queries/des/des.h
@@ -6,7 +6,9 @@
#include "../query.h"
#include "../rrdr.h"
-extern void *grouping_init_des(RRDR *r);
+extern void grouping_init_des(void);
+
+extern void *grouping_create_des(RRDR *r);
extern void grouping_reset_des(RRDR *r);
extern void grouping_free_des(RRDR *r);
extern void grouping_add_des(RRDR *r, calculated_number value);
diff --git a/web/api/queries/incremental_sum/README.md b/web/api/queries/incremental_sum/README.md
index e69de29bb2..ef86d4d411 100644
--- a/web/api/queries/incremental_sum/README.md
+++ b/web/api/queries/incremental_sum/README.md
@@ -0,0 +1,34 @@
+# Incremental Sum (`incremental_sum`)
+
+This modules finds the incremental sum of a period, which `last value - first value`.
+
+The result may be positive (rising) or negative (falling) depending on the first and last values.
+
+## how to use
+
+Use it in alarms like this:
+
+```
+ alarm: my_alarm
+ on: my_chart
+lookup: incremental_sum -1m unaligned of my_dimension
+ warn: $this > 1000
+```
+
+`incremental_sum` does not change the units. For example, if the chart units is `requests/sec`, the result
+will be again expressed in the same units.
+
+It can also be used in APIs and badges as `&group=incremental_sum` in the URL.
+
+## Examples
+
+Examining last 1 minute `successful` web server responses:
+
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=min&after=-60&label=min)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=average&after=-60&label=average)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=max&after=-60&label=max)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=incremental_sum&after=-60&label=incremental+sum&value_color=orange)
+
+## References
+
+- none
diff --git a/web/api/queries/incremental_sum/incremental_sum.c b/web/api/queries/incremental_sum/incremental_sum.c
index 3fce4fe777..131d85d789 100644
--- a/web/api/queries/incremental_sum/incremental_sum.c
+++ b/web/api/queries/incremental_sum/incremental_sum.c
@@ -11,7 +11,7 @@ struct grouping_incremental_sum {
size_t count;
};
-void *grouping_init_incremental_sum(RRDR *r) {
+void *grouping_create_incremental_sum(RRDR *r) {
(void)r;
return callocz(1, sizeof(struct grouping_incremental_sum));
}
@@ -19,19 +19,20 @@ void *grouping_init_incremental_sum(RRDR *r) {
// resets when switches dimensions
// so, clear everything to restart
void grouping_reset_incremental_sum(RRDR *r) {
- struct grouping_incremental_sum *g = (struct grouping_incremental_sum *)r->grouping_data;
+ struct grouping_incremental_sum *g = (struct grouping_incremental_sum *)r->internal.grouping_data;
g->first = 0;
g->last = 0;
g->count = 0;
}
void grouping_free_incremental_sum(RRDR *r) {
- freez(r->grouping_data);
+ freez(r->internal.grouping_data);
+ r->internal.grouping_data = NULL;
}
void grouping_add_incremental_sum(RRDR *r, calculated_number value) {
if(!isnan(value)) {
- struct grouping_incremental_sum *g = (struct grouping_incremental_sum *)r->grouping_data;
+ struct grouping_incremental_sum *g = (struct grouping_incremental_sum *)r->internal.grouping_data;
if(unlikely(!g->count)) {
g->first = value;
@@ -45,7 +46,7 @@ void grouping_add_incremental_sum(RRDR *r, calculated_number value) {
}
calculated_number grouping_flush_incremental_sum(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr) {
- struct grouping_incremental_sum *g = (struct grouping_incremental_sum *)r->grouping_data;
+ struct grouping_incremental_sum *g = (struct grouping_incremental_sum *)r->internal.grouping_data;
calculated_number value;
diff --git a/web/api/queries/incremental_sum/incremental_sum.h b/web/api/queries/incremental_sum/incremental_sum.h
index 5bf9d961a3..990a2ac4a5 100644
--- a/web/api/queries/incremental_sum/incremental_sum.h
+++ b/web/api/queries/incremental_sum/incremental_sum.h
@@ -6,7 +6,7 @@
#include "../query.h"
#include "../rrdr.h"
-extern void *grouping_init_incremental_sum(RRDR *r);
+extern void *grouping_create_incremental_sum(RRDR *r);
extern void grouping_reset_incremental_sum(RRDR *r);
extern void grouping_free_incremental_sum(RRDR *r);
extern void grouping_add_incremental_sum(RRDR *r, calculated_number value);
diff --git a/web/api/queries/max/README.md b/web/api/queries/max/README.md
index e69de29bb2..2ea14bf0b9 100644
--- a/web/api/queries/max/README.md
+++ b/web/api/queries/max/README.md
@@ -0,0 +1,31 @@
+# Max
+
+This module finds the max value in the time-frame given.
+
+## how to use
+
+Use it in alarms like this:
+
+```
+ alarm: my_alarm
+ on: my_chart
+lookup: max -1m unaligned of my_dimension
+ warn: $this > 1000
+```
+
+`max` does not change the units. For example, if the chart units is `requests/sec`, the result
+will be again expressed in the same units.
+
+It can also be used in APIs and badges as `&group=max` in the URL.
+
+## Examples
+
+Examining last 1 minute `successful` web server responses:
+
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=min&after=-60&label=min)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=average&after=-60&label=average)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=max&after=-60&label=max&value_color=orange)
+
+## References
+
+- [https://en.wikipedia.org/wiki/Sample_maximum_and_minimum](https://en.wikipedia.org/wiki/Sample_maximum_and_minimum).
diff --git a/web/api/queries/max/max.c b/web/api/queries/max/max.c
index b6e4866a61..a4be36add1 100644
--- a/web/api/queries/max/max.c
+++ b/web/api/queries/max/max.c
@@ -10,7 +10,7 @@ struct grouping_max {
size_t count;
};
-void *grouping_init_max(RRDR *r) {
+void *grouping_create_max(RRDR *r) {
(void)r;
return callocz(1, sizeof(struct grouping_max));
}
@@ -18,18 +18,19 @@ void *grouping_init_max(RRDR *r) {
// resets when switches dimensions
// so, clear everything to restart
void grouping_reset_max(RRDR *r) {
- struct grouping_max *g = (struct grouping_max *)r->grouping_data;
+ struct grouping_max *g = (struct grouping_max *)r->internal.grouping_data;
g->max = 0;
g->count = 0;
}
void grouping_free_max(RRDR *r) {
- freez(r->grouping_data);
+ freez(r->internal.grouping_data);
+ r->internal.grouping_data = NULL;
}
void grouping_add_max(RRDR *r, calculated_number value) {
if(!isnan(value)) {
- struct grouping_max *g = (struct grouping_max *)r->grouping_data;
+ struct grouping_max *g = (struct grouping_max *)r->internal.grouping_data;
if(!g->count || calculated_number_fabs(value) > calculated_number_fabs(g->max)) {
g->max = value;
@@ -39,7 +40,7 @@ void grouping_add_max(RRDR *r, calculated_number value) {
}
calculated_number grouping_flush_max(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr) {
- struct grouping_max *g = (struct grouping_max *)r->grouping_data;
+ struct grouping_max *g = (struct grouping_max *)r->internal.grouping_data;
calculated_number value;
diff --git a/web/api/queries/max/max.h b/web/api/queries/max/max.h
index 5b7da52524..d839fe3f93 100644
--- a/web/api/queries/max/max.h
+++ b/web/api/queries/max/max.h
@@ -6,7 +6,7 @@
#include "../query.h"
#include "../rrdr.h"
-extern void *grouping_init_max(RRDR *r);
+extern void *grouping_create_max(RRDR *r);
extern void grouping_reset_max(RRDR *r);
extern void grouping_free_max(RRDR *r);
extern void grouping_add_max(RRDR *r, calculated_number value);
diff --git a/web/api/queries/median/README.md b/web/api/queries/median/README.md
index e69de29bb2..eb2dbaa963 100644
--- a/web/api/queries/median/README.md
+++ b/web/api/queries/median/README.md
@@ -0,0 +1,37 @@
+# Median
+
+The median is the value separating the higher half from the lower half of a data sample
+(a population or a probability distribution). For a data set, it may be thought of as the
+"middle" value.
+
+`median` is not an accurate average. However, it eliminates all spikes, by sorting
+all the values in a period, and selecting the value in the middle of the sorted array.
+
+## how to use
+
+Use it in alarms like this:
+
+```
+ alarm: my_alarm
+ on: my_chart
+lookup: median -1m unaligned of my_dimension
+ warn: $this > 1000
+```
+
+`median` does not change the units. For example, if the chart units is `requests/sec`, the result
+will be again expressed in the same units.
+
+It can also be used in APIs and badges as `&group=median` in the URL.
+
+## Examples
+
+Examining last 1 minute `successful` web server responses:
+
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=min&after=-60&label=min)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=average&after=-60&label=average)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=median&after=-60&label=median&value_color=orange)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=max&after=-60&label=max)
+
+## References
+
+- [https://en.wikipedia.org/wiki/Median](https://en.wikipedia.org/wiki/Median).
diff --git a/web/api/queries/median/median.c b/web/api/queries/median/median.c
index 06a60c6dda..5a13b2e4da 100644
--- a/web/api/queries/median/median.c
+++ b/web/api/queries/median/median.c
@@ -13,8 +13,8 @@ struct grouping_median {
LONG_DOUBLE series[];
};
-void *grouping_init_median(RRDR *r) {
- long entries = (r->group > r->group_points) ? r->group : r->group_points;
+void *grouping_create_median(RRDR *r) {
+ long entries = r->group;
if(entries < 0) entries = 0;
struct grouping_median *g = (struct grouping_median *)callocz(1, sizeof(struct grouping_median) + entries * sizeof(LONG_DOUBLE));
@@ -26,19 +26,20 @@ void *grouping_init_median(RRDR *r) {
// resets when switches dimensions
// so, clear everything to restart
void grouping_reset_median(RRDR *r) {
- struct grouping_median *g = (struct grouping_median *)r->grouping_data;
+ struct grouping_median *g = (struct grouping_median *)r->internal.grouping_data;
g->next_pos = 0;
}
void grouping_free_median(RRDR *r) {
- freez(r->grouping_data);
+ freez(r->internal.grouping_data);
+ r->internal.grouping_data = NULL;
}
void grouping_add_median(RRDR *r, calculated_number value) {
- struct grouping_median *g = (struct grouping_median *)r->grouping_data;
+ struct grouping_median *g = (struct grouping_median *)r->internal.grouping_data;
if(unlikely(g->next_pos >= g->series_size)) {
- error("INTERNAL ERROR: median buffer overflow on chart '%s' - next_pos = %zu, series_size = %zu, r->group = %ld, r->group_points = %ld.", r->st->name, g->next_pos, g->series_size, r->group, r->group_points);
+ error("INTERNAL ERROR: median buffer overflow on chart '%s' - next_pos = %zu, series_size = %zu, r->group = %ld.", r->st->name, g->next_pos, g->series_size, r->group);
}
else {
if(isnormal(value))
@@ -47,7 +48,7 @@ void grouping_add_median(RRDR *r, calculated_number value) {
}
calculated_number grouping_flush_median(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr) {
- struct grouping_median *g = (struct grouping_median *)r->grouping_data;
+ struct grouping_median *g = (struct grouping_median *)r->internal.grouping_data;
calculated_number value;
diff --git a/web/api/queries/median/median.h b/web/api/queries/median/median.h
index 18ec2c2b01..dd2c1ffc53 100644
--- a/web/api/queries/median/median.h
+++ b/web/api/queries/median/median.h
@@ -6,7 +6,7 @@
#include "../query.h"
#include "../rrdr.h"
-extern void *grouping_init_median(RRDR *r);
+extern void *grouping_create_median(RRDR *r);
extern void grouping_reset_median(RRDR *r);
extern void grouping_free_median(RRDR *r);
extern void grouping_add_median(RRDR *r, calculated_number value);
diff --git a/web/api/queries/min/README.md b/web/api/queries/min/README.md
index e69de29bb2..3fe13106a9 100644
--- a/web/api/queries/min/README.md
+++ b/web/api/queries/min/README.md
@@ -0,0 +1,31 @@
+# Min
+
+This module finds the min value in the time-frame given.
+
+## how to use
+
+Use it in alarms like this:
+
+```
+ alarm: my_alarm
+ on: my_chart
+lookup: min -1m unaligned of my_dimension
+ warn: $this > 1000
+```
+
+`min` does not change the units. For example, if the chart units is `requests/sec`, the result
+will be again expressed in the same units.
+
+It can also be used in APIs and badges as `&group=min` in the URL.
+
+## Examples
+
+Examining last 1 minute `successful` web server responses:
+
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=min&after=-60&label=min&value_color=orange)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=average&after=-60&label=average)
+- ![](https://registry.my-netdata.io/api/v1/badge.svg?chart=web_log_nginx.response_statuses&options=unaligned&dimensions=success&group=max&after=-60&label=max)
+
+## References
+
+- [https://en.wikipedia.org/wiki/Sample_maximum_and_minimum](https://en.wikipedia.org/wiki/Sample_maximum_and_minimum).
diff --git a/web/api/queries/min/min.c b/web/api/queries/min/min.c
index 4a488e9481..9bd7460e0b 100644
--- a/web/api/queries/min/min.c
+++ b/web/api/queries/min/min.c
@@ -10,7 +10,7 @@ struct grouping_min {
size_t count;
};
-void *grouping_init_min(RRDR *r) {
+void *grouping_create_min(RRDR *r) {
(void)r;
return callocz(1, sizeof(struct grouping_min));
}
@@ -18,18 +18,19 @@ void *grouping_init_min(RRDR *r)