summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCosta Tsaousis <costa@netdata.cloud>2022-11-18 14:24:35 +0200
committerGitHub <noreply@github.com>2022-11-18 14:24:35 +0200
commitd9eb78d7d894be2b01308dbdfa4105c82bca1b26 (patch)
treef7a7562086acd3ed3a6e58657dfa5c2bb838d63b
parentdadb1e8aad05a9252d4c1972d4f52ebb03164bfa (diff)
allow statsd tags to modify chart metadata on the fly (#14014)
-rw-r--r--collectors/statsd.plugin/statsd.c37
-rw-r--r--database/rrdset.c10
2 files changed, 38 insertions, 9 deletions
diff --git a/collectors/statsd.plugin/statsd.c b/collectors/statsd.plugin/statsd.c
index cb78341a0c..02ee4ef22c 100644
--- a/collectors/statsd.plugin/statsd.c
+++ b/collectors/statsd.plugin/statsd.c
@@ -96,6 +96,7 @@ typedef enum statsd_metric_options {
STATSD_METRIC_OPTION_CHECKED = 0x00000040, // set when the charting thread checks this metric for use in charts (its usefulness)
STATSD_METRIC_OPTION_USEFUL = 0x00000080, // set when the charting thread finds the metric useful (i.e. used in a chart)
STATSD_METRIC_OPTION_COLLECTION_FULL_LOGGED = 0x00000100, // set when the collection is full for this metric
+ STATSD_METRIC_OPTION_UPDATED_CHART_METADATA = 0x00000200, // set when the private chart metadata have been updated via tags
} STATS_METRIC_OPTIONS;
typedef enum statsd_metric_type {
@@ -769,14 +770,20 @@ static void statsd_process_metric(const char *name, const char *value, const cha
statsd_parse_field_trim(tagvalue, tagvalue_end);
if(tagkey && *tagkey && tagvalue && *tagvalue) {
- if (!m->units && strcmp(tagkey, "units") == 0)
+ if (strcmp(tagkey, "units") == 0 && (!m->units || strcmp(m->units, tagvalue) != 0)) {
m->units = strdupz(tagvalue);
+ m->options |= STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
+ }
- if (!m->dimname && strcmp(tagkey, "name") == 0)
+ if (strcmp(tagkey, "name") == 0 && (!m->dimname || strcmp(m->dimname, tagvalue) != 0)) {
m->dimname = strdupz(tagvalue);
+ m->options |= STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
+ }
- if (!m->family && strcmp(tagkey, "family") == 0)
+ if (strcmp(tagkey, "family") == 0 && (!m->family || strcmp(m->family, tagvalue) != 0)) {
m->family = strdupz(tagvalue);
+ m->options |= STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
+ }
}
}
}
@@ -1604,7 +1611,9 @@ static inline RRDSET *statsd_private_rrdset_create(
, int update_every
, RRDSET_TYPE chart_type
) {
- statsd.private_charts++;
+ if(!m->st)
+ statsd.private_charts++;
+
RRDSET *st = rrdset_create_custom(
localhost // host
, type // type
@@ -1634,7 +1643,9 @@ static inline RRDSET *statsd_private_rrdset_create(
static inline void statsd_private_chart_gauge(STATSD_METRIC *m) {
debug(D_STATSD, "updating private chart for gauge metric '%s'", m->name);
- if(unlikely(!m->st)) {
+ if(unlikely(!m->st || m->options & STATSD_METRIC_OPTION_UPDATED_CHART_METADATA)) {
+ m->options &= ~STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
+
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1], context[RRD_ID_LENGTH_MAX + 1];
statsd_get_metric_type_and_id(m, type, id, context, "gauge", RRD_ID_LENGTH_MAX);
@@ -1673,7 +1684,9 @@ static inline void statsd_private_chart_gauge(STATSD_METRIC *m) {
static inline void statsd_private_chart_counter_or_meter(STATSD_METRIC *m, const char *dim, const char *family) {
debug(D_STATSD, "updating private chart for %s metric '%s'", dim, m->name);
- if(unlikely(!m->st)) {
+ if(unlikely(!m->st || m->options & STATSD_METRIC_OPTION_UPDATED_CHART_METADATA)) {
+ m->options &= ~STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
+
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1], context[RRD_ID_LENGTH_MAX + 1];
statsd_get_metric_type_and_id(m, type, id, context, dim, RRD_ID_LENGTH_MAX);
@@ -1712,7 +1725,9 @@ static inline void statsd_private_chart_counter_or_meter(STATSD_METRIC *m, const
static inline void statsd_private_chart_set(STATSD_METRIC *m) {
debug(D_STATSD, "updating private chart for set metric '%s'", m->name);
- if(unlikely(!m->st)) {
+ if(unlikely(!m->st || m->options & STATSD_METRIC_OPTION_UPDATED_CHART_METADATA)) {
+ m->options &= ~STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
+
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1], context[RRD_ID_LENGTH_MAX + 1];
statsd_get_metric_type_and_id(m, type, id, context, "set", RRD_ID_LENGTH_MAX);
@@ -1751,7 +1766,9 @@ static inline void statsd_private_chart_set(STATSD_METRIC *m) {
static inline void statsd_private_chart_dictionary(STATSD_METRIC *m) {
debug(D_STATSD, "updating private chart for dictionary metric '%s'", m->name);
- if(unlikely(!m->st)) {
+ if(unlikely(!m->st || m->options & STATSD_METRIC_OPTION_UPDATED_CHART_METADATA)) {
+ m->options &= ~STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
+
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1], context[RRD_ID_LENGTH_MAX + 1];
statsd_get_metric_type_and_id(m, type, id, context, "dictionary", RRD_ID_LENGTH_MAX);
@@ -1793,7 +1810,9 @@ static inline void statsd_private_chart_dictionary(STATSD_METRIC *m) {
static inline void statsd_private_chart_timer_or_histogram(STATSD_METRIC *m, const char *dim, const char *family, const char *units) {
debug(D_STATSD, "updating private chart for %s metric '%s'", dim, m->name);
- if(unlikely(!m->st)) {
+ if(unlikely(!m->st || m->options & STATSD_METRIC_OPTION_UPDATED_CHART_METADATA)) {
+ m->options &= ~STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
+
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1], context[RRD_ID_LENGTH_MAX + 1];
statsd_get_metric_type_and_id(m, type, id, context, dim, RRD_ID_LENGTH_MAX);
diff --git a/database/rrdset.c b/database/rrdset.c
index 8ebd52ba0f..7898ce1bb6 100644
--- a/database/rrdset.c
+++ b/database/rrdset.c
@@ -317,6 +317,16 @@ static bool rrdset_conflict_callback(const DICTIONARY_ITEM *item __maybe_unused,
string_freez(old_units);
}
+ if(ctr->family && *ctr->family) {
+ STRING *old_family = st->family;
+ st->family = rrd_string_strdupz(ctr->family);
+ if(old_family != st->family)
+ ctr->react_action |= RRDSET_REACT_UPDATED;
+ string_freez(old_family);
+
+ // TODO - we should rename RRDFAMILY variables
+ }
+
if(ctr->context && *ctr->context) {
STRING *old_context = st->context;
st->context = rrd_string_strdupz(ctr->context);