summaryrefslogtreecommitdiffstats
path: root/database
diff options
context:
space:
mode:
Diffstat (limited to 'database')
-rw-r--r--database/rrd.h117
-rw-r--r--database/rrdcalc.c91
-rw-r--r--database/rrdcalc.h4
-rw-r--r--database/rrdcalctemplate.c102
-rw-r--r--database/rrdcalctemplate.h4
-rw-r--r--database/rrdhost.c278
-rw-r--r--database/rrdlabels.c1230
-rw-r--r--database/rrdset.c105
-rw-r--r--database/sqlite/sqlite_aclk_chart.c12
-rw-r--r--database/sqlite/sqlite_aclk_node.c5
10 files changed, 1254 insertions, 694 deletions
diff --git a/database/rrd.h b/database/rrd.h
index dc32b2a2da..d17f0abb5f 100644
--- a/database/rrd.h
+++ b/database/rrd.h
@@ -3,6 +3,10 @@
#ifndef NETDATA_RRD_H
#define NETDATA_RRD_H 1
+#ifdef __cplusplus
+extern "C" {
+#endif
+
// forward typedefs
typedef struct rrdhost RRDHOST;
typedef struct rrddim RRDDIM;
@@ -22,7 +26,6 @@ typedef void *ml_dimension_t;
struct rrddim_volatile;
struct rrdset_volatile;
struct context_param;
-struct label;
#ifdef ENABLE_DBENGINE
struct rrdeng_page_descr;
struct rrdengine_instance;
@@ -177,66 +180,45 @@ typedef enum rrddim_flags {
#define rrddim_flag_set(rd, flag) __atomic_or_fetch(&((rd)->flags), (flag), __ATOMIC_SEQ_CST)
#define rrddim_flag_clear(rd, flag) __atomic_and_fetch(&((rd)->flags), ~(flag), __ATOMIC_SEQ_CST)
-typedef enum label_source {
- LABEL_SOURCE_AUTO = 0,
- LABEL_SOURCE_NETDATA_CONF = 1,
- LABEL_SOURCE_DOCKER = 2,
- LABEL_SOURCE_ENVIRONMENT = 3,
- LABEL_SOURCE_KUBERNETES = 4
-} LABEL_SOURCE;
-
-#define LABEL_FLAG_UPDATE_STREAM 1
-#define LABEL_FLAG_STOP_STREAM 2
-
-struct label {
- char *key, *value;
- uint32_t key_hash;
- LABEL_SOURCE label_source;
- struct label *next;
-};
+typedef enum rrdlabel_source {
+ RRDLABEL_SRC_AUTO = (1 << 0), // set when Netdata found the label by some automation
+ RRDLABEL_SRC_CONFIG = (1 << 1), // set when the user configured the label
+ RRDLABEL_SRC_K8S = (1 << 2), // set when this label is found from k8s (RRDLABEL_SRC_AUTO should also be set)
+ RRDLABEL_SRC_ACLK = (1 << 3), // set when this label is found from ACLK (RRDLABEL_SRC_AUTO should also be set)
-struct label_index {
- struct label *head; // Label list
- netdata_rwlock_t labels_rwlock; // lock for the label list
- uint32_t labels_flag; // Flags for labels
-};
+ // more sources can be added here
+
+ RRDLABEL_FLAG_OLD = (1 << 30), // marks set for rrdlabels internal use - they are not exposed outside rrdlabels
+ RRDLABEL_FLAG_NEW = (1 << 31) //
+} RRDLABEL_SRC;
+
+extern DICTIONARY *rrdlabels_create(void);
+extern void rrdlabels_destroy(DICTIONARY *labels_dict);
+extern void rrdlabels_add(DICTIONARY *dict, const char *name, const char *value, RRDLABEL_SRC ls);
+extern void rrdlabels_add_pair(DICTIONARY *dict, const char *string, RRDLABEL_SRC ls);
+extern void rrdlabels_get_value_to_buffer_or_null(DICTIONARY *labels, BUFFER *wb, const char *key, const char *quote, const char *null);
+
+extern void rrdlabels_unmark_all(DICTIONARY *labels);
+extern void rrdlabels_remove_all_unmarked(DICTIONARY *labels);
+
+extern int rrdlabels_walkthrough_read(DICTIONARY *labels, int (*callback)(const char *name, const char *value, RRDLABEL_SRC ls, void *data), void *data);
+extern int rrdlabels_sorted_walkthrough_read(DICTIONARY *labels, int (*callback)(const char *name, const char *value, RRDLABEL_SRC ls, void *data), void *data);
+
+extern void rrdlabels_log_to_buffer(DICTIONARY *labels, BUFFER *wb);
+extern bool rrdlabels_match_simple_pattern(DICTIONARY *labels, const char *simple_pattern_txt);
+extern bool rrdlabels_match_simple_pattern_parsed(DICTIONARY *labels, SIMPLE_PATTERN *pattern, char equal);
+extern void rrdlabels_to_buffer(DICTIONARY *labels, BUFFER *wb, const char *before_each, const char *equal, const char *quote, const char *between_them, bool (*filter_callback)(const char *name, const char *value, RRDLABEL_SRC ls, void *data), void *filter_data, void (*name_sanitizer)(char *dst, const char *src, size_t dst_size), void (*value_sanitizer)(char *dst, const char *src, size_t dst_size));
+
+extern void rrdlabels_migrate_to_these(DICTIONARY *dst, DICTIONARY *src);
+extern void rrdlabels_copy(DICTIONARY *dst, DICTIONARY *src);
-typedef enum strip_quotes {
- DO_NOT_STRIP_QUOTES,
- STRIP_QUOTES
-} STRIP_QUOTES_OPTION;
-
-typedef enum skip_escaped_characters {
- DO_NOT_SKIP_ESCAPED_CHARACTERS,
- SKIP_ESCAPED_CHARACTERS
-} SKIP_ESCAPED_CHARACTERS_OPTION;
-
-char *translate_label_source(LABEL_SOURCE l);
-struct label *create_label(char *key, char *value, LABEL_SOURCE label_source);
-extern struct label *add_label_to_list(struct label *l, char *key, char *value, LABEL_SOURCE label_source);
-extern void update_label_list(struct label **labels, struct label *new_labels);
-extern void replace_label_list(struct label_index *labels, struct label *new_labels);
-extern int is_valid_label_value(char *value);
-extern int is_valid_label_key(char *key);
-extern void free_label_list(struct label *labels);
-extern struct label *label_list_lookup_key(struct label *head, char *key, uint32_t key_hash);
-extern struct label *label_list_lookup_keylist(struct label *head, char *keylist);
-extern int label_list_contains_keylist(struct label *head, char *keylist);
-extern int label_list_contains_key(struct label *head, char *key, uint32_t key_hash);
-extern int label_list_contains(struct label *head, struct label *check);
-extern struct label *merge_label_lists(struct label *lo_pri, struct label *hi_pri);
-extern void strip_last_symbol(
- char *str,
- char symbol,
- SKIP_ESCAPED_CHARACTERS_OPTION skip_escaped_characters);
-extern char *strip_double_quotes(char *str, SKIP_ESCAPED_CHARACTERS_OPTION skip_escaped_characters);
void reload_host_labels(void);
-extern void rrdset_add_label_to_new_list(RRDSET *st, char *key, char *value, LABEL_SOURCE source);
-extern void rrdset_finalize_labels(RRDSET *st);
-extern void rrdset_update_labels(RRDSET *st, struct label *labels);
-extern int rrdset_contains_label_keylist(RRDSET *st, char *key);
-extern int rrdset_matches_label_keys(RRDSET *st, char *key, char *words[], uint32_t *hash_key_list, int *word_count, int size);
-extern struct label *rrdset_lookup_label_key(RRDSET *st, char *key, uint32_t key_hash);
+extern void rrdset_update_rrdlabels(RRDSET *st, DICTIONARY *new_rrdlabels);
+
+extern int rrdlabels_unittest(void);
+
+// unfortunately this break when defined in exporting_engine.h
+extern bool exporting_labels_filter_callback(const char *name, const char *value, RRDLABEL_SRC ls, void *data);
// ----------------------------------------------------------------------------
// RRD DIMENSION - this is a metric
@@ -402,8 +384,7 @@ struct rrdset_volatile {
char *old_units;
char *old_context;
uuid_t hash_id;
- struct label *new_labels;
- struct label_index labels;
+ DICTIONARY *chart_labels;
bool is_ar_chart;
};
@@ -593,11 +574,14 @@ typedef enum rrdhost_flags {
RRDHOST_FLAG_ORPHAN = 1 << 0, // this host is orphan (not receiving data)
RRDHOST_FLAG_DELETE_OBSOLETE_CHARTS = 1 << 1, // delete files of obsolete charts
RRDHOST_FLAG_DELETE_ORPHAN_HOST = 1 << 2, // delete the entire host when orphan
- RRDHOST_FLAG_EXPORTING_SEND = 1 << 3, // send it to external databases
- RRDHOST_FLAG_EXPORTING_DONT_SEND = 1 << 4, // don't send it to external databases
+ RRDHOST_FLAG_EXPORTING_SEND = 1 << 3, // send it to external databases
+ RRDHOST_FLAG_EXPORTING_DONT_SEND = 1 << 4, // don't send it to external databases
RRDHOST_FLAG_ARCHIVED = 1 << 5, // The host is archived, no collected charts yet
RRDHOST_FLAG_MULTIHOST = 1 << 6, // Host belongs to localhost/megadb
- RRDHOST_FLAG_PENDING_FOREACH_ALARMS = 1 << 7, // contains dims with uninitialized foreach alarms
+ RRDHOST_FLAG_PENDING_FOREACH_ALARMS = 1 << 7, // contains dims with uninitialized foreach alarms
+ RRDHOST_FLAG_STREAM_LABELS_UPDATE = 1 << 8,
+ RRDHOST_FLAG_STREAM_LABELS_STOP = 1 << 9,
+
} RRDHOST_FLAGS;
#define rrdhost_flag_check(host, flag) (__atomic_load_n(&((host)->flags), __ATOMIC_SEQ_CST) & (flag))
@@ -859,7 +843,7 @@ struct rrdhost {
// ------------------------------------------------------------------------
// Support for host-level labels
- struct label_index labels;
+ DICTIONARY *host_labels;
// ------------------------------------------------------------------------
// indexes
@@ -1349,4 +1333,9 @@ extern void set_host_properties(
#include "sqlite/sqlite_aclk_alert.h"
#include "sqlite/sqlite_aclk_node.h"
#include "sqlite/sqlite_health.h"
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* NETDATA_RRD_H */
diff --git a/database/rrdcalc.c b/database/rrdcalc.c
index b29a0ffc00..6af7054cf4 100644
--- a/database/rrdcalc.c
+++ b/database/rrdcalc.c
@@ -109,51 +109,23 @@ static void rrdsetcalc_link(RRDSET *st, RRDCALC *rc) {
health_alarm_log(host, ae);
}
-static inline int rrdcalc_test_additional_restriction(RRDCALC *rc, RRDSET *st){
- if (rc->module_match && !simple_pattern_matches(rc->module_pattern, st->module_name))
+static int rrdcalc_is_matching_rrdset(RRDCALC *rc, RRDSET *st) {
+ if((rc->hash_chart != st->hash || strcmp(rc->chart, st->id) != 0) &&
+ (rc->hash_chart != st->hash_name || strcmp(rc->chart, st->name) != 0))
return 0;
- if (rc->plugin_match && !simple_pattern_matches(rc->plugin_pattern, st->plugin_name))
+ if (rc->module_pattern && !simple_pattern_matches(rc->module_pattern, st->module_name))
return 0;
- if (rc->labels) {
- int labels_count=1;
- int labels_match=0;
- char *s = rc->labels;
- while (*s) {
- if (*s==' ')
- labels_count++;
- s++;
- }
- RRDHOST *host = st->rrdhost;
- char cmp[CONFIG_FILE_LINE_MAX+1];
- struct label *move = host->labels.head;
- while(move) {
- snprintf(cmp, CONFIG_FILE_LINE_MAX, "%s=%s", move->key, move->value);
- if (simple_pattern_matches(rc->splabels, move->key) ||
- simple_pattern_matches(rc->splabels, cmp)) {
- labels_match++;
- }
- move = move->next;
- }
+ if (rc->plugin_pattern && !simple_pattern_matches(rc->plugin_pattern, st->plugin_name))
+ return 0;
- if (labels_match != labels_count)
- return 0;
- }
+ if (st->rrdhost->host_labels && rc->host_labels_pattern && !rrdlabels_match_simple_pattern_parsed(st->rrdhost->host_labels, rc->host_labels_pattern, '='))
+ return 0;
return 1;
}
-static inline int rrdcalc_is_matching_this_rrdset(RRDCALC *rc, RRDSET *st) {
- if(((rc->hash_chart == st->hash && !strcmp(rc->chart, st->id)) ||
- (rc->hash_chart == st->hash_name && !strcmp(rc->chart, st->name))) &&
- rrdcalc_test_additional_restriction(rc, st)) {
- return 1;
- }
-
- return 0;
-}
-
// this has to be called while the RRDHOST is locked
inline void rrdsetcalc_link_matching(RRDSET *st) {
RRDHOST *host = st->rrdhost;
@@ -164,7 +136,7 @@ inline void rrdsetcalc_link_matching(RRDSET *st) {
if(unlikely(rc->rrdset))
continue;
- if(unlikely(rrdcalc_is_matching_this_rrdset(rc, st)))
+ if(unlikely(rrdcalc_is_matching_rrdset(rc, st)))
rrdsetcalc_link(st, rc);
}
}
@@ -382,7 +354,7 @@ inline void rrdcalc_add_to_host(RRDHOST *host, RRDCALC *rc) {
// link it to its chart
RRDSET *st;
rrdset_foreach_read(st, host) {
- if(rrdcalc_is_matching_this_rrdset(rc, st)) {
+ if(rrdcalc_is_matching_rrdset(rc, st)) {
rrdsetcalc_link(st, rc);
break;
}
@@ -612,8 +584,8 @@ void rrdcalc_free(RRDCALC *rc) {
freez(rc->component);
freez(rc->type);
simple_pattern_free(rc->spdim);
- freez(rc->labels);
- simple_pattern_free(rc->splabels);
+ freez(rc->host_labels);
+ simple_pattern_free(rc->host_labels_pattern);
freez(rc->module_match);
simple_pattern_free(rc->module_pattern);
freez(rc->plugin_match);
@@ -681,51 +653,26 @@ void rrdcalc_foreach_unlink_and_free(RRDHOST *host, RRDCALC *rc) {
}
static void rrdcalc_labels_unlink_alarm_loop(RRDHOST *host, RRDCALC *alarms) {
- RRDCALC *rc = alarms;
- while (rc) {
- if (!rc->labels) {
- rc = rc->next;
- continue;
- }
-
- char cmp[CONFIG_FILE_LINE_MAX+1];
- struct label *move = host->labels.head;
- while(move) {
- snprintf(cmp, CONFIG_FILE_LINE_MAX, "%s=%s", move->key, move->value);
- if (simple_pattern_matches(rc->splabels, move->key) ||
- simple_pattern_matches(rc->splabels, cmp)) {
- break;
- }
-
- move = move->next;
- }
+ for(RRDCALC *rc = alarms ; rc ; rc = rc->next ) {
+ if (!rc->host_labels) continue;
- RRDCALC *next = rc->next;
- if(!move) {
+ if(!rrdlabels_match_simple_pattern_parsed(host->host_labels, rc->host_labels_pattern, '=')) {
info("Health configuration for alarm '%s' cannot be applied, because the host %s does not have the label(s) '%s'",
rc->name,
host->hostname,
- rc->labels);
+ rc->host_labels);
- if(host->alarms == alarms) {
+ if(host->alarms == alarms)
rrdcalc_unlink_and_free(host, rc);
- } else
+ else
rrdcalc_foreach_unlink_and_free(host, rc);
-
}
-
- rc = next;
}
}
void rrdcalc_labels_unlink_alarm_from_host(RRDHOST *host) {
- rrdhost_check_rdlock(host);
- netdata_rwlock_rdlock(&host->labels.labels_rwlock);
-
rrdcalc_labels_unlink_alarm_loop(host, host->alarms);
rrdcalc_labels_unlink_alarm_loop(host, host->alarms_with_foreach);
-
- netdata_rwlock_unlock(&host->labels.labels_rwlock);
}
void rrdcalc_labels_unlink() {
@@ -736,7 +683,7 @@ void rrdcalc_labels_unlink() {
if (unlikely(!host->health_enabled))
continue;
- if (host->labels.head) {
+ if (host->host_labels) {
rrdhost_wrlock(host);
rrdcalc_labels_unlink_alarm_from_host(host);
diff --git a/database/rrdcalc.h b/database/rrdcalc.h
index 2ae47788e3..86464b87f2 100644
--- a/database/rrdcalc.h
+++ b/database/rrdcalc.h
@@ -103,8 +103,8 @@ struct rrdcalc {
// ------------------------------------------------------------------------
// Labels settings
- char *labels; // the label read from an alarm file
- SIMPLE_PATTERN *splabels; // the simple pattern of labels
+ char *host_labels; // the label read from an alarm file
+ SIMPLE_PATTERN *host_labels_pattern; // the simple pattern of labels
// ------------------------------------------------------------------------
// runtime information
diff --git a/database/rrdcalctemplate.c b/database/rrdcalctemplate.c
index 9789f4beab..3f9804b936 100644
--- a/database/rrdcalctemplate.c
+++ b/database/rrdcalctemplate.c
@@ -4,98 +4,50 @@
#include "rrd.h"
// ----------------------------------------------------------------------------
+// RRDCALCTEMPLATE management
+/**
+ * RRDCALC TEMPLATE LINK MATCHING
+ *
+ * @param rt is the template used to create the chart.
+ * @param st is the chart where the alarm will be attached.
+ */
+void rrdcalctemplate_check_conditions_and_link(RRDCALCTEMPLATE *rt, RRDSET *st, RRDHOST *host) {
+ if(rt->hash_context != st->hash_context || strcmp(rt->context, st->context) != 0)
+ return;
-static int rrdcalctemplate_is_there_label_restriction(RRDCALCTEMPLATE *rt, RRDHOST *host) {
- if(!rt->labels)
- return 0;
-
- errno = 0;
- struct label *move = host->labels.head;
- char cmp[CONFIG_FILE_LINE_MAX+1];
-
- int ret;
- if(move) {
- rrdhost_check_rdlock(host);
- netdata_rwlock_rdlock(&host->labels.labels_rwlock);
- while(move) {
- snprintfz(cmp, CONFIG_FILE_LINE_MAX, "%s=%s", move->key, move->value);
- if (simple_pattern_matches(rt->splabels, move->key) ||
- simple_pattern_matches(rt->splabels, cmp)) {
- break;
- }
- move = move->next;
- }
- netdata_rwlock_unlock(&host->labels.labels_rwlock);
-
- if(!move) {
- error("Health template '%s' cannot be applied, because the host %s does not have the label(s) '%s'",
- rt->name,
- host->hostname,
- rt->labels
- );
- ret = 1;
- } else {
- ret = 0;
- }
- } else {
- ret =0;
- }
-
- return ret;
-}
-
-static inline int rrdcalctemplate_test_additional_restriction(RRDCALCTEMPLATE *rt, RRDSET *st) {
if (rt->charts_pattern && !simple_pattern_matches(rt->charts_pattern, st->name))
- return 0;
+ return;
if (rt->family_pattern && !simple_pattern_matches(rt->family_pattern, st->family))
- return 0;
+ return;
if (rt->module_pattern && !simple_pattern_matches(rt->module_pattern, st->module_name))
- return 0;
+ return;
if (rt->plugin_pattern && !simple_pattern_matches(rt->plugin_pattern, st->plugin_name))
- return 0;
+ return;
- return 1;
-}
+ if(host->host_labels && rt->host_labels_pattern && !rrdlabels_match_simple_pattern_parsed(host->host_labels, rt->host_labels_pattern, '='))
+ return;
-// RRDCALCTEMPLATE management
-/**
- * RRDCALC TEMPLATE LINK MATCHING
- *
- * @param rt is the template used to create the chart.
- * @param st is the chart where the alarm will be attached.
- */
-void rrdcalctemplate_link_matching_test(RRDCALCTEMPLATE *rt, RRDSET *st, RRDHOST *host) {
- if(rt->hash_context == st->hash_context && !strcmp(rt->context, st->context) &&
- rrdcalctemplate_test_additional_restriction(rt, st) ) {
- if (!rrdcalctemplate_is_there_label_restriction(rt, host)) {
- RRDCALC *rc = rrdcalc_create_from_template(host, rt, st->id);
- if (unlikely(!rc))
- info("Health tried to create alarm from template '%s' on chart '%s' of host '%s', but it failed",
- rt->name, st->id, host->hostname);
+ RRDCALC *rc = rrdcalc_create_from_template(host, rt, st->id);
+ if (unlikely(!rc))
+ info("Health tried to create alarm from template '%s' on chart '%s' of host '%s', but it failed", rt->name, st->id, host->hostname);
#ifdef NETDATA_INTERNAL_CHECKS
- else if (rc->rrdset != st &&
- !rc->foreachdim) //When we have a template with foreadhdim, the child will be added to the index late
- error("Health alarm '%s.%s' should be linked to chart '%s', but it is not",
- rc->chart ? rc->chart : "NOCHART", rc->name, st->id);
+ else if (rc->rrdset != st && !rc->foreachdim) //When we have a template with foreadhdim, the child will be added to the index late
+ error("Health alarm '%s.%s' should be linked to chart '%s', but it is not", rc->chart ? rc->chart : "NOCHART", rc->name, st->id);
#endif
- }
- }
}
void rrdcalctemplate_link_matching(RRDSET *st) {
RRDHOST *host = st->rrdhost;
RRDCALCTEMPLATE *rt;
- for(rt = host->templates; rt ; rt = rt->next) {
- rrdcalctemplate_link_matching_test(rt, st, host);
- }
+ for(rt = host->templates; rt ; rt = rt->next)
+ rrdcalctemplate_check_conditions_and_link(rt, st, host);
- for(rt = host->alarms_template_with_foreach; rt ; rt = rt->next) {
- rrdcalctemplate_link_matching_test(rt, st, host);
- }
+ for(rt = host->alarms_template_with_foreach; rt ; rt = rt->next)
+ rrdcalctemplate_check_conditions_and_link(rt, st, host);
}
inline void rrdcalctemplate_free(RRDCALCTEMPLATE *rt) {
@@ -129,9 +81,9 @@ inline void rrdcalctemplate_free(RRDCALCTEMPLATE *rt) {
freez(rt->info);
freez(rt->dimensions);
freez(rt->foreachdim);
- freez(rt->labels);
+ freez(rt->host_labels);
simple_pattern_free(rt->spdim);
- simple_pattern_free(rt->splabels);
+ simple_pattern_free(rt->host_labels_pattern);
freez(rt);
}
diff --git a/database/rrdcalctemplate.h b/database/rrdcalctemplate.h
index 0f12bba059..63d843c92e 100644
--- a/database/rrdcalctemplate.h
+++ b/database/rrdcalctemplate.h
@@ -74,8 +74,8 @@ struct rrdcalctemplate {
// ------------------------------------------------------------------------
// Labels settings
- char *labels; // the label read from an alarm file
- SIMPLE_PATTERN *splabels; // the simple pattern of labels
+ char *host_labels; // the label read from an alarm file
+ SIMPLE_PATTERN *host_labels_pattern; // the simple pattern of labels
// ------------------------------------------------------------------------
// expressions related to the alarm
diff --git a/database/rrdhost.c b/database/rrdhost.c
index cb56bf353a..3b020b7be2 100644
--- a/database/rrdhost.c
+++ b/database/rrdhost.c
@@ -199,7 +199,7 @@ RRDHOST *rrdhost_create(const char *hostname,
#endif
netdata_rwlock_init(&host->rrdhost_rwlock);
- netdata_rwlock_init(&host->labels.labels_rwlock);
+ host->host_labels = rrdlabels_create();
netdata_mutex_init(&host->aclk_state_lock);
@@ -976,7 +976,7 @@ void rrdhost_free(RRDHOST *host) {
freez(host->aclk_state.claimed_id);
freez(host->aclk_state.prev_claimed_id);
freez((void *)host->tags);
- free_label_list(host->labels.head);
+ rrdlabels_destroy(host->host_labels);
freez((void *)host->os);
freez((void *)host->timezone);
freez((void *)host->abbrev_timezone);
@@ -994,7 +994,6 @@ void rrdhost_free(RRDHOST *host) {
freez(host->registry_hostname);
simple_pattern_free(host->rrdpush_send_charts_matching);
rrdhost_unlock(host);
- netdata_rwlock_destroy(&host->labels.labels_rwlock);
netdata_rwlock_destroy(&host->health_log.alarm_log_rwlock);
netdata_rwlock_destroy(&host->rrdhost_rwlock);
freez(host->node_id);
@@ -1038,297 +1037,138 @@ void rrdhost_save_charts(RRDHOST *host) {
rrdhost_unlock(host);
}
-static struct label *rrdhost_load_auto_labels(void)
-{
- struct label *label_list = NULL;
+static void rrdhost_load_auto_labels(void) {
+ DICTIONARY *labels = localhost->host_labels;
if (localhost->system_info->cloud_provider_type)
- label_list =
- add_label_to_list(label_list, "_cloud_provider_type", localhost->system_info->cloud_provider_type, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_cloud_provider_type", localhost->system_info->cloud_provider_type, RRDLABEL_SRC_AUTO);
if (localhost->system_info->cloud_instance_type)
- label_list =
- add_label_to_list(label_list, "_cloud_instance_type", localhost->system_info->cloud_instance_type, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_cloud_instance_type", localhost->system_info->cloud_instance_type, RRDLABEL_SRC_AUTO);
if (localhost->system_info->cloud_instance_region)
- label_list =
- add_label_to_list(label_list, "_cloud_instance_region", localhost->system_info->cloud_instance_region, LABEL_SOURCE_AUTO);
+ rrdlabels_add(
+ labels, "_cloud_instance_region", localhost->system_info->cloud_instance_region, RRDLABEL_SRC_AUTO);
if (localhost->system_info->host_os_name)
- label_list =
- add_label_to_list(label_list, "_os_name", localhost->system_info->host_os_name, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_os_name", localhost->system_info->host_os_name, RRDLABEL_SRC_AUTO);
if (localhost->system_info->host_os_version)
- label_list =
- add_label_to_list(label_list, "_os_version", localhost->system_info->host_os_version, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_os_version", localhost->system_info->host_os_version, RRDLABEL_SRC_AUTO);
if (localhost->system_info->kernel_version)
- label_list =
- add_label_to_list(label_list, "_kernel_version", localhost->system_info->kernel_version, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_kernel_version", localhost->system_info->kernel_version, RRDLABEL_SRC_AUTO);
if (localhost->system_info->host_cores)
- label_list =
- add_label_to_list(label_list, "_system_cores", localhost->system_info->host_cores, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_system_cores", localhost->system_info->host_cores, RRDLABEL_SRC_AUTO);
if (localhost->system_info->host_cpu_freq)
- label_list =
- add_label_to_list(label_list, "_system_cpu_freq", localhost->system_info->host_cpu_freq, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_system_cpu_freq", localhost->system_info->host_cpu_freq, RRDLABEL_SRC_AUTO);
if (localhost->system_info->host_ram_total)
- label_list =
- add_label_to_list(label_list, "_system_ram_total", localhost->system_info->host_ram_total, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_system_ram_total", localhost->system_info->host_ram_total, RRDLABEL_SRC_AUTO);
if (localhost->system_info->host_disk_space)
- label_list =
- add_label_to_list(label_list, "_system_disk_space", localhost->system_info->host_disk_space, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_system_disk_space", localhost->system_info->host_disk_space, RRDLABEL_SRC_AUTO);
if (localhost->system_info->architecture)
- label_list =
- add_label_to_list(label_list, "_architecture", localhost->system_info->architecture, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_architecture", localhost->system_info->architecture, RRDLABEL_SRC_AUTO);
if (localhost->system_info->virtualization)
- label_list =
- add_label_to_list(label_list, "_virtualization", localhost->system_info->virtualization, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_virtualization", localhost->system_info->virtualization, RRDLABEL_SRC_AUTO);
if (localhost->system_info->container)
- label_list =
- add_label_to_list(label_list, "_container", localhost->system_info->container, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_container", localhost->system_info->container, RRDLABEL_SRC_AUTO);
if (localhost->system_info->container_detection)
- label_list =
- add_label_to_list(label_list, "_container_detection", localhost->system_info->container_detection, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_container_detection", localhost->system_info->container_detection, RRDLABEL_SRC_AUTO);
if (localhost->system_info->virt_detection)
- label_list =
- add_label_to_list(label_list, "_virt_detection", localhost->system_info->virt_detection, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_virt_detection", localhost->system_info->virt_detection, RRDLABEL_SRC_AUTO);
if (localhost->system_info->is_k8s_node)
- label_list =
- add_label_to_list(label_list, "_is_k8s_node", localhost->system_info->is_k8s_node, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_is_k8s_node", localhost->system_info->is_k8s_node, RRDLABEL_SRC_AUTO);
if (localhost->system_info->install_type)
- label_list =
- add_label_to_list(label_list, "_install_type", localhost->system_info->install_type, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_install_type", localhost->system_info->install_type, RRDLABEL_SRC_AUTO);
if (localhost->system_info->prebuilt_arch)
- label_list =
- add_label_to_list(label_list, "_prebuilt_arch", localhost->system_info->prebuilt_arch, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_prebuilt_arch", localhost->system_info->prebuilt_arch, RRDLABEL_SRC_AUTO);
if (localhost->system_info->prebuilt_dist)
- label_list =
- add_label_to_list(label_list, "_prebuilt_dist", localhost->system_info->prebuilt_dist, LABEL_SOURCE_AUTO);
+ rrdlabels_add(labels, "_prebuilt_dist", localhost->system_info->prebuilt_dist, RRDLABEL_SRC_AUTO);
- label_list = add_aclk_host_labels(label_list);
+ add_aclk_host_labels();
- label_list = add_label_to_list(
- label_list, "_is_parent", (localhost->next || configured_as_parent()) ? "true" : "false", LABEL_SOURCE_AUTO);
+ rrdlabels_add(
+ labels, "_is_parent", (localhost->next || configured_as_parent()) ? "true" : "false", RRDLABEL_SRC_AUTO);
if (localhost->rrdpush_send_destination)
- label_list =
- add_label_to_list(label_list, "_streams_to", localhost->rrdpush_send_destination, LABEL_SOURCE_AUTO);
-
- return label_list;
-}
-
-static inline int rrdhost_is_valid_label_config_option(char *name, char *value)
-{
- return (is_valid_label_key(name) && is_valid_label_value(value) && strcmp(name, "from environment") &&
- strcmp(name, "from kubernetes pods"));
+ rrdlabels_add(labels, "_streams_to", localhost->rrdpush_send_destination, RRDLABEL_SRC_AUTO);
}
-static struct label *rrdhost_load_config_labels()
-{
+static void rrdhost_load_config_labels(void) {
int status = config_load(NULL, 1, CONFIG_SECTION_HOST_LABEL);
if(!status) {
char *filename = CONFIG_DIR "/" CONFIG_FILENAME;
- error("LABEL: Cannot reload the configuration file '%s', using labels in memory", filename);
+ error("RRDLABEL: Cannot reload the configuration file '%s', using labels in memory", filename);
}
- struct label *l = NULL;
struct section *co = appconfig_get_section(&netdata_config, CONFIG_SECTION_HOST_LABEL);
if(co) {
config_section_wrlock(co);
struct config_option *cv;
for(cv = co->values; cv ; cv = cv->next) {
- if(rrdhost_is_valid_label_config_option(cv->name, cv->value)) {
- l = add_label_to_list(l, cv->name, cv->value, LABEL_SOURCE_NETDATA_CONF);
- cv->flags |= CONFIG_VALUE_USED;
- } else {
- error("LABELS: It was not possible to create the label '%s' because it contains invalid character(s) or values."
- , cv->name);
- }
+ rrdlabels_add(localhost->host_labels, cv->name, cv->value, RRDLABEL_SRC_CONFIG);
+ cv->flags |= CONFIG_VALUE_USED;
}
config_section_unlock(co);
}
-
- return l;
}
-struct label *parse_simple_tags(
- struct label *label_list,
- const char *tags,
- char key_value_separator,
- char label_separator,
- STRIP_QUOTES_OPTION strip_quotes_from_key,
- STRIP_QUOTES_OPTION strip_quotes_from_value,
- SKIP_ESCAPED_CHARACTERS_OPTION skip_escaped_characters)
-{
- const char *end = tags;
-
- while (*end) {
- const char *start = end;
- char key[CONFIG_MAX_VALUE + 1];
- char value[CONFIG_MAX_VALUE + 1];
-
- while (*end && *end != key_value_separator)
- end++;
- strncpyz(key, start, end - start);
-
- if (*end)
- start = ++end;
- while (*end && *end != label_separator)
- end++;
- strncpyz(value, start, end - start);
-
- label_list = add_label_to_list(
- label_list,
- strip_quotes_from_key ? strip_double_quotes(trim(key), skip_escaped_characters) : trim(key),
- strip_quotes_from_value ? strip_double_quotes(trim(value), skip_escaped_characters) : trim(value),
- LABEL_SOURCE_NETDATA_CONF);
+static void rrdhost_load_kubernetes_labels(void) {
+ char label_script[sizeof(char) * (strlen(netdata_configured_primary_plugins_dir) + strlen("get-kubernetes-labels.sh") + 2)];
+ sprintf(label_script, "%s/%s", netdata_configured_primary_plugins_dir, "get-kubernetes-labels.sh");
- if (*end)
- end++;
+ if (unlikely(access(label_script, R_OK) != 0)) {
+ error("Kubernetes pod label fetching script %s not found.",label_script);
+ return;
}
- return label_list;
-}
-
-struct label *parse_json_tags(struct label *label_list, const char *tags)
-{
- char tags_buf[CONFIG_MAX_VALUE + 1];
- strncpy(tags_buf, tags, CONFIG_MAX_VALUE);
- char *str = tags_buf;
-
- switch (*str) {
- case '{':
- str++;
- strip_last_symbol(str, '}', SKIP_ESCAPED_CHARACTERS);
-
- label_list = parse_simple_tags(label_list, str, ':', ',', STRIP_QUOTES, STRIP_QUOTES, SKIP_ESCAPED_CHARACTERS);
+ debug(D_RRDHOST, "Attempting to fetch external labels via %s", label_script);
- break;
- case '[':
- str++;
- strip_last_symbol(str, ']', SKIP_ESCAPED_CHARACTERS);
+ pid_t pid;
+ FILE *fp = mypopen(label_script, &pid);
+ if(!fp) return;
- char *end = str + strlen(str);
- size_t i = 0;
+ char buffer[1000 + 1];
+ while (fgets(buffer, 1000, fp) != NULL)
+ rrdlabels_add_pair(localhost->host_labels, buffer, RRDLABEL_SRC_AUTO|RRDLABEL_SRC_K8S);
- while (str < end) {
- char key[CONFIG_MAX_VALUE + 1];
- snprintfz(key, CONFIG_MAX_VALUE, "host_tag%zu", i);
-
- str = strip_double_quotes(trim(str), SKIP_ESCAPED_CHARACTERS);
-
- label_list = add_label_to_list(label_list, key, str, LABEL_SOURCE_NETDATA_CONF);
-
- // skip to the next element in the array
- str += strlen(str) + 1;
- while (*str && *str != ',')
- str++;
- str++;
- i++;
- }
-
- break;
- case '"':
- label_list = add_label_to_list(
- label_list, "host_tag", strip_double_quotes(str, SKIP_ESCAPED_CHARACTERS), LABEL_SOURCE_NETDATA_CONF);
- break;
- default:
- label_list = add_label_to_list(label_list, "host_tag", str, LABEL_SOURCE_NETDATA_CONF);
- break;
- }
-
- return label_lis