@cryptotaxi247 / netdata-1 / commits / 39de0064d

the dimensions list of API calls now supports netdata simple patterns

Costa Tsaousis (ktsaou) committed Dec 23, 2017 at 14:32 UTC 39de0064d10522690585165c7199cab201d15dfc
17 files changed +81 -73
src/backends.c
+1 -1
@@ -529,7 +529,7 @@ void *backends_main(void *ptr) {
529 long timeoutms = config_get_number(CONFIG_SECTION_BACKEND, "timeout ms", backend_update_every * 2 * 1000);
530 backend_send_names = config_get_boolean(CONFIG_SECTION_BACKEND, "send names instead of ids", backend_send_names);
531
532 - charts_pattern = simple_pattern_create(config_get(CONFIG_SECTION_BACKEND, "send charts matching", "*"), SIMPLE_PATTERN_EXACT);
532 + charts_pattern = simple_pattern_create(config_get(CONFIG_SECTION_BACKEND, "send charts matching", "*"), NULL, SIMPLE_PATTERN_EXACT);
533
534
535 // ------------------------------------------------------------------------
src/freebsd_devstat.c
+1
@@ -221,6 +221,7 @@ int do_kern_devstat(int update_every, usec_t dt) {
221
222 excluded_disks = simple_pattern_create(
223 config_get(CONFIG_SECTION_KERN_DEVSTAT, "disable by default disks matching", DELAULT_EXLUDED_DISKS)
224 + , NULL
225 , SIMPLE_PATTERN_EXACT
226 );
227 }
src/freebsd_getifaddrs.c
+2 -2
@@ -170,8 +170,8 @@ int do_getifaddrs(int update_every, usec_t dt) {
170 CONFIG_BOOLEAN_AUTO);
171
172 excluded_interfaces = simple_pattern_create(
173 - config_get(CONFIG_SECTION_GETIFADDRS, "disable by default interfaces matching",
174 - DELAULT_EXLUDED_INTERFACES)
173 + config_get(CONFIG_SECTION_GETIFADDRS, "disable by default interfaces matching", DELAULT_EXLUDED_INTERFACES)
174 + , NULL
175 , SIMPLE_PATTERN_EXACT
176 );
177 }
src/freebsd_getmntinfo.c
+6 -4
@@ -142,14 +142,16 @@ int do_getmntinfo(int update_every, usec_t dt) {
142
143 excluded_mountpoints = simple_pattern_create(
144 config_get(CONFIG_SECTION_GETMNTINFO, "exclude space metrics on paths",
145 - DELAULT_EXLUDED_PATHS),
146 - SIMPLE_PATTERN_EXACT
145 + DELAULT_EXLUDED_PATHS)
146 + , NULL
147 + , SIMPLE_PATTERN_EXACT
148 );
149
150 excluded_filesystems = simple_pattern_create(
151 config_get(CONFIG_SECTION_GETMNTINFO, "exclude space metrics on filesystems",
151 - DEFAULT_EXCLUDED_FILESYSTEMS),
152 - SIMPLE_PATTERN_EXACT
152 + DEFAULT_EXCLUDED_FILESYSTEMS)
153 + , NULL
154 + , SIMPLE_PATTERN_EXACT
155 );
156 }
157
src/health_config.c
+3 -3
@@ -556,7 +556,7 @@ int health_readfile(RRDHOST *host, const char *path, const char *filename) {
556 }
557 else if(hash == hash_os && !strcasecmp(key, HEALTH_OS_KEY)) {
558 char *os_match = value;
559 - SIMPLE_PATTERN *os_pattern = simple_pattern_create(os_match, SIMPLE_PATTERN_EXACT);
559 + SIMPLE_PATTERN *os_pattern = simple_pattern_create(os_match, NULL, SIMPLE_PATTERN_EXACT);
560
561 if(!simple_pattern_matches(os_pattern, host->os)) {
562 if(rc)
@@ -572,7 +572,7 @@ int health_readfile(RRDHOST *host, const char *path, const char *filename) {
572 }
573 else if(hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY)) {
574 char *host_match = value;
575 - SIMPLE_PATTERN *host_pattern = simple_pattern_create(host_match, SIMPLE_PATTERN_EXACT);
575 + SIMPLE_PATTERN *host_pattern = simple_pattern_create(host_match, NULL, SIMPLE_PATTERN_EXACT);
576
577 if(!simple_pattern_matches(host_pattern, host->hostname)) {
578 if(rc)
@@ -721,7 +721,7 @@ int health_readfile(RRDHOST *host, const char *path, const char *filename) {
721 simple_pattern_free(rt->family_pattern);
722
723 rt->family_match = strdupz(value);
724 - rt->family_pattern = simple_pattern_create(rt->family_match, SIMPLE_PATTERN_EXACT);
724 + rt->family_pattern = simple_pattern_create(rt->family_match, NULL, SIMPLE_PATTERN_EXACT);
725 }
726 else if(hash == hash_lookup && !strcasecmp(key, HEALTH_LOOKUP_KEY)) {
727 health_parse_db_lookup(line, path, filename, value, &rt->group, &rt->after, &rt->before,
src/main.c
+7 -7
@@ -94,12 +94,12 @@ void web_server_config_options(void) {
94 web_x_frame_options = config_get(CONFIG_SECTION_WEB, "x-frame-options response header", "");
95 if(!*web_x_frame_options) web_x_frame_options = NULL;
96
97 - web_allow_connections_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow connections from", "localhost *"), SIMPLE_PATTERN_EXACT);
98 - web_allow_dashboard_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow dashboard from", "localhost *"), SIMPLE_PATTERN_EXACT);
99 - web_allow_badges_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow badges from", "*"), SIMPLE_PATTERN_EXACT);
100 - web_allow_registry_from = simple_pattern_create(config_get(CONFIG_SECTION_REGISTRY, "allow from", "*"), SIMPLE_PATTERN_EXACT);
101 - web_allow_streaming_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow streaming from", "*"), SIMPLE_PATTERN_EXACT);
102 - web_allow_netdataconf_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow netdata.conf from", "localhost fd* 10.* 192.168.* 172.16.* 172.17.* 172.18.* 172.19.* 172.20.* 172.21.* 172.22.* 172.23.* 172.24.* 172.25.* 172.26.* 172.27.* 172.28.* 172.29.* 172.30.* 172.31.*"), SIMPLE_PATTERN_EXACT);
97 + web_allow_connections_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow connections from", "localhost *"), NULL, SIMPLE_PATTERN_EXACT);
98 + web_allow_dashboard_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow dashboard from", "localhost *"), NULL, SIMPLE_PATTERN_EXACT);
99 + web_allow_badges_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow badges from", "*"), NULL, SIMPLE_PATTERN_EXACT);
100 + web_allow_registry_from = simple_pattern_create(config_get(CONFIG_SECTION_REGISTRY, "allow from", "*"), NULL, SIMPLE_PATTERN_EXACT);
101 + web_allow_streaming_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow streaming from", "*"), NULL, SIMPLE_PATTERN_EXACT);
102 + web_allow_netdataconf_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow netdata.conf from", "localhost fd* 10.* 192.168.* 172.16.* 172.17.* 172.18.* 172.19.* 172.20.* 172.21.* 172.22.* 172.23.* 172.24.* 172.25.* 172.26.* 172.27.* 172.28.* 172.29.* 172.30.* 172.31.*"), NULL, SIMPLE_PATTERN_EXACT);
103
104 #ifdef NETDATA_WITH_ZLIB
105 web_enable_gzip = config_get_boolean(CONFIG_SECTION_WEB, "enable gzip compression", web_enable_gzip);
@@ -774,7 +774,7 @@ int main(int argc, char **argv) {
774 size_t len = strlen(needle) + 1;
775 char wildcarded[len];
776
777 - SIMPLE_PATTERN *p = simple_pattern_create(heystack, SIMPLE_PATTERN_EXACT);
777 + SIMPLE_PATTERN *p = simple_pattern_create(heystack, NULL, SIMPLE_PATTERN_EXACT);
778 int ret = simple_pattern_matches_extract(p, needle, wildcarded, len);
779 simple_pattern_free(p);
780
src/plugin_proc_diskspace.c
+6 -4
@@ -96,13 +96,15 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
96 }
97
98 excluded_mountpoints = simple_pattern_create(
99 - config_get(CONFIG_SECTION_DISKSPACE, "exclude space metrics on paths", DELAULT_EXLUDED_PATHS),
100 - mode
99 + config_get(CONFIG_SECTION_DISKSPACE, "exclude space metrics on paths", DELAULT_EXLUDED_PATHS)
100 + , NULL
101 + , mode
102 );
103
104 excluded_filesystems = simple_pattern_create(
104 - config_get(CONFIG_SECTION_DISKSPACE, "exclude space metrics on filesystems", DEFAULT_EXCLUDED_FILESYSTEMS),
105 - SIMPLE_PATTERN_EXACT
105 + config_get(CONFIG_SECTION_DISKSPACE, "exclude space metrics on filesystems", DEFAULT_EXCLUDED_FILESYSTEMS)
106 + , NULL
107 + , SIMPLE_PATTERN_EXACT
108 );
109
110 dict_mountpoints = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
src/proc_diskstats.c
+3 -2
@@ -501,8 +501,9 @@ int do_proc_diskstats(int update_every, usec_t dt) {
501
502 if(unlikely(!excluded_disks)) {
503 excluded_disks = simple_pattern_create(
504 - config_get(CONFIG_SECTION_DISKSTATS, "exclude disks", DEFAULT_EXCLUDED_DISKS),
505 - SIMPLE_PATTERN_EXACT
504 + config_get(CONFIG_SECTION_DISKSTATS, "exclude disks", DEFAULT_EXCLUDED_DISKS)
505 + , NULL
506 + , SIMPLE_PATTERN_EXACT
507 );
508 }
509
src/proc_net_dev.c
+1 -1
@@ -447,7 +447,7 @@ int do_proc_net_dev(int update_every, usec_t dt) {
447 do_compressed = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "compressed packets for all interfaces", CONFIG_BOOLEAN_AUTO);
448 do_events = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "frames, collisions, carrier counters for all interfaces", CONFIG_BOOLEAN_AUTO);
449
450 - disabled_list = simple_pattern_create(config_get("plugin:proc:/proc/net/dev", "disable by default interfaces matching", "lo fireqos* *-ifb"), SIMPLE_PATTERN_EXACT);
450 + disabled_list = simple_pattern_create(config_get("plugin:proc:/proc/net/dev", "disable by default interfaces matching", "lo fireqos* *-ifb"), NULL, SIMPLE_PATTERN_EXACT);
451 }
452
453 if(unlikely(!ff)) {
src/rrd2json.c
+22 -34
@@ -464,47 +464,35 @@ static void rrdr_dump(RRDR *r)
464 void rrdr_disable_not_selected_dimensions(RRDR *r, uint32_t options, const char *dims) {
465 rrdset_check_rdlock(r->st);
466
467 - if(unlikely(!dims || !*dims)) return;
468 -
469 - char b[strlen(dims) + 1];
470 - char *o = b, *tok;
471 - strcpy(o, dims);
467 + if(unlikely(!dims || !*dims || (dims[0] == '*' && dims[1] == '\0'))) return;
468
469 long c, dims_selected = 0, dims_not_hidden_not_zero = 0;
470 RRDDIM *d;
471
476 - // disable all of them
477 - for(c = 0, d = r->st->dimensions; d ;c++, d = d->next)
478 - r->od[c] |= RRDR_HIDDEN;
479 -
480 - while(o && *o && (tok = mystrsep(&o, ",|"))) {
481 - if(!*tok) continue;
482 -
483 - uint32_t hash = simple_hash(tok);
484 -
485 - // find it and enable it
486 - for(c = 0, d = r->st->dimensions; d ;c++, d = d->next) {
487 - if(unlikely((hash == d->hash && !strcmp(d->id, tok)) || (hash == d->hash_name && !strcmp(d->name, tok)))) {
488 -
489 - if(likely(r->od[c] & RRDR_HIDDEN)) {
490 - r->od[c] |= RRDR_SELECTED;
491 - r->od[c] &= ~RRDR_HIDDEN;
492 - dims_selected++;
493 - }
494 -
495 - // since the user needs this dimension
496 - // make it appear as NONZERO, to return it
497 - // even if the dimension has only zeros
498 - // unless option non_zero is set
499 - if(likely(!(options & RRDR_OPTION_NONZERO)))
500 - r->od[c] |= RRDR_NONZERO;
472 + SIMPLE_PATTERN *pattern = simple_pattern_create(dims, ",|\t\r\n\f\v", SIMPLE_PATTERN_EXACT);
473 + for(c = 0, d = r->st->dimensions; d ;c++, d = d->next) {
474 + if(simple_pattern_matches(pattern, d->id) || simple_pattern_matches(pattern, d->name)) {
475 + r->od[c] |= RRDR_SELECTED;
476 + if(unlikely(r->od[c] & RRDR_HIDDEN)) r->od[c] &= ~RRDR_HIDDEN;
477 + dims_selected++;
478 +
479 + // since the user needs this dimension
480 + // make it appear as NONZERO, to return it
481 + // even if the dimension has only zeros
482 + // unless option non_zero is set
483 + if(unlikely(!(options & RRDR_OPTION_NONZERO)))
484 + r->od[c] |= RRDR_NONZERO;
485
502 - // count the visible dimensions
503 - if(likely(r->od[c] & RRDR_NONZERO))
504 - dims_not_hidden_not_zero++;
505 - }
486 + // count the visible dimensions
487 + if(likely(r->od[c] & RRDR_NONZERO))
488 + dims_not_hidden_not_zero++;
489 + }
490 + else {
491 + r->od[c] |= RRDR_HIDDEN;
492 + if(unlikely(r->od[c] & RRDR_SELECTED)) r->od[c] &= ~RRDR_SELECTED;
493 }
494 }
495 + simple_pattern_free(pattern);
496
497 // check if all dimensions are hidden
498 if(unlikely(!dims_not_hidden_not_zero && dims_selected)) {
src/rrdpush.c
+2 -2
@@ -1004,7 +1004,7 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url
1004 }
1005
1006 {
1007 - SIMPLE_PATTERN *key_allow_from = simple_pattern_create(appconfig_get(&stream_config, key, "allow from", "*"), SIMPLE_PATTERN_EXACT);
1007 + SIMPLE_PATTERN *key_allow_from = simple_pattern_create(appconfig_get(&stream_config, key, "allow from", "*"), NULL, SIMPLE_PATTERN_EXACT);
1008 if(key_allow_from) {
1009 if(!simple_pattern_matches(key_allow_from, w->client_ip)) {
1010 simple_pattern_free(key_allow_from);
@@ -1023,7 +1023,7 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url
1023 }
1024
1025 {
1026 - SIMPLE_PATTERN *machine_allow_from = simple_pattern_create(appconfig_get(&stream_config, machine_guid, "allow from", "*"), SIMPLE_PATTERN_EXACT);
1026 + SIMPLE_PATTERN *machine_allow_from = simple_pattern_create(appconfig_get(&stream_config, machine_guid, "allow from", "*"), NULL, SIMPLE_PATTERN_EXACT);
1027 if(machine_allow_from) {
1028 if(!simple_pattern_matches(machine_allow_from, w->client_ip)) {
1029 simple_pattern_free(machine_allow_from);
src/simple_pattern.c
+17 -3
@@ -68,11 +68,25 @@ static inline struct simple_pattern *parse_pattern(char *str, SIMPLE_PREFIX_MODE
68 return m;
69 }
70
71 -SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE default_mode) {
71 +SIMPLE_PATTERN *simple_pattern_create(const char *list, const char *separators, SIMPLE_PREFIX_MODE default_mode) {
72 struct simple_pattern *root = NULL, *last = NULL;
73
74 if(unlikely(!list || !*list)) return root;
75
76 + int isseparator[256] = {
77 + [' '] = 1 // space
78 + , ['\t'] = 1 // tab
79 + , ['\r'] = 1 // carriage return
80 + , ['\n'] = 1 // new line
81 + , ['\f'] = 1 // form feed
82 + , ['\v'] = 1 // vertical tab
83 + };
84 +
85 + if (unlikely(separators && *separators)) {
86 + memset(&isseparator[0], 0, sizeof(isseparator));
87 + while(*separators) isseparator[(unsigned char)*separators++] = 1;
88 + }
89 +
90 char *buf = mallocz(strlen(list) + 1);
91 const char *s = list;
92
@@ -83,7 +97,7 @@ SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE defau
97 char negative = 0;
98
99 // skip all spaces
86 - while(isspace(*s))
100 + while(isseparator[(unsigned char)*s])
101 s++;
102
103 if(*s == '!') {
@@ -103,7 +117,7 @@ SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE defau
117 s++;
118 }
119 else {
106 - if (isspace(*s) && !escape) {
120 + if (isseparator[(unsigned char)*s] && !escape) {
121 s++;
122 break;
123 }
src/simple_pattern.h
+1 -1
@@ -13,7 +13,7 @@ typedef void SIMPLE_PATTERN;
13 // create a simple_pattern from the string given
14 // default_mode is used in cases where EXACT matches, without an asterisk,
15 // should be considered PREFIX matches.
16 -extern SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE default_mode);
16 +extern SIMPLE_PATTERN *simple_pattern_create(const char *list, const char *separators, SIMPLE_PREFIX_MODE default_mode);
17
18 // test if string str is matched from the pattern and fill 'wildcarded' with the parts matched by '*'
19 extern int simple_pattern_matches_extract(SIMPLE_PATTERN *list, const char *str, char *wildcarded, size_t wildcarded_size);
src/statsd.c
+3 -3
@@ -1139,7 +1139,7 @@ int statsd_readfile(const char *path, const char *filename) {
1139 }
1140 else if (!strcmp(name, "metrics")) {
1141 simple_pattern_free(app->metrics);
1142 - app->metrics = simple_pattern_create(value, SIMPLE_PATTERN_EXACT);
1142 + app->metrics = simple_pattern_create(value, NULL, SIMPLE_PATTERN_EXACT);
1143 }
1144 else if (!strcmp(name, "private charts")) {
1145 if (!strcmp(value, "yes") || !strcmp(value, "on"))
@@ -1249,7 +1249,7 @@ int statsd_readfile(const char *path, const char *filename) {
1249 );
1250
1251 if(pattern)
1252 - dim->metric_pattern = simple_pattern_create(dim->metric, SIMPLE_PATTERN_EXACT);
1252 + dim->metric_pattern = simple_pattern_create(dim->metric, NULL, SIMPLE_PATTERN_EXACT);
1253 }
1254 else {
1255 error("STATSD: ignoring line %zu ('%s') of file '%s/%s'. Unknown keyword for the [%s] section.", line, name, path, filename, chart->id);
@@ -1995,7 +1995,7 @@ void *statsd_main(void *ptr) {
1995 statsd.recvmmsg_size = (size_t)config_get_number(CONFIG_SECTION_STATSD, "udp messages to process at once", (long long)statsd.recvmmsg_size);
1996 #endif
1997
1998 - statsd.charts_for = simple_pattern_create(config_get(CONFIG_SECTION_STATSD, "create private charts for metrics matching", "*"), SIMPLE_PATTERN_EXACT);
1998 + statsd.charts_for = simple_pattern_create(config_get(CONFIG_SECTION_STATSD, "create private charts for metrics matching", "*"), NULL, SIMPLE_PATTERN_EXACT);
1999 statsd.max_private_charts = (size_t)config_get_number(CONFIG_SECTION_STATSD, "max private charts allowed", (long long)statsd.max_private_charts);
2000 statsd.max_private_charts_hard = (size_t)config_get_number(CONFIG_SECTION_STATSD, "max private charts hard limit", (long long)statsd.max_private_charts * 5);
2001 statsd.private_charts_memory_mode = rrd_memory_mode_id(config_get(CONFIG_SECTION_STATSD, "private charts memory mode", rrd_memory_mode_name(default_rrd_memory_mode)));
src/sys_fs_cgroup.c
+4 -4
@@ -175,7 +175,7 @@ void read_cgroup_plugin_configuration() {
175 " !/systemd "
176 " !/user "
177 " * " // enable anything else
178 - ), SIMPLE_PATTERN_EXACT);
178 + ), NULL, SIMPLE_PATTERN_EXACT);
179
180 enabled_cgroup_paths = simple_pattern_create(
181 config_get("plugin:cgroups", "search for cgroups in subpaths matching",
@@ -189,7 +189,7 @@ void read_cgroup_plugin_configuration() {
189 " !/user.slice "
190 " !/lxc/*/* " // #2161 #2649
191 " * "
192 - ), SIMPLE_PATTERN_EXACT);
192 + ), NULL, SIMPLE_PATTERN_EXACT);
193
194 snprintfz(filename, FILENAME_MAX, "%s/cgroup-name.sh", netdata_configured_plugins_dir);
195 cgroups_rename_script = config_get("plugin:cgroups", "script to get cgroup names", filename);
@@ -215,14 +215,14 @@ void read_cgroup_plugin_configuration() {
215 " *qemu* "
216 " *.libvirt-qemu " // #3010
217 " * "
218 - ), SIMPLE_PATTERN_EXACT);
218 + ), NULL, SIMPLE_PATTERN_EXACT);
219
220 if(cgroup_enable_systemd_services) {
221 systemd_services_cgroups = simple_pattern_create(
222 config_get("plugin:cgroups", "cgroups to match as systemd services",
223 " !/system.slice/*/*.service "
224 " /system.slice/*.service "
225 - ), SIMPLE_PATTERN_EXACT);
225 + ), NULL, SIMPLE_PATTERN_EXACT);
226 }
227
228 mountinfo_free(root);
web/netdata-swagger.json
+1 -1
@@ -258,7 +258,7 @@
258 {
259 "name": "dimension",
260 "in": "query",
261 - "description": "zero, one or more dimension ids, as returned by the /chart call.",
261 + "description": "zero, one or more dimension ids or names, as returned by the /chart call, separated with comma or pipe. Netdata simple patterns are supported.",
262 "required": false,
263 "type": "array",
264 "items": {
web/netdata-swagger.yaml
+1 -1
@@ -56,7 +56,7 @@ paths:
56 default: system.cpu
57 - name: dimension
58 in: query
59 - description: 'zero, one or more dimension ids, as returned by the /chart call.'
59 + description: 'zero, one or more dimension ids or names, as returned by the /chart call, separated with comma or pipe. Netdata simple patterns are supported.'
60 required: false
61 type: array
62 items: