summaryrefslogtreecommitdiffstats
path: root/health
diff options
context:
space:
mode:
authorAndrew Moss <1043609+amoss@users.noreply.github.com>2019-12-16 15:12:00 +0100
committerGitHub <noreply@github.com>2019-12-16 15:12:00 +0100
commitc8c72f18a6a8fd09d3b6284e49525396b24e8395 (patch)
tree5b9aeaea7d72e1d1029d45f67c0a5f130ecc2f80 /health
parentc4bb3d2642ab34e6aca912b22e55aed52f84e974 (diff)
Labels issues (#7515)
Initial work on host labels from the dedicated branch. Includes work for issues #7096, #7400, #7411, #7369, #7410, #7458, #7459, #7412 and #7408 by @vlvkobal, @thiagoftsm, @cakrit and @amoss.
Diffstat (limited to 'health')
-rw-r--r--health/REFERENCE.md43
-rw-r--r--health/health.c5
-rw-r--r--health/health_config.c31
-rw-r--r--health/health_json.c6
4 files changed, 83 insertions, 2 deletions
diff --git a/health/REFERENCE.md b/health/REFERENCE.md
index 7136ba0b5b..886942c869 100644
--- a/health/REFERENCE.md
+++ b/health/REFERENCE.md
@@ -68,6 +68,7 @@ Netdata parses the following lines. Beneath the table is an in-depth explanation
| [`delay`](#alarm-line-delay) | no | Optional hysteresis settings to prevent floods of notifications. |
| [`repeat`](#alarm-line-repeat) | no | The interval for sending notifications when an alarm is in WARNING or CRITICAL mode. |
| [`option`](#alarm-line-option) | no | Add an option to not clear alarms. |
+| [`label`](#alarm-line-label) | no | List of labels present on a host. |
The `alarm` or `template` line must be the first line of any entity.
@@ -370,6 +371,48 @@ increasing. Eventually, the comparison will find the averages in the two time-fr
However, the issue was not resolved, it's just a matter of the newer data "polluting" the old. For such alarms, it's a
good idea to tell Netdata to not clear the notification, by using the `no-clear-notification` option.
+#### Alarm line `label`
+
+Defines the list of labels expected on a host. For example, let's suppose that `netdata.conf` is configured with the
+following labels:
+
+```yaml
+[host labels]
+ installed = 20191211
+ room = server
+```
+
+And more labels in `netdata.conf` for workstations:
+
+```yaml
+[host labels]
+ installed = 201705
+ room = workstation
+```
+
+By defining labels inside of `netdata.conf`, you can now apply labels to alarms. For example, you can add the following
+line to any alarms you'd like to apply to hosts that have the label `room = server`.
+
+```yaml
+label: room = server
+```
+
+You can also combine labels when applying them to alarms. For example, if you want to raise a specific alarm only for hosts
+inside a room that were installed at a specific time, you can write the following label line:
+
+```yaml
+label: room = workstation AND installed = 201705
+```
+
+The `label` is a space-separated list that accepts simple patterns. For example, you can create an alarm
+that will be applied to all hosts installed in the last decade with the following line:
+
+```yaml
+label: installed = 201*
+```
+
+See our [simple patterns docs](../libnetdata/simple_pattern/) for more examples.
+
## Expressions
Netdata has an internal [infix expression parser](../libnetdata/eval). This parses expressions and creates an internal
diff --git a/health/health.c b/health/health.c
index 329191fb88..b28c67d159 100644
--- a/health/health.c
+++ b/health/health.c
@@ -152,6 +152,9 @@ void health_reload_host(RRDHOST *host) {
rrdhost_wrlock(host);
health_readdir(host, user_path, stock_path, NULL);
+ //Discard alarms with labels that do not apply to host
+ rrdcalc_labels_unlink_alarm_from_host(host);
+
// link the loaded alarms to their charts
RRDDIM *rd;
rrdset_foreach_write(st, host) {
@@ -577,6 +580,8 @@ void *health_main(void *ptr) {
time_t now = now_realtime_sec();
time_t hibernation_delay = config_get_number(CONFIG_SECTION_HEALTH, "postpone alarms during hibernation for seconds", 60);
+ rrdcalc_labels_unlink();
+
unsigned int loop = 0;
while(!netdata_exit) {
loop++;
diff --git a/health/health_config.c b/health/health_config.c
index 65c6d8bd7f..1323f17f7d 100644
--- a/health/health_config.c
+++ b/health/health_config.c
@@ -24,6 +24,7 @@
#define HEALTH_DELAY_KEY "delay"
#define HEALTH_OPTIONS_KEY "options"
#define HEALTH_REPEAT_KEY "repeat"
+#define HEALTH_LABEL_KEY "label"
static inline int rrdcalc_add_alarm_from_config(RRDHOST *host, RRDCALC *rc) {
if(!rc->chart) {
@@ -497,7 +498,8 @@ static int health_readfile(const char *filename, void *data) {
hash_recipient = 0,
hash_delay = 0,
hash_options = 0,
- hash_repeat = 0;
+ hash_repeat = 0,
+ hash_label = 0;
char buffer[HEALTH_CONF_MAX_LINE + 1];
@@ -522,6 +524,7 @@ static int health_readfile(const char *filename, void *data) {
hash_delay = simple_uhash(HEALTH_DELAY_KEY);
hash_options = simple_uhash(HEALTH_OPTIONS_KEY);
hash_repeat = simple_uhash(HEALTH_REPEAT_KEY);
+ hash_label = simple_uhash(HEALTH_LABEL_KEY);
}
FILE *fp = fopen(filename, "r");
@@ -795,6 +798,19 @@ static int health_readfile(const char *filename, void *data) {
&rc->warn_repeat_every,
&rc->crit_repeat_every);
}
+ else if(hash == hash_label && !strcasecmp(key, HEALTH_LABEL_KEY)) {
+ if(rc->labels) {
+ if(strcmp(rc->labels, value) != 0)
+ error("Health configuration at line %zu of file '%s' for alarm '%s' has key '%s' twice, once with value '%s' and later with value '%s'.",
+ line, filename, rc->name, key, value, value);
+
+ freez(rc->labels);
+ simple_pattern_free(rc->splabels);
+ }
+
+ rc->labels = simple_pattern_trim_around_equal(value);
+ rc->splabels = simple_pattern_create(rc->labels, NULL, SIMPLE_PATTERN_EXACT);
+ }
else {
error("Health configuration at line %zu of file '%s' for alarm '%s' has unknown key '%s'.",
line, filename, rc->name, key);
@@ -927,6 +943,19 @@ static int health_readfile(const char *filename, void *data) {
&rt->warn_repeat_every,
&rt->crit_repeat_every);
}
+ else if(hash == hash_label && !strcasecmp(key, HEALTH_LABEL_KEY)) {
+ if(rt->labels) {
+ if(strcmp(rt->labels, value) != 0)
+ error("Health configuration at line %zu of file '%s' for template '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
+ line, filename, rt->name, key, rt->labels, value, value);
+
+ freez(rt->labels);
+ simple_pattern_free(rt->splabels);
+ }
+
+ rt->labels = simple_pattern_trim_around_equal(value);
+ rt->splabels = simple_pattern_create(rt->labels, NULL, SIMPLE_PATTERN_EXACT);
+ }
else {
error("Health configuration at line %zu of file '%s' for template '%s' has unknown key '%s'.",
line, filename, rt->name, key);
diff --git a/health/health_json.c b/health/health_json.c
index 8a088d034a..ab7eb52e35 100644
--- a/health/health_json.c
+++ b/health/health_json.c
@@ -304,8 +304,12 @@ void health_alarms2json(RRDHOST *host, BUFFER *wb, int all) {
// for(rt = host->templates; rt ; rt = rt->next)
// health_rrdcalctemplate2json_nolock(wb, rt);
- buffer_strcat(wb, "\n\t}\n}\n");
+ buffer_strcat(wb, "\n\t},");
rrdhost_unlock(host);
+
+ buffer_strcat(wb, "\n\t\"labels\": {\n");
+ host_labels2json(host, wb, 2);
+ buffer_strcat(wb, "\t}\n}\n");
}