@cryptotaxi247 / netdata-1 / commits / 6b2ffc355

New alarm entities (#10041)

Co-authored-by: Joel Hans <joel.g.hans@gmail.com> Co-authored-by: Ilya Mashchenko <ilya@netdata.cloud>

thiagoftsm committed Oct 20, 2020 at 09:00 UTC 6b2ffc355a0d450e4569f3d5412b18d709318986
6 files changed +115 -6
database/rrdcalc.c
+19 -3
@@ -108,10 +108,22 @@ static void rrdsetcalc_link(RRDSET *st, RRDCALC *rc) {
108 }
109 }
110
111 +static inline int rrdcalc_test_additional_restriction(RRDCALC *rc, RRDSET *st){
112 + if (rc->module_match && !simple_pattern_matches(rc->module_pattern, st->module_name))
113 + return 0;
114 +
115 + if (rc->plugin_match && !simple_pattern_matches(rc->plugin_pattern, st->plugin_name))
116 + return 0;
117 +
118 + return 1;
119 +}
120 +
121 static inline int rrdcalc_is_matching_this_rrdset(RRDCALC *rc, RRDSET *st) {
112 - if( (rc->hash_chart == st->hash && !strcmp(rc->chart, st->id)) ||
113 - (rc->hash_chart == st->hash_name && !strcmp(rc->chart, st->name)))
114 - return 1;
122 + if(((rc->hash_chart == st->hash && !strcmp(rc->chart, st->id)) ||
123 + (rc->hash_chart == st->hash_name && !strcmp(rc->chart, st->name))) &&
124 + rrdcalc_test_additional_restriction(rc, st)) {
125 + return 1;
126 + }
127
128 return 0;
129 }
@@ -564,6 +576,10 @@ void rrdcalc_free(RRDCALC *rc) {
576 simple_pattern_free(rc->spdim);
577 freez(rc->labels);
578 simple_pattern_free(rc->splabels);
579 + freez(rc->module_match);
580 + simple_pattern_free(rc->module_pattern);
581 + freez(rc->plugin_match);
582 + simple_pattern_free(rc->plugin_pattern);
583 freez(rc);
584 }
585
database/rrdcalc.h
+7
@@ -45,6 +45,13 @@ struct rrdcalc {
45 char *chart; // the chart id this should be linked to
46 uint32_t hash_chart;
47
48 +
49 + char *plugin_match; //the plugin name that should be linked to
50 + SIMPLE_PATTERN *plugin_pattern;
51 +
52 + char *module_match; //the module name that should be linked to
53 + SIMPLE_PATTERN *module_pattern;
54 +
55 char *source; // the source of this alarm
56 char *units; // the units of the alarm
57 char *info; // a short description of the alarm
database/rrdcalctemplate.c
+22 -3
@@ -44,6 +44,19 @@ static int rrdcalctemplate_is_there_label_restriction(RRDCALCTEMPLATE *rt, RRDH
44 return ret;
45 }
46
47 +static inline int rrdcalctemplate_test_additional_restriction(RRDCALCTEMPLATE *rt, RRDSET *st) {
48 + if (rt->family_pattern && !simple_pattern_matches(rt->family_pattern, st->family))
49 + return 0;
50 +
51 + if (rt->module_pattern && !simple_pattern_matches(rt->module_pattern, st->module_name))
52 + return 0;
53 +
54 + if (rt->plugin_pattern && !simple_pattern_matches(rt->plugin_pattern, st->plugin_name))
55 + return 0;
56 +
57 + return 1;
58 +}
59 +
60 // RRDCALCTEMPLATE management
61 /**
62 * RRDCALC TEMPLATE LINK MATCHING
@@ -51,9 +64,9 @@ static int rrdcalctemplate_is_there_label_restriction(RRDCALCTEMPLATE *rt, RRDH
64 * @param rt is the template used to create the chart.
65 * @param st is the chart where the alarm will be attached.
66 */
54 -void rrdcalctemplate_link_matching_test(RRDCALCTEMPLATE *rt, RRDSET *st, RRDHOST *host ) {
55 - if(rt->hash_context == st->hash_context && !strcmp(rt->context, st->context)
56 - && (!rt->family_pattern || simple_pattern_matches(rt->family_pattern, st->family))) {
67 +void rrdcalctemplate_link_matching_test(RRDCALCTEMPLATE *rt, RRDSET *st, RRDHOST *host) {
68 + if(rt->hash_context == st->hash_context && !strcmp(rt->context, st->context) &&
69 + rrdcalctemplate_test_additional_restriction(rt, st) ) {
70 if (!rrdcalctemplate_is_there_label_restriction(rt, host)) {
71 RRDCALC *rc = rrdcalc_create_from_template(host, rt, st->id);
72 if (unlikely(!rc))
@@ -92,6 +105,12 @@ inline void rrdcalctemplate_free(RRDCALCTEMPLATE *rt) {
105 freez(rt->family_match);
106 simple_pattern_free(rt->family_pattern);
107
108 + freez(rt->plugin_match);
109 + simple_pattern_free(rt->plugin_pattern);
110 +
111 + freez(rt->module_match);
112 + simple_pattern_free(rt->module_pattern);
113 +
114 freez(rt->name);
115 freez(rt->exec);
116 freez(rt->recipient);
database/rrdcalctemplate.h
+6
@@ -21,6 +21,12 @@ struct rrdcalctemplate {
21 char *family_match;
22 SIMPLE_PATTERN *family_pattern;
23
24 + char *plugin_match;
25 + SIMPLE_PATTERN *plugin_pattern;
26 +
27 + char *module_match;
28 + SIMPLE_PATTERN *module_pattern;
29 +
30 char *source; // the source of this alarm
31 char *units; // the units of the alarm
32 char *info; // a short description of the alarm
health/REFERENCE.md
+27
@@ -60,6 +60,8 @@ Netdata parses the following lines. Beneath the table is an in-depth explanation
60 | [`on`](#alarm-line-on) | yes | The chart this alarm should attach to. |
61 | [`os`](#alarm-line-os) | no | Which operating systems to run this chart. |
62 | [`hosts`](#alarm-line-hosts) | no | Which hostnames will run this alarm. |
63 +| [`plugin`](#alarm-line-plugin) | no | Restrict an alarm or template to only a certain plugin. |
64 +| [`module`](#alarm-line-module) | no | Restrict an alarm or template to only a certain module. |
65 | [`families`](#alarm-line-families) | no | Restrict a template to only certain families. |
66 | [`lookup`](#alarm-line-lookup) | yes | The database lookup to find and process metrics for the chart specified through `on`. |
67 | [`calc`](#alarm-line-calc) | yes (see above) | A calculation to apply to the value found via `lookup` or another variable. |
@@ -150,6 +152,31 @@ begin with `redis`.
152 hosts: server1 server2 database* !redis3 redis*
153 ```
154
155 +#### Alarm line `plugin`
156 +
157 +The `plugin` line filters which plugin within the context this alarm should apply to. The value is a space-separated
158 +list of [simple patterns](/libnetdata/simple_pattern/README.md). For example,
159 +you can create a filter for an alarm that applies specifically to `python.d.plugin`:
160 +
161 +```yaml
162 +plugin: python.d.plugin
163 +```
164 +
165 +The `plugin` line is best used with other options like `module`. When used alone, the `plugin` line creates a very
166 +inclusive filter that is unlikely to be of much use in production. See [`module`](#alarm-line-module) for a
167 +comprehensive example using both.
168 +
169 +#### Alarm line `module`
170 +
171 +The `module` line filters which module within the context this alarm should apply to. The value is a space-separated
172 +list of [simple patterns](/libnetdata/simple_pattern/README.md). For
173 +example, you can create an alarm that applies only on the `isc_dhcpd` module started by `python.d.plugin`:
174 +
175 +```yaml
176 +plugin: python.d.plugin
177 +module: isc_dhcpd
178 +```
179 +
180 #### Alarm line `families`
181
182 The `families` line, used only alongside templates, filters which families within the context this alarm should apply
health/health_config.c
+34
@@ -10,6 +10,8 @@
10 #define HEALTH_HOST_KEY "hosts"
11 #define HEALTH_OS_KEY "os"
12 #define HEALTH_FAMILIES_KEY "families"
13 +#define HEALTH_PLUGIN_KEY "plugin"
14 +#define HEALTH_MODULE_KEY "module"
15 #define HEALTH_LOOKUP_KEY "lookup"
16 #define HEALTH_CALC_KEY "calc"
17 #define HEALTH_EVERY_KEY "every"
@@ -485,6 +487,8 @@ static int health_readfile(const char *filename, void *data) {
487 hash_on = 0,
488 hash_host = 0,
489 hash_families = 0,
490 + hash_plugin = 0,
491 + hash_module = 0,
492 hash_calc = 0,
493 hash_green = 0,
494 hash_red = 0,
@@ -510,6 +514,8 @@ static int health_readfile(const char *filename, void *data) {
514 hash_os = simple_uhash(HEALTH_OS_KEY);
515 hash_host = simple_uhash(HEALTH_HOST_KEY);
516 hash_families = simple_uhash(HEALTH_FAMILIES_KEY);
517 + hash_plugin = simple_uhash(HEALTH_PLUGIN_KEY);
518 + hash_module = simple_uhash(HEALTH_MODULE_KEY);
519 hash_calc = simple_uhash(HEALTH_CALC_KEY);
520 hash_lookup = simple_uhash(HEALTH_LOOKUP_KEY);
521 hash_green = simple_uhash(HEALTH_GREEN_KEY);
@@ -811,6 +817,20 @@ static int health_readfile(const char *filename, void *data) {
817 rc->labels = simple_pattern_trim_around_equal(value);
818 rc->splabels = simple_pattern_create(rc->labels, NULL, SIMPLE_PATTERN_EXACT);
819 }
820 + else if(hash == hash_plugin && !strcasecmp(key, HEALTH_PLUGIN_KEY)) {
821 + freez(rc->plugin_match);
822 + simple_pattern_free(rc->plugin_pattern);
823 +
824 + rc->plugin_match = strdupz(value);
825 + rc->plugin_pattern = simple_pattern_create(rc->plugin_match, NULL, SIMPLE_PATTERN_EXACT);
826 + }
827 + else if(hash == hash_module && !strcasecmp(key, HEALTH_MODULE_KEY)) {
828 + freez(rc->module_match);
829 + simple_pattern_free(rc->module_pattern);
830 +
831 + rc->module_match = strdupz(value);
832 + rc->module_pattern = simple_pattern_create(rc->module_match, NULL, SIMPLE_PATTERN_EXACT);
833 + }
834 else {
835 error("Health configuration at line %zu of file '%s' for alarm '%s' has unknown key '%s'.",
836 line, filename, rc->name, key);
@@ -835,6 +855,20 @@ static int health_readfile(const char *filename, void *data) {
855 rt->family_match = strdupz(value);
856 rt->family_pattern = simple_pattern_create(rt->family_match, NULL, SIMPLE_PATTERN_EXACT);
857 }
858 + else if(hash == hash_plugin && !strcasecmp(key, HEALTH_PLUGIN_KEY)) {
859 + freez(rt->plugin_match);
860 + simple_pattern_free(rt->plugin_pattern);
861 +
862 + rt->plugin_match = strdupz(value);
863 + rt->plugin_pattern = simple_pattern_create(rt->plugin_match, NULL, SIMPLE_PATTERN_EXACT);
864 + }
865 + else if(hash == hash_module && !strcasecmp(key, HEALTH_MODULE_KEY)) {
866 + freez(rt->module_match);
867 + simple_pattern_free(rt->module_pattern);
868 +
869 + rt->module_match = strdupz(value);
870 + rt->module_pattern = simple_pattern_create(rt->module_match, NULL, SIMPLE_PATTERN_EXACT);
871 + }
872 else if(hash == hash_lookup && !strcasecmp(key, HEALTH_LOOKUP_KEY)) {
873 health_parse_db_lookup(line, filename, value, &rt->group, &rt->after, &rt->before,
874 &rt->update_every, &rt->options, &rt->dimensions, &rt->foreachdim);