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: