| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #ifndef NETDATA_RRDLABELS_H |
| 4 | #define NETDATA_RRDLABELS_H |
| 5 | |
| 6 | #include "libnetdata/libnetdata.h" |
| 7 | |
| 8 | typedef enum __attribute__ ((__packed__)) rrdlabel_source { |
| 9 | RRDLABEL_SRC_AUTO = (1 << 0), // set when Netdata found the label by some automation |
| 10 | RRDLABEL_SRC_CONFIG = (1 << 1), // set when the user configured the label |
| 11 | RRDLABEL_SRC_K8S = (1 << 2), // set when this label is found from k8s (RRDLABEL_SRC_AUTO should also be set) |
| 12 | RRDLABEL_SRC_ACLK = (1 << 3), // set when this label is found from ACLK (RRDLABEL_SRC_AUTO should also be set) |
| 13 | |
| 14 | // more sources can be added here |
| 15 | |
| 16 | RRDLABEL_FLAG_DONT_DELETE = (1 << 29), // set when this label should never be removed (can be overwritten though) |
| 17 | RRDLABEL_FLAG_OLD = (1 << 30), // marks for rrdlabels internal use - they are not exposed outside rrdlabels |
| 18 | RRDLABEL_FLAG_NEW = (1 << 31) // marks for rrdlabels internal use - they are not exposed outside rrdlabels |
| 19 | } RRDLABEL_SRC; |
| 20 | |
| 21 | #define RRDLABEL_FLAG_INTERNAL (RRDLABEL_FLAG_OLD | RRDLABEL_FLAG_NEW | RRDLABEL_FLAG_DONT_DELETE) |
| 22 | |
| 23 | #define RRDLABELS_MAX_NAME_LENGTH 200 |
| 24 | #define RRDLABELS_MAX_VALUE_LENGTH 800 // 800 in bytes, up to 200 UTF-8 characters |
| 25 | |
| 26 | struct rrdlabels; |
| 27 | typedef struct rrdlabels RRDLABELS; |
| 28 | |
| 29 | void rrdlabels_aral_init(bool with_stats); |
| 30 | void rrdlabels_aral_destroy(bool with_stats); |
| 31 | RRDLABELS *rrdlabels_create(void); |
| 32 | void rrdlabels_destroy(RRDLABELS *labels_dict); |
| 33 | void rrdlabels_flush(RRDLABELS *labels); |
| 34 | void rrdlabels_add(RRDLABELS *labels, const char *name, const char *value, RRDLABEL_SRC ls); |
| 35 | // like rrdlabels_add() but returns true when the call actually changed the |
| 36 | // label set (new key, or value changed for an existing key); false when the |
| 37 | // key already existed with the same value. |
| 38 | bool rrdlabels_add_changed(RRDLABELS *labels, const char *name, const char *value, RRDLABEL_SRC ls); |
| 39 | void rrdlabels_add_pair(RRDLABELS *labels, const char *string, RRDLABEL_SRC ls); |
| 40 | void rrdlabels_value_to_buffer_array_item_or_null(RRDLABELS *labels, BUFFER *wb, const char *key); |
| 41 | void rrdlabels_key_to_buffer_array_item(RRDLABELS *labels, BUFFER *wb); |
| 42 | void rrdlabels_key_to_buffer_array_or_string_or_null(RRDLABELS *labels, BUFFER *wb); |
| 43 | void rrdlabels_get_value_strdup_or_null(RRDLABELS *labels, char **value, const char *key); |
| 44 | void rrdlabels_get_value_to_buffer_or_unset(RRDLABELS *labels, BUFFER *wb, const char *key, const char *unset); |
| 45 | bool rrdlabels_exist(RRDLABELS *labels, const char *key); |
| 46 | size_t rrdlabels_entries(RRDLABELS *labels __maybe_unused); |
| 47 | uint32_t rrdlabels_version(RRDLABELS *labels __maybe_unused); |
| 48 | void rrdlabels_get_value_strcpyz(RRDLABELS *labels, char *dst, size_t dst_len, const char *key); |
| 49 | |
| 50 | void rrdlabels_unmark_all(RRDLABELS *labels); |
| 51 | void rrdlabels_remove_all_unmarked(RRDLABELS *labels); |
| 52 | |
| 53 | // OR RRDLABEL_FLAG_OLD onto every entry whose source bits intersect src_match. |
| 54 | // Used after a best-effort loader (e.g. the kubernetes labels script) fails, |
| 55 | // so labels from that source survive the next rrdlabels_remove_all_unmarked() |
| 56 | // prune even though the loader did not re-add them this round. |
| 57 | void rrdlabels_mark_source_as_old(RRDLABELS *labels, RRDLABEL_SRC src_match); |
| 58 | |
| 59 | int rrdlabels_walkthrough_read(RRDLABELS *labels, int (*callback)(const char *name, const char *value, RRDLABEL_SRC ls, void *data), void *data); |
| 60 | int rrdlabels_walkthrough_read_string(RRDLABELS *labels, int (*callback)(STRING *name, STRING *value, RRDLABEL_SRC ls, void *data), void *data); |
| 61 | void rrdlabels_log_to_buffer(RRDLABELS *labels, BUFFER *wb); |
| 62 | bool rrdlabels_match_simple_pattern(RRDLABELS *labels, const char *simple_pattern_txt); |
| 63 | |
| 64 | SIMPLE_PATTERN_RESULT rrdlabels_match_simple_pattern_parsed(RRDLABELS *labels, SIMPLE_PATTERN *pattern, char equal, size_t *searches); |
| 65 | |
| 66 | // Forward declaration for RRDLABELS_AGGREGATED |
| 67 | struct rrdlabels_aggregated; |
| 68 | // Full text search through labels - matches if either key OR value matches the pattern |
| 69 | // If agg is NULL and matches are found, a new aggregated structure is created and returned |
| 70 | // If agg is not NULL, matches are added to it and it is returned |
| 71 | // Returns NULL only if no matches found and agg was NULL |
| 72 | struct rrdlabels_aggregated *rrdlabels_full_text_search(RRDLABELS *labels, SIMPLE_PATTERN *pattern, struct rrdlabels_aggregated *agg, size_t *searches); |
| 73 | int rrdlabels_to_buffer(RRDLABELS *labels, BUFFER *wb, const char *before_each, const char *equal, const char *quote, const char *between_them, |
| 74 | bool (*filter_callback)(const char *name, const char *value, RRDLABEL_SRC ls, void *data), void *filter_data, |
| 75 | void (*name_sanitizer)(char *dst, const char *src, size_t dst_size), |
| 76 | void (*value_sanitizer)(char *dst, const char *src, size_t dst_size)); |
| 77 | void rrdlabels_to_buffer_json_members(RRDLABELS *labels, BUFFER *wb); |
| 78 | |
| 79 | // migrate dst toward src by key/value: labels present in src but missing from |
| 80 | // dst are added, labels present in dst but missing from src are removed |
| 81 | // (entries flagged RRDLABEL_FLAG_DONT_DELETE are preserved). The RRDLABEL_SRC |
| 82 | // bits on entries that are already present in both are NOT reconciled to src. |
| 83 | // Returns true when at least one label was added or removed, false otherwise. |
| 84 | // A false return does not imply dst equals src bit-for-bit (preserved |
| 85 | // DONT_DELETE entries and unchanged RRDLABEL_SRC bits can still differ). |
| 86 | bool rrdlabels_migrate_to_these(RRDLABELS *dst, RRDLABELS *src); |
| 87 | |
| 88 | // finalize a CLABEL stream commit: remove unmarked entries and report whether |
| 89 | // the resulting label set differs from the pre-commit set (added, removed, or |
| 90 | // value-changed entries). |
| 91 | bool rrdlabels_remove_all_unmarked_and_changed(RRDLABELS *labels); |
| 92 | void rrdlabels_copy(RRDLABELS *dst, RRDLABELS *src); |
| 93 | size_t rrdlabels_common_count(RRDLABELS *labels1, RRDLABELS *labels2); |
| 94 | |
| 95 | int rrdlabels_unittest(void); |
| 96 | size_t rrdlabels_sanitize_name(char *dst, const char *src, size_t dst_size); |
| 97 | |
| 98 | // unfortunately this break when defined in exporting_engine.h |
| 99 | bool exporting_labels_filter_callback(const char *name, const char *value, RRDLABEL_SRC ls, void *data); |
| 100 | |
| 101 | int rrdlabels_registry_count(void); |
| 102 | |
| 103 | #endif /* NETDATA_RRDLABELS_H */ |