From 7877a98bd9c00db5e81dd2f8c734cba2bab20be7 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 12 Aug 2022 09:26:17 +0200 Subject: Merging upstream version 1.36.0. Signed-off-by: Daniel Baumann --- web/api/queries/countif/Makefile.am | 8 +++ web/api/queries/countif/README.md | 36 ++++++++++ web/api/queries/countif/countif.c | 136 ++++++++++++++++++++++++++++++++++++ web/api/queries/countif/countif.h | 15 ++++ 4 files changed, 195 insertions(+) create mode 100644 web/api/queries/countif/Makefile.am create mode 100644 web/api/queries/countif/README.md create mode 100644 web/api/queries/countif/countif.c create mode 100644 web/api/queries/countif/countif.h (limited to 'web/api/queries/countif') diff --git a/web/api/queries/countif/Makefile.am b/web/api/queries/countif/Makefile.am new file mode 100644 index 000000000..161784b8f --- /dev/null +++ b/web/api/queries/countif/Makefile.am @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-3.0-or-later + +AUTOMAKE_OPTIONS = subdir-objects +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +dist_noinst_DATA = \ + README.md \ + $(NULL) diff --git a/web/api/queries/countif/README.md b/web/api/queries/countif/README.md new file mode 100644 index 000000000..200a4c9ed --- /dev/null +++ b/web/api/queries/countif/README.md @@ -0,0 +1,36 @@ + + +# CountIf + +> This query is available as `countif`. + +CountIf returns the percentage of points in the database that satisfy the condition supplied. + +The following conditions are available: + +- `!` or `!=` or `<>`, different than +- `=` or `:`, equal to +- `>`, greater than +- `<`, less than +- `>=`, greater or equal to +- `<=`, less or equal to + +The target number and the desired condition can be set using the `group_options` query parameter, as a string, like in these examples: + +- `!0`, to match any number except zero. +- `>=-3` to match any number bigger or equal to -3. + +. When an invalid condition is given, the web server can deliver a not accurate response. + +## how to use + +This query cannot be used in alarms. + +`countif` changes the units of charts. The result of the calculation is always from zero to 1, expressing the percentage of database points that matched the condition. + +In APIs and badges can be used like this: `&group=countif&group_options=>10` in the URL. + + diff --git a/web/api/queries/countif/countif.c b/web/api/queries/countif/countif.c new file mode 100644 index 000000000..369b20be9 --- /dev/null +++ b/web/api/queries/countif/countif.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "countif.h" + +// ---------------------------------------------------------------------------- +// countif + +struct grouping_countif { + size_t (*comparison)(NETDATA_DOUBLE, NETDATA_DOUBLE); + NETDATA_DOUBLE target; + size_t count; + size_t matched; +}; + +static size_t countif_equal(NETDATA_DOUBLE v, NETDATA_DOUBLE target) { + return (v == target); +} + +static size_t countif_notequal(NETDATA_DOUBLE v, NETDATA_DOUBLE target) { + return (v != target); +} + +static size_t countif_less(NETDATA_DOUBLE v, NETDATA_DOUBLE target) { + return (v < target); +} + +static size_t countif_lessequal(NETDATA_DOUBLE v, NETDATA_DOUBLE target) { + return (v <= target); +} + +static size_t countif_greater(NETDATA_DOUBLE v, NETDATA_DOUBLE target) { + return (v > target); +} + +static size_t countif_greaterequal(NETDATA_DOUBLE v, NETDATA_DOUBLE target) { + return (v >= target); +} + +void grouping_create_countif(RRDR *r, const char *options __maybe_unused) { + struct grouping_countif *g = onewayalloc_callocz(r->internal.owa, 1, sizeof(struct grouping_countif)); + r->internal.grouping_data = g; + + if(options && *options) { + // skip any leading spaces + while(isspace(*options)) options++; + + // find the comparison function + switch(*options) { + case '!': + options++; + if(*options != '=' && *options != ':') + options--; + g->comparison = countif_notequal; + break; + + case '>': + options++; + if(*options == '=' || *options == ':') { + g->comparison = countif_greaterequal; + } + else { + options--; + g->comparison = countif_greater; + } + break; + + case '<': + options++; + if(*options == '>') { + g->comparison = countif_notequal; + } + else if(*options == '=' || *options == ':') { + g->comparison = countif_lessequal; + } + else { + options--; + g->comparison = countif_less; + } + break; + + default: + case '=': + case ':': + g->comparison = countif_equal; + break; + } + if(*options) options++; + + // skip everything up to the first digit + while(isspace(*options)) options++; + + g->target = str2ndd(options, NULL); + } + else { + g->target = 0.0; + g->comparison = countif_equal; + } +} + +// resets when switches dimensions +// so, clear everything to restart +void grouping_reset_countif(RRDR *r) { + struct grouping_countif *g = (struct grouping_countif *)r->internal.grouping_data; + g->matched = 0; + g->count = 0; +} + +void grouping_free_countif(RRDR *r) { + onewayalloc_freez(r->internal.owa, r->internal.grouping_data); + r->internal.grouping_data = NULL; +} + +void grouping_add_countif(RRDR *r, NETDATA_DOUBLE value) { + struct grouping_countif *g = (struct grouping_countif *)r->internal.grouping_data; + g->matched += g->comparison(value, g->target); + g->count++; +} + +NETDATA_DOUBLE grouping_flush_countif(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr) { + struct grouping_countif *g = (struct grouping_countif *)r->internal.grouping_data; + + NETDATA_DOUBLE value; + + if(unlikely(!g->count)) { + value = 0.0; + *rrdr_value_options_ptr |= RRDR_VALUE_EMPTY; + } + else { + value = (NETDATA_DOUBLE)g->matched * 100 / (NETDATA_DOUBLE)g->count; + } + + g->matched = 0; + g->count = 0; + + return value; +} diff --git a/web/api/queries/countif/countif.h b/web/api/queries/countif/countif.h new file mode 100644 index 000000000..0c7d2d7d1 --- /dev/null +++ b/web/api/queries/countif/countif.h @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef NETDATA_API_QUERY_COUNTIF_H +#define NETDATA_API_QUERY_COUNTIF_H + +#include "../query.h" +#include "../rrdr.h" + +extern void grouping_create_countif(RRDR *r, const char *options __maybe_unused); +extern void grouping_reset_countif(RRDR *r); +extern void grouping_free_countif(RRDR *r); +extern void grouping_add_countif(RRDR *r, NETDATA_DOUBLE value); +extern NETDATA_DOUBLE grouping_flush_countif(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr); + +#endif //NETDATA_API_QUERY_COUNTIF_H -- cgit v1.2.3