diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 11:19:16 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-24 09:53:24 +0000 |
commit | b5f8ee61a7f7e9bd291dd26b0585d03eb686c941 (patch) | |
tree | d4d31289c39fc00da064a825df13a0b98ce95b10 /src/libnetdata/line_splitter | |
parent | Adding upstream version 1.44.3. (diff) | |
download | netdata-b5f8ee61a7f7e9bd291dd26b0585d03eb686c941.tar.xz netdata-b5f8ee61a7f7e9bd291dd26b0585d03eb686c941.zip |
Adding upstream version 1.46.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/libnetdata/line_splitter')
-rw-r--r-- | src/libnetdata/line_splitter/README.md | 14 | ||||
-rw-r--r-- | src/libnetdata/line_splitter/line_splitter.c | 78 | ||||
-rw-r--r-- | src/libnetdata/line_splitter/line_splitter.h | 125 |
3 files changed, 217 insertions, 0 deletions
diff --git a/src/libnetdata/line_splitter/README.md b/src/libnetdata/line_splitter/README.md new file mode 100644 index 000000000..b391a492c --- /dev/null +++ b/src/libnetdata/line_splitter/README.md @@ -0,0 +1,14 @@ +<!-- +title: "Log" +custom_edit_url: https://github.com/netdata/netdata/edit/master/src/libnetdata/log/README.md +sidebar_label: "Log" +learn_status: "Published" +learn_topic_type: "Tasks" +learn_rel_path: "Developers/libnetdata" +--> + +# Log + +The netdata log library supports debug, info, error and fatal error logging. +By default we have an access log, an error log and a collectors log. + diff --git a/src/libnetdata/line_splitter/line_splitter.c b/src/libnetdata/line_splitter/line_splitter.c new file mode 100644 index 000000000..6726d9096 --- /dev/null +++ b/src/libnetdata/line_splitter/line_splitter.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "../libnetdata.h" + + +bool line_splitter_reconstruct_line(BUFFER *wb, void *ptr) { + struct line_splitter *spl = ptr; + if(!spl) return false; + + size_t added = 0; + for(size_t i = 0; i < spl->num_words ;i++) { + if(i) buffer_fast_strcat(wb, " ", 1); + + buffer_fast_strcat(wb, "'", 1); + const char *s = get_word(spl->words, spl->num_words, i); + buffer_strcat(wb, s?s:""); + buffer_fast_strcat(wb, "'", 1); + added++; + } + + return added > 0; +} + +inline int pluginsd_isspace(char c) { + switch(c) { + case ' ': + case '\t': + case '\r': + case '\n': + case '=': + return 1; + + default: + return 0; + } +} + +inline int config_isspace(char c) { + switch (c) { + case ' ': + case '\t': + case '\r': + case '\n': + case ',': + return 1; + + default: + return 0; + } +} + +inline int group_by_label_isspace(char c) { + if(c == ',' || c == '|') + return 1; + + return 0; +} + +inline int dyncfg_id_isspace(char c) { + if(c == ':') + return 1; + + return 0; +} + +bool isspace_map_pluginsd[256] = {}; +bool isspace_map_config[256] = {}; +bool isspace_map_group_by_label[256] = {}; +bool isspace_dyncfg_id_map[256] = {}; + +__attribute__((constructor)) void initialize_is_space_arrays(void) { + for(int c = 0; c < 256 ; c++) { + isspace_map_pluginsd[c] = pluginsd_isspace((char) c); + isspace_map_config[c] = config_isspace((char) c); + isspace_map_group_by_label[c] = group_by_label_isspace((char) c); + isspace_dyncfg_id_map[c] = dyncfg_id_isspace((char)c); + } +} diff --git a/src/libnetdata/line_splitter/line_splitter.h b/src/libnetdata/line_splitter/line_splitter.h new file mode 100644 index 000000000..968930410 --- /dev/null +++ b/src/libnetdata/line_splitter/line_splitter.h @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "../libnetdata.h" + +#ifndef NETDATA_LINE_SPLITTER_H +#define NETDATA_LINE_SPLITTER_H + +#define PLUGINSD_MAX_WORDS 30 + +struct line_splitter { + size_t count; // counts number of lines + char *words[PLUGINSD_MAX_WORDS]; // an array of pointers for the words in this line + size_t num_words; // the number of pointers used in this line +}; + +bool line_splitter_reconstruct_line(BUFFER *wb, void *ptr); + +static inline void line_splitter_reset(struct line_splitter *line) { + line->num_words = 0; +} + +int pluginsd_isspace(char c); +int config_isspace(char c); +int group_by_label_isspace(char c); +int dyncfg_id_isspace(char c); + +extern bool isspace_map_pluginsd[256]; +extern bool isspace_map_config[256]; +extern bool isspace_map_group_by_label[256]; +extern bool isspace_dyncfg_id_map[256]; + +static inline size_t quoted_strings_splitter(char *str, char **words, size_t max_words, bool *isspace_map) { + char *s = str, quote = 0; + size_t i = 0; + + // skip all white space + while (unlikely(isspace_map[(uint8_t)*s])) + s++; + + if(unlikely(!*s)) { + words[i] = NULL; + return 0; + } + + // check for quote + if (unlikely(*s == '\'' || *s == '"')) { + quote = *s; // remember the quote + s++; // skip the quote + } + + // store the first word + words[i++] = s; + + // while we have something + while (likely(*s)) { + // if it is an escape + if (unlikely(*s == '\\' && s[1])) { + s += 2; + continue; + } + + // if it is a quote + else if (unlikely(*s == quote)) { + quote = 0; + *s = ' '; + continue; + } + + // if it is a space + else if (unlikely(quote == 0 && isspace_map[(uint8_t)*s])) { + // terminate the word + *s++ = '\0'; + + // skip all white space + while (likely(isspace_map[(uint8_t)*s])) + s++; + + // check for a quote + if (unlikely(*s == '\'' || *s == '"')) { + quote = *s; // remember the quote + s++; // skip the quote + } + + // if we reached the end, stop + if (unlikely(!*s)) + break; + + // store the next word + if (likely(i < max_words)) + words[i++] = s; + else + break; + } + + // anything else + else + s++; + } + + if (likely(i < max_words)) + words[i] = NULL; + + return i; +} + +#define quoted_strings_splitter_query_group_by_label(str, words, max_words) \ + quoted_strings_splitter(str, words, max_words, isspace_map_group_by_label) + +#define quoted_strings_splitter_config(str, words, max_words) \ + quoted_strings_splitter(str, words, max_words, isspace_map_config) + +#define quoted_strings_splitter_pluginsd(str, words, max_words) \ + quoted_strings_splitter(str, words, max_words, isspace_map_pluginsd) + +#define quoted_strings_splitter_dyncfg_id(str, words, max_words) \ + quoted_strings_splitter(str, words, max_words, isspace_dyncfg_id_map) + +static inline char *get_word(char **words, size_t num_words, size_t index) { + if (unlikely(index >= num_words)) + return NULL; + + return words[index]; +} + +#endif //NETDATA_LINE_SPLITTER_H |