allow statsd tags to modify chart metadata on the fly (#14014)
Costa Tsaousis committed
Nov 18, 2022 at 14:24 UTC
d9eb78d7d894be2b01308dbdfa4105c82bca1b26
2 files changed
+38
-9
collectors/statsd.plugin/statsd.c
+28
-9
@@ -96,6 +96,7 @@ typedef enum statsd_metric_options {
96
STATSD_METRIC_OPTION_CHECKED = 0x00000040, // set when the charting thread checks this metric for use in charts (its usefulness)
97
STATSD_METRIC_OPTION_USEFUL = 0x00000080, // set when the charting thread finds the metric useful (i.e. used in a chart)
98
STATSD_METRIC_OPTION_COLLECTION_FULL_LOGGED = 0x00000100, // set when the collection is full for this metric
99
+ STATSD_METRIC_OPTION_UPDATED_CHART_METADATA = 0x00000200, // set when the private chart metadata have been updated via tags
100
} STATS_METRIC_OPTIONS;
101
102
typedef enum statsd_metric_type {
@@ -769,14 +770,20 @@ static void statsd_process_metric(const char *name, const char *value, const cha
770
statsd_parse_field_trim(tagvalue, tagvalue_end);
771
772
if(tagkey && *tagkey && tagvalue && *tagvalue) {
772
- if (!m->units && strcmp(tagkey, "units") == 0)
773
+ if (strcmp(tagkey, "units") == 0 && (!m->units || strcmp(m->units, tagvalue) != 0)) {
774
m->units = strdupz(tagvalue);
775
+ m->options |= STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
776
+ }
777
775
- if (!m->dimname && strcmp(tagkey, "name") == 0)
778
+ if (strcmp(tagkey, "name") == 0 && (!m->dimname || strcmp(m->dimname, tagvalue) != 0)) {
779
m->dimname = strdupz(tagvalue);
780
+ m->options |= STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
781
+ }
782
778
- if (!m->family && strcmp(tagkey, "family") == 0)
783
+ if (strcmp(tagkey, "family") == 0 && (!m->family || strcmp(m->family, tagvalue) != 0)) {
784
m->family = strdupz(tagvalue);
785
+ m->options |= STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
786
+ }
787
}
788
}
789
}
@@ -1604,7 +1611,9 @@ static inline RRDSET *statsd_private_rrdset_create(
1611
, int update_every
1612
, RRDSET_TYPE chart_type
1613
) {
1607
- statsd.private_charts++;
1614
+ if(!m->st)
1615
+ statsd.private_charts++;
1616
+
1617
RRDSET *st = rrdset_create_custom(
1618
localhost // host
1619
, type // type
@@ -1634,7 +1643,9 @@ static inline RRDSET *statsd_private_rrdset_create(
1643
static inline void statsd_private_chart_gauge(STATSD_METRIC *m) {
1644
debug(D_STATSD, "updating private chart for gauge metric '%s'", m->name);
1645
1637
- if(unlikely(!m->st)) {
1646
+ if(unlikely(!m->st || m->options & STATSD_METRIC_OPTION_UPDATED_CHART_METADATA)) {
1647
+ m->options &= ~STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
1648
+
1649
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1], context[RRD_ID_LENGTH_MAX + 1];
1650
statsd_get_metric_type_and_id(m, type, id, context, "gauge", RRD_ID_LENGTH_MAX);
1651
@@ -1673,7 +1684,9 @@ static inline void statsd_private_chart_gauge(STATSD_METRIC *m) {
1684
static inline void statsd_private_chart_counter_or_meter(STATSD_METRIC *m, const char *dim, const char *family) {
1685
debug(D_STATSD, "updating private chart for %s metric '%s'", dim, m->name);
1686
1676
- if(unlikely(!m->st)) {
1687
+ if(unlikely(!m->st || m->options & STATSD_METRIC_OPTION_UPDATED_CHART_METADATA)) {
1688
+ m->options &= ~STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
1689
+
1690
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1], context[RRD_ID_LENGTH_MAX + 1];
1691
statsd_get_metric_type_and_id(m, type, id, context, dim, RRD_ID_LENGTH_MAX);
1692
@@ -1712,7 +1725,9 @@ static inline void statsd_private_chart_counter_or_meter(STATSD_METRIC *m, const
1725
static inline void statsd_private_chart_set(STATSD_METRIC *m) {
1726
debug(D_STATSD, "updating private chart for set metric '%s'", m->name);
1727
1715
- if(unlikely(!m->st)) {
1728
+ if(unlikely(!m->st || m->options & STATSD_METRIC_OPTION_UPDATED_CHART_METADATA)) {
1729
+ m->options &= ~STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
1730
+
1731
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1], context[RRD_ID_LENGTH_MAX + 1];
1732
statsd_get_metric_type_and_id(m, type, id, context, "set", RRD_ID_LENGTH_MAX);
1733
@@ -1751,7 +1766,9 @@ static inline void statsd_private_chart_set(STATSD_METRIC *m) {
1766
static inline void statsd_private_chart_dictionary(STATSD_METRIC *m) {
1767
debug(D_STATSD, "updating private chart for dictionary metric '%s'", m->name);
1768
1754
- if(unlikely(!m->st)) {
1769
+ if(unlikely(!m->st || m->options & STATSD_METRIC_OPTION_UPDATED_CHART_METADATA)) {
1770
+ m->options &= ~STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
1771
+
1772
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1], context[RRD_ID_LENGTH_MAX + 1];
1773
statsd_get_metric_type_and_id(m, type, id, context, "dictionary", RRD_ID_LENGTH_MAX);
1774
@@ -1793,7 +1810,9 @@ static inline void statsd_private_chart_dictionary(STATSD_METRIC *m) {
1810
static inline void statsd_private_chart_timer_or_histogram(STATSD_METRIC *m, const char *dim, const char *family, const char *units) {
1811
debug(D_STATSD, "updating private chart for %s metric '%s'", dim, m->name);
1812
1796
- if(unlikely(!m->st)) {
1813
+ if(unlikely(!m->st || m->options & STATSD_METRIC_OPTION_UPDATED_CHART_METADATA)) {
1814
+ m->options &= ~STATSD_METRIC_OPTION_UPDATED_CHART_METADATA;
1815
+
1816
char type[RRD_ID_LENGTH_MAX + 1], id[RRD_ID_LENGTH_MAX + 1], context[RRD_ID_LENGTH_MAX + 1];
1817
statsd_get_metric_type_and_id(m, type, id, context, dim, RRD_ID_LENGTH_MAX);
1818
database/rrdset.c
+10
@@ -317,6 +317,16 @@ static bool rrdset_conflict_callback(const DICTIONARY_ITEM *item __maybe_unused,
317
string_freez(old_units);
318
}
319
320
+ if(ctr->family && *ctr->family) {
321
+ STRING *old_family = st->family;
322
+ st->family = rrd_string_strdupz(ctr->family);
323
+ if(old_family != st->family)
324
+ ctr->react_action |= RRDSET_REACT_UPDATED;
325
+ string_freez(old_family);
326
+
327
+ // TODO - we should rename RRDFAMILY variables
328
+ }
329
+
330
if(ctr->context && *ctr->context) {
331
STRING *old_context = st->context;
332
st->context = rrd_string_strdupz(ctr->context);