]> arthur.barton.de Git - netdata.git/commitdiff
allow alarm templates to match patterns of chart families; fixes #1571
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sun, 15 Jan 2017 16:16:41 +0000 (18:16 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sun, 15 Jan 2017 16:16:41 +0000 (18:16 +0200)
src/health.c
src/health.h
src/main.c
src/plugin_proc_diskspace.c
src/proc_net_dev.c
src/simple_pattern.c
src/simple_pattern.h
src/sys_fs_cgroup.c

index ebd3ff612ce6202444bced96c1e4f8af98633496..31fe8e06c48fa85c8780d63240cf72fa4e13f48d 100755 (executable)
@@ -1400,7 +1400,8 @@ void rrdcalctemplate_link_matching(RRDSET *st) {
     RRDCALCTEMPLATE *rt;
 
     for(rt = st->rrdhost->templates; rt ; rt = rt->next) {
-        if(rt->hash_context == st->hash_context && !strcmp(rt->context, st->context)) {
+        if(rt->hash_context == st->hash_context && !strcmp(rt->context, st->context)
+                && (!rt->family_pattern || simple_pattern_matches(rt->family_pattern, st->family))) {
             RRDCALC *rc = rrdcalc_create(st->rrdhost, rt, st->id);
             if(unlikely(!rc))
                 error("Health tried to create alarm from template '%s', but it failed", rt->name);
@@ -1436,6 +1437,9 @@ static inline void rrdcalctemplate_free(RRDHOST *host, RRDCALCTEMPLATE *rt) {
     expression_free(rt->warning);
     expression_free(rt->critical);
 
+    freez(rt->family_match);
+    simple_pattern_free(rt->family_pattern);
+
     freez(rt->name);
     freez(rt->exec);
     freez(rt->recipient);
@@ -1455,6 +1459,7 @@ static inline void rrdcalctemplate_free(RRDHOST *host, RRDCALCTEMPLATE *rt) {
 #define HEALTH_ALARM_KEY "alarm"
 #define HEALTH_TEMPLATE_KEY "template"
 #define HEALTH_ON_KEY "on"
+#define HEALTH_FAMILIES_KEY "families"
 #define HEALTH_LOOKUP_KEY "lookup"
 #define HEALTH_CALC_KEY "calc"
 #define HEALTH_EVERY_KEY "every"
@@ -1825,13 +1830,14 @@ static inline void strip_quotes(char *s) {
 int health_readfile(const char *path, const char *filename) {
     debug(D_HEALTH, "Health configuration reading file '%s/%s'", path, filename);
 
-    static uint32_t hash_alarm = 0, hash_template = 0, hash_on = 0, hash_calc = 0, hash_green = 0, hash_red = 0, hash_warn = 0, hash_crit = 0, hash_exec = 0, hash_every = 0, hash_lookup = 0, hash_units = 0, hash_info = 0, hash_recipient = 0, hash_delay = 0;
+    static uint32_t hash_alarm = 0, hash_template = 0, hash_on = 0, hash_families = 0, hash_calc = 0, hash_green = 0, hash_red = 0, hash_warn = 0, hash_crit = 0, hash_exec = 0, hash_every = 0, hash_lookup = 0, hash_units = 0, hash_info = 0, hash_recipient = 0, hash_delay = 0;
     char buffer[HEALTH_CONF_MAX_LINE + 1];
 
     if(unlikely(!hash_alarm)) {
         hash_alarm = simple_uhash(HEALTH_ALARM_KEY);
         hash_template = simple_uhash(HEALTH_TEMPLATE_KEY);
         hash_on = simple_uhash(HEALTH_ON_KEY);
+        hash_families = simple_uhash(HEALTH_FAMILIES_KEY);
         hash_calc = simple_uhash(HEALTH_CALC_KEY);
         hash_lookup = simple_uhash(HEALTH_LOOKUP_KEY);
         hash_green = simple_uhash(HEALTH_GREEN_KEY);
@@ -1951,7 +1957,7 @@ int health_readfile(const char *path, const char *filename) {
                 if(rc->chart) {
                     if(strcmp(rc->chart, value))
                         error("Health configuration at line %zu of file '%s/%s' for alarm '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
-                             line, path, filename, rc->name, key, rc->chart, value, value);
+                                line, path, filename, rc->name, key, rc->chart, value, value);
 
                     freez(rc->chart);
                 }
@@ -2066,17 +2072,23 @@ int health_readfile(const char *path, const char *filename) {
                 if(rt->context) {
                     if(strcmp(rt->context, value))
                         error("Health configuration at line %zu of file '%s/%s' for template '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
-                             line, path, filename, rt->name, key, rt->context, value, value);
+                                line, path, filename, rt->name, key, rt->context, value, value);
 
                     freez(rt->context);
                 }
                 rt->context = tabs2spaces(strdupz(value));
                 rt->hash_context = simple_hash(rt->context);
             }
+            else if(hash == hash_families && !strcasecmp(key, HEALTH_FAMILIES_KEY)) {
+                freez(rt->family_match);
+                simple_pattern_free(rt->family_pattern);
+
+                rt->family_match = tabs2spaces(strdupz(value));
+                rt->family_pattern = simple_pattern_create(rt->family_match, SIMPLE_PATTERN_EXACT);
+            }
             else if(hash == hash_lookup && !strcasecmp(key, HEALTH_LOOKUP_KEY)) {
                 health_parse_db_lookup(line, path, filename, value, &rt->group, &rt->after, &rt->before,
-                                       &rt->update_every,
-                                       &rt->options, &rt->dimensions);
+                                       &rt->update_every, &rt->options, &rt->dimensions);
             }
             else if(hash == hash_every && !strcasecmp(key, HEALTH_EVERY_KEY)) {
                 if(!health_parse_duration(value, &rt->update_every))
index 5b4d8538254447ede04abfa03a83422fa091de78..79831d4fc563257a24ce26cd7e9f42bad1036649 100644 (file)
@@ -232,6 +232,9 @@ typedef struct rrdcalctemplate {
     char *context;
     uint32_t hash_context;
 
+    char *family_match;
+    SIMPLE_PATTERN *family_pattern;
+
     char *source;                   // the source of this alarm
     char *units;                    // the units of the alarm
     char *info;                     // a short description of the alarm
index 5bfce7706972795389ebbf424224ded372a5c28c..26bc49f5e6027eb1c69234396b63b33760bdba25 100644 (file)
@@ -478,9 +478,10 @@ int main(int argc, char **argv)
                             const char *heystack = argv[optind];
                             const char *needle = argv[optind + 1];
 
-                            NETDATA_SIMPLE_PATTERN *p = netdata_simple_pattern_list_create(heystack, NETDATA_SIMPLE_PATTERN_MODE_EXACT);
-                            int ret = netdata_simple_pattern_list_matches(p, needle);
-                            netdata_simple_pattern_free(p);
+                            SIMPLE_PATTERN *p = simple_pattern_create(heystack
+                                                                      , SIMPLE_PATTERN_EXACT);
+                            int ret = simple_pattern_matches(p, needle);
+                            simple_pattern_free(p);
 
                             if(ret) {
                                 fprintf(stdout, "RESULT: MATCHED - pattern '%s' matches '%s'\n", heystack, needle);
index 8b6bedfedd35a9851951ce382e4e6a4bad947199..7043385994f84b6137d1cbfae4fdf643d8d261d5 100644 (file)
@@ -32,23 +32,23 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
     const char *disk = mi->persistent_id;
 
     static DICTIONARY *mount_points = NULL;
-    static NETDATA_SIMPLE_PATTERN *excluded_mountpoints = NULL;
+    static SIMPLE_PATTERN *excluded_mountpoints = NULL;
     int do_space, do_inodes;
 
     if(unlikely(!mount_points)) {
         const char *s;
-        NETDATA_SIMPLE_PREFIX_MODE mode = NETDATA_SIMPLE_PATTERN_MODE_EXACT;
+        SIMPLE_PREFIX_MODE mode = SIMPLE_PATTERN_EXACT;
 
         if(config_exists("plugin:proc:/proc/diskstats", "exclude space metrics on paths") && !config_exists("plugin:proc:diskspace", "exclude space metrics on paths")) {
             // the config exists in the old section
             s = config_get("plugin:proc:/proc/diskstats", "exclude space metrics on paths", DELAULT_EXLUDED_PATHS);
-            mode = NETDATA_SIMPLE_PATTERN_MODE_PREFIX;
+            mode = SIMPLE_PATTERN_PREFIX;
         }
         else
             s = config_get("plugin:proc:diskspace", "exclude space metrics on paths", DELAULT_EXLUDED_PATHS);
 
         mount_points = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
-        excluded_mountpoints = netdata_simple_pattern_list_create(s, mode);
+        excluded_mountpoints = simple_pattern_create(s, mode);
     }
 
     struct mount_point_metadata *m = dictionary_get(mount_points, mi->mount_point);
@@ -59,7 +59,7 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
         int def_space = config_get_boolean_ondemand("plugin:proc:diskspace", "space usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
         int def_inodes = config_get_boolean_ondemand("plugin:proc:diskspace", "inodes usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
 
-        if(unlikely(netdata_simple_pattern_list_matches(excluded_mountpoints, mi->mount_point))) {
+        if(unlikely(simple_pattern_matches(excluded_mountpoints, mi->mount_point))) {
             def_space = CONFIG_ONDEMAND_NO;
             def_inodes = CONFIG_ONDEMAND_NO;
         }
index 6813d5e56d00608e075c4d987065550d300be510..a330010abe40110a2959851a461a55617af126df 100644 (file)
@@ -112,7 +112,7 @@ static struct netdev *get_netdev(const char *name) {
 int do_proc_net_dev(int update_every, usec_t dt) {
     (void)dt;
 
-    static NETDATA_SIMPLE_PATTERN *disabled_list = NULL;
+    static SIMPLE_PATTERN *disabled_list = NULL;
     static procfile *ff = NULL;
     static int enable_new_interfaces = -1;
     static int do_bandwidth = -1, do_packets = -1, do_errors = -1, do_drops = -1, do_fifo = -1, do_compressed = -1, do_events = -1;
@@ -128,7 +128,9 @@ int do_proc_net_dev(int update_every, usec_t dt) {
         do_compressed   = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "compressed packets for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
         do_events       = config_get_boolean_ondemand("plugin:proc:/proc/net/dev", "frames, collisions, carrier counters for all interfaces", CONFIG_ONDEMAND_ONDEMAND);
 
-        disabled_list = netdata_simple_pattern_list_create(config_get("plugin:proc:/proc/net/dev", "disable by default interfaces matching", "lo fireqos* *-ifb"), NETDATA_SIMPLE_PATTERN_MODE_EXACT);
+        disabled_list = simple_pattern_create(
+                config_get("plugin:proc:/proc/net/dev", "disable by default interfaces matching", "lo fireqos* *-ifb")
+                , SIMPLE_PATTERN_EXACT);
     }
 
     if(unlikely(!ff)) {
@@ -157,7 +159,7 @@ int do_proc_net_dev(int update_every, usec_t dt) {
             d->enabled = enable_new_interfaces;
 
             if(d->enabled)
-                d->enabled = !netdata_simple_pattern_list_matches(disabled_list, d->name);
+                d->enabled = !simple_pattern_matches(disabled_list, d->name);
 
             char var_name[512 + 1];
             snprintfz(var_name, 512, "plugin:proc:/proc/net/dev:%s", d->name);
index 135366efc9ec747130764fed95ba39b42ea462d9..7e4424297f86c2c311f58a57dedaa6221dddf144 100644 (file)
@@ -4,7 +4,7 @@ struct simple_pattern {
     const char *match;
     size_t len;
 
-    NETDATA_SIMPLE_PREFIX_MODE mode;
+    SIMPLE_PREFIX_MODE mode;
     char negative;
 
     struct simple_pattern *child;
@@ -12,13 +12,8 @@ struct simple_pattern {
     struct simple_pattern *next;
 };
 
-static inline struct simple_pattern *parse_pattern(const char *str, NETDATA_SIMPLE_PREFIX_MODE default_mode) {
-    /*
-     * DEBUG
-    info(">>>> PARSE: '%s'", str);
-     */
-
-    NETDATA_SIMPLE_PREFIX_MODE mode;
+static inline struct simple_pattern *parse_pattern(const char *str, SIMPLE_PREFIX_MODE default_mode) {
+    SIMPLE_PREFIX_MODE mode;
     struct simple_pattern *child = NULL;
 
     char *buf = strdupz(str);
@@ -43,15 +38,15 @@ static inline struct simple_pattern *parse_pattern(const char *str, NETDATA_SIMP
     if(len >= 2 && *s == '*' && s[len - 1] == '*') {
         s[len - 1] = '\0';
         s++;
-        mode = NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING;
+        mode = SIMPLE_PATTERN_SUBSTRING;
     }
     else if(len >= 1 && *s == '*') {
         s++;
-        mode = NETDATA_SIMPLE_PATTERN_MODE_SUFFIX;
+        mode = SIMPLE_PATTERN_SUFFIX;
     }
     else if(len >= 1 && s[len - 1] == '*') {
         s[len - 1] = '\0';
-        mode = NETDATA_SIMPLE_PATTERN_MODE_PREFIX;
+        mode = SIMPLE_PATTERN_PREFIX;
     }
     else
         mode = default_mode;
@@ -64,30 +59,17 @@ static inline struct simple_pattern *parse_pattern(const char *str, NETDATA_SIMP
         m->mode = mode;
     }
     else {
-        m->mode = NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING;
+        m->mode = SIMPLE_PATTERN_SUBSTRING;
     }
 
     m->child = child;
 
     freez(buf);
 
-    /*
-     * DEBUG
-    info("PATTERN '%s' is composed by", str);
-    struct simple_pattern *p;
-    for(p = m; p ; p = p->child)
-        info(">>>> COMPONENT: '%s%s%s' (len %zu type %u)",
-            (p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUFFIX || p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
-            p->match,
-            (p->mode == NETDATA_SIMPLE_PATTERN_MODE_PREFIX || p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
-            p->len,
-            p->mode);
-     */
-
     return m;
 }
 
-NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NETDATA_SIMPLE_PREFIX_MODE default_mode) {
+SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE default_mode) {
     struct simple_pattern *root = NULL, *last = NULL;
 
     if(unlikely(!list || !*list)) return root;
@@ -141,25 +123,15 @@ NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NET
     }
 
     freez(buf);
-    return (NETDATA_SIMPLE_PATTERN *)root;
+    return (SIMPLE_PATTERN *)root;
 }
 
 static inline int match_pattern(struct simple_pattern *m, const char *str, size_t len) {
-    /*
-     * DEBUG
-     *
-    info("CHECK string '%s' (len %zu) with pattern '%s%s%s' (len %zu type %u)", str, len,
-            (m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUFFIX || m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
-            m->match,
-            (m->mode == NETDATA_SIMPLE_PATTERN_MODE_PREFIX || m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
-            m->len, m->mode);
-    */
-
     char *s;
 
     if(m->len <= len) {
         switch(m->mode) {
-            case NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING:
+            case SIMPLE_PATTERN_SUBSTRING:
                 if(!m->len) return 1;
                 if((s = strstr(str, m->match))) {
                     if(!m->child) return 1;
@@ -167,21 +139,21 @@ static inline int match_pattern(struct simple_pattern *m, const char *str, size_
                 }
                 break;
 
-            case NETDATA_SIMPLE_PATTERN_MODE_PREFIX:
+            case SIMPLE_PATTERN_PREFIX:
                 if(unlikely(strncmp(str, m->match, m->len) == 0)) {
                     if(!m->child) return 1;
                     return match_pattern(m->child, &str[m->len], len - m->len);
                 }
                 break;
 
-            case NETDATA_SIMPLE_PATTERN_MODE_SUFFIX:
+            case SIMPLE_PATTERN_SUFFIX:
                 if(unlikely(strcmp(&str[len - m->len], m->match) == 0)) {
                     if(!m->child) return 1;
                     return 0;
                 }
                 break;
 
-            case NETDATA_SIMPLE_PATTERN_MODE_EXACT:
+            case SIMPLE_PATTERN_EXACT:
             default:
                 if(unlikely(strcmp(str, m->match) == 0)) {
                     if(!m->child) return 1;
@@ -194,7 +166,7 @@ static inline int match_pattern(struct simple_pattern *m, const char *str, size_
     return 0;
 }
 
-int netdata_simple_pattern_list_matches(NETDATA_SIMPLE_PATTERN *list, const char *str) {
+int simple_pattern_matches(SIMPLE_PATTERN *list, const char *str) {
     struct simple_pattern *m, *root = (struct simple_pattern *)list;
 
     if(unlikely(!root)) return 0;
@@ -202,25 +174,6 @@ int netdata_simple_pattern_list_matches(NETDATA_SIMPLE_PATTERN *list, const char
     size_t len = strlen(str);
     for(m = root; m ; m = m->next)
         if(match_pattern(m, str, len)) {
-            /*
-             * DEBUG
-             *
-            info("MATCHED string '%s' (len %zu) with pattern '%s%s%s' (len %zu type %u)", str, len,
-                    (m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUFFIX || m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
-                    m->match,
-                    (m->mode == NETDATA_SIMPLE_PATTERN_MODE_PREFIX || m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
-                    m->len, m->mode);
-
-            struct simple_pattern *p;
-            for(p = m; p ; p = p->child)
-                info(">>>> MATCHED COMPONENT: '%s%s%s' (len %zu type %u)",
-                        (p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUFFIX || p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
-                        p->match,
-                        (p->mode == NETDATA_SIMPLE_PATTERN_MODE_PREFIX || p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
-                        p->len,
-                        p->mode);
-            */
-
             if(m->negative) return 0;
             return 1;
         }
@@ -237,6 +190,8 @@ static inline void free_pattern(struct simple_pattern *m) {
     freez(m);
 }
 
-void netdata_simple_pattern_free(NETDATA_SIMPLE_PATTERN *list) {
+void simple_pattern_free(SIMPLE_PATTERN *list) {
+    if(!list) return;
+
     free_pattern(((struct simple_pattern *)list)->next);
 }
index a1a6a396cced72ca664f226ba6acc4f4f612193b..3768c5089757f59c9c65a0953f048b3d484c1933 100644 (file)
@@ -2,15 +2,24 @@
 #define NETDATA_SIMPLE_PATTERN_H
 
 typedef enum {
-    NETDATA_SIMPLE_PATTERN_MODE_EXACT,
-    NETDATA_SIMPLE_PATTERN_MODE_PREFIX,
-    NETDATA_SIMPLE_PATTERN_MODE_SUFFIX,
-    NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING
-} NETDATA_SIMPLE_PREFIX_MODE;
+    SIMPLE_PATTERN_EXACT,
+    SIMPLE_PATTERN_PREFIX,
+    SIMPLE_PATTERN_SUFFIX,
+    SIMPLE_PATTERN_SUBSTRING
+} SIMPLE_PREFIX_MODE;
 
-typedef void NETDATA_SIMPLE_PATTERN;
-extern NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NETDATA_SIMPLE_PREFIX_MODE default_mode);
-extern int netdata_simple_pattern_list_matches(NETDATA_SIMPLE_PATTERN *list, const char *str);
-extern void netdata_simple_pattern_free(NETDATA_SIMPLE_PATTERN *list);
+typedef void SIMPLE_PATTERN;
+
+// create a simple_pattern from the string given
+// default_mode is used in cases where EXACT matches, without an asterisk,
+// should be considered PREFIX matches.
+extern SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE default_mode);
+
+// test if string str is matched from the pattern
+extern int simple_pattern_matches(SIMPLE_PATTERN *list, const char *str);
+
+// free a simple_pattern that was created with simple_pattern_create()
+// list can be NULL, in which case, this does nothing.
+extern void simple_pattern_free(SIMPLE_PATTERN *list);
 
 #endif //NETDATA_SIMPLE_PATTERN_H
index cc338dccfd0f81ae7f34df7e444c9e56f2db521a..dccd4264bdadb8de7e712853e39e38a54f762080 100644 (file)
@@ -22,10 +22,10 @@ static int cgroup_root_count = 0;
 static int cgroup_root_max = 500;
 static int cgroup_max_depth = 0;
 
-static NETDATA_SIMPLE_PATTERN *disabled_cgroups_patterns = NULL;
-static NETDATA_SIMPLE_PATTERN *disabled_cgroup_paths = NULL;
-static NETDATA_SIMPLE_PATTERN *disabled_cgroup_renames = NULL;
-static NETDATA_SIMPLE_PATTERN *systemd_services_cgroups = NULL;
+static SIMPLE_PATTERN *disabled_cgroups_patterns = NULL;
+static SIMPLE_PATTERN *disabled_cgroup_paths = NULL;
+static SIMPLE_PATTERN *disabled_cgroup_renames = NULL;
+static SIMPLE_PATTERN *systemd_services_cgroups = NULL;
 
 static char *cgroups_rename_script = PLUGINS_DIR "/cgroup-name.sh";
 
@@ -93,9 +93,8 @@ void read_cgroup_plugin_configuration() {
 
     cgroup_enable_new_cgroups_detected_at_runtime = config_get_boolean("plugin:cgroups", "enable new cgroups detected at run time", cgroup_enable_new_cgroups_detected_at_runtime);
 
-    disabled_cgroups_patterns = netdata_simple_pattern_list_create(
-            config_get("plugin:cgroups", "disable by default cgroups matching",
-                    " *.mount "
+    disabled_cgroups_patterns = simple_pattern_create(
+            config_get("plugin:cgroups", "disable by default cgroups matching", " *.mount "
                     " *.partition "
                     " *.service "
                     " *.slice "
@@ -115,23 +114,22 @@ void read_cgroup_plugin_configuration() {
                     " /systemd "
                     " /user "
                     " /user.slice "
-            ), NETDATA_SIMPLE_PATTERN_MODE_EXACT);
-
-    disabled_cgroup_paths = netdata_simple_pattern_list_create(
-            config_get("plugin:cgroups", "do not search for cgroups in paths matching",
-                    " *-qemu "                             //  #345
-                    " /init.scope "
-                    " /system "
-                    " /systemd "
-                    " /user "
-                    " /user.slice "
-            ), NETDATA_SIMPLE_PATTERN_MODE_EXACT);
+            ), SIMPLE_PATTERN_EXACT);
+
+    disabled_cgroup_paths = simple_pattern_create(
+            config_get("plugin:cgroups", "do not search for cgroups in paths matching"
+                       , " *-qemu "                             //  #345
+                            " /init.scope "
+                            " /system "
+                            " /systemd "
+                            " /user "
+                            " /user.slice "
+            ), SIMPLE_PATTERN_EXACT);
 
     cgroups_rename_script = config_get("plugin:cgroups", "script to get cgroup names", cgroups_rename_script);
 
-    disabled_cgroup_renames = netdata_simple_pattern_list_create(
-            config_get("plugin:cgroups", "do not run script to rename cgroups matching",
-                    " / "
+    disabled_cgroup_renames = simple_pattern_create(
+            config_get("plugin:cgroups", "do not run script to rename cgroups matching", " / "
                     " *.mount "
                     " *.partition "
                     " *.scope "
@@ -139,13 +137,13 @@ void read_cgroup_plugin_configuration() {
                     " *.slice "
                     " *.swap "
                     " *.user "
-            ), NETDATA_SIMPLE_PATTERN_MODE_EXACT);
+            ), SIMPLE_PATTERN_EXACT);
 
     if(cgroup_enable_systemd_services)
-        systemd_services_cgroups = netdata_simple_pattern_list_create(
-                config_get("plugin:cgroups", "cgroups to match as systemd services",
-                        " !/system.slice/*/*.service /system.slice/*.service "
-                ), NETDATA_SIMPLE_PATTERN_MODE_EXACT);
+        systemd_services_cgroups = simple_pattern_create(
+                config_get("plugin:cgroups", "cgroups to match as systemd services"
+                           , " !/system.slice/*/*.service /system.slice/*.service "
+                ), SIMPLE_PATTERN_EXACT);
 
     mountinfo_free(root);
 }
@@ -776,7 +774,7 @@ struct cgroup *cgroup_add(const char *id) {
         return NULL;
     }
 
-    int def = netdata_simple_pattern_list_matches(disabled_cgroups_patterns, id)?0:cgroup_enable_new_cgroups_detected_at_runtime;
+    int def = simple_pattern_matches(disabled_cgroups_patterns, id)?0:cgroup_enable_new_cgroups_detected_at_runtime;
     struct cgroup *cg = callocz(1, sizeof(struct cgroup));
 
     cg->id = strdupz(id);
@@ -799,8 +797,8 @@ struct cgroup *cgroup_add(const char *id) {
     cgroup_root_count++;
 
     // fix the chart_id and title by calling the external script
-    if(!netdata_simple_pattern_list_matches(disabled_cgroup_renames, cg->id) &&
-       !netdata_simple_pattern_list_matches(disabled_cgroup_renames, cg->chart_id)) {
+    if(!simple_pattern_matches(disabled_cgroup_renames, cg->id) &&
+       !simple_pattern_matches(disabled_cgroup_renames, cg->chart_id)) {
 
         cgroup_get_chart_name(cg);
 
@@ -813,8 +811,8 @@ struct cgroup *cgroup_add(const char *id) {
 
     // check if this cgroup should be a systemd service
     if(cgroup_enable_systemd_services) {
-        if(netdata_simple_pattern_list_matches(systemd_services_cgroups, cg->id) ||
-           netdata_simple_pattern_list_matches(systemd_services_cgroups, cg->chart_id)) {
+        if(simple_pattern_matches(systemd_services_cgroups, cg->id) ||
+                simple_pattern_matches(systemd_services_cgroups, cg->chart_id)) {
             debug(D_CGROUP, "cgroup '%s' with chart id '%s' (title: '%s') matches systemd services cgroups", cg->id, cg->chart_id, cg->chart_title);
 
             char buffer[CGROUP_CHARTID_LINE_MAX + 1];
@@ -1001,7 +999,7 @@ int find_dir_in_subdirs(const char *base, const char *this, void (*callback)(con
 
                 // do not decent in directories we are not interested
                 int def = 1;
-                if(netdata_simple_pattern_list_matches(disabled_cgroup_paths, r))
+                if(simple_pattern_matches(disabled_cgroup_paths, r))
                     def = 0;
 
                 // we check for this option here