diff options
Diffstat (limited to 'database')
-rw-r--r-- | database/rrd.h | 117 | ||||
-rw-r--r-- | database/rrdcalc.c | 91 | ||||
-rw-r--r-- | database/rrdcalc.h | 4 | ||||
-rw-r--r-- | database/rrdcalctemplate.c | 102 | ||||
-rw-r--r-- | database/rrdcalctemplate.h | 4 | ||||
-rw-r--r-- | database/rrdhost.c | 278 | ||||
-rw-r--r-- | database/rrdlabels.c | 1230 | ||||
-rw-r--r-- | database/rrdset.c | 105 | ||||
-rw-r--r-- | database/sqlite/sqlite_aclk_chart.c | 12 | ||||
-rw-r--r-- | database/sqlite/sqlite_aclk_node.c | 5 |
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 |