diff options
Diffstat (limited to '')
-rw-r--r-- | database/rrdcalc.c | 119 |
1 files changed, 113 insertions, 6 deletions
diff --git a/database/rrdcalc.c b/database/rrdcalc.c index 9f16ce374..935ee9c05 100644 --- a/database/rrdcalc.c +++ b/database/rrdcalc.c @@ -108,10 +108,22 @@ static void rrdsetcalc_link(RRDSET *st, RRDCALC *rc) { } } +static inline int rrdcalc_test_additional_restriction(RRDCALC *rc, RRDSET *st){ + if (rc->module_match && !simple_pattern_matches(rc->module_pattern, st->module_name)) + return 0; + + if (rc->plugin_match && !simple_pattern_matches(rc->plugin_pattern, st->plugin_name)) + return 0; + + return 1; +} + static inline int rrdcalc_is_matching_this_rrdset(RRDCALC *rc, RRDSET *st) { - if( (rc->hash_chart == st->hash && !strcmp(rc->chart, st->id)) || - (rc->hash_chart == st->hash_name && !strcmp(rc->chart, st->name))) - return 1; + if(((rc->hash_chart == st->hash && !strcmp(rc->chart, st->id)) || + (rc->hash_chart == st->hash_name && !strcmp(rc->chart, st->name))) && + rrdcalc_test_additional_restriction(rc, st)) { + return 1; + } return 0; } @@ -252,6 +264,9 @@ inline uint32_t rrdcalc_get_unique_id(RRDHOST *host, const char *chart, const ch } } + if (unlikely(!host->health_log.next_alarm_id)) + host->health_log.next_alarm_id = (uint32_t)now_realtime_sec(); + return host->health_log.next_alarm_id++; } @@ -307,7 +322,7 @@ inline void rrdcalc_add_to_host(RRDHOST *host, RRDCALC *rc) { if(rc->calculation) { rc->calculation->status = &rc->status; - rc->calculation->this = &rc->value; + rc->calculation->myself = &rc->value; rc->calculation->after = &rc->db_after; rc->calculation->before = &rc->db_before; rc->calculation->rrdcalc = rc; @@ -315,7 +330,7 @@ inline void rrdcalc_add_to_host(RRDHOST *host, RRDCALC *rc) { if(rc->warning) { rc->warning->status = &rc->status; - rc->warning->this = &rc->value; + rc->warning->myself = &rc->value; rc->warning->after = &rc->db_after; rc->warning->before = &rc->db_before; rc->warning->rrdcalc = rc; @@ -323,7 +338,7 @@ inline void rrdcalc_add_to_host(RRDHOST *host, RRDCALC *rc) { if(rc->critical) { rc->critical->status = &rc->status; - rc->critical->this = &rc->value; + rc->critical->myself = &rc->value; rc->critical->after = &rc->db_after; rc->critical->before = &rc->db_before; rc->critical->rrdcalc = rc; @@ -559,6 +574,12 @@ void rrdcalc_free(RRDCALC *rc) { freez(rc->units); freez(rc->info); simple_pattern_free(rc->spdim); + freez(rc->labels); + simple_pattern_free(rc->splabels); + freez(rc->module_match); + simple_pattern_free(rc->module_pattern); + freez(rc->plugin_match); + simple_pattern_free(rc->plugin_pattern); freez(rc); } @@ -603,6 +624,92 @@ void rrdcalc_unlink_and_free(RRDHOST *host, RRDCALC *rc) { rrdcalc_free(rc); } +void rrdcalc_foreach_unlink_and_free(RRDHOST *host, RRDCALC *rc) { + + if(unlikely(rc == host->alarms_with_foreach)) + host->alarms_with_foreach = rc->next; + else { + RRDCALC *t; + for(t = host->alarms_with_foreach; t && t->next != rc; t = t->next) ; + if(t) { + t->next = rc->next; + rc->next = NULL; + } + else + error("Cannot unlink alarm '%s.%s' from host '%s': not found", rc->chart?rc->chart:"NOCHART", rc->name, host->hostname); + } + + rrdcalc_free(rc); +} + +static void rrdcalc_labels_unlink_alarm_loop(RRDHOST *host, RRDCALC *alarms) { + RRDCALC *rc = alarms; + while (rc) { + if (!rc->labels) { + rc = rc->next; + continue; + } + + char cmp[CONFIG_FILE_LINE_MAX+1]; + struct label *move = host->labels.head; + while(move) { + snprintf(cmp, CONFIG_FILE_LINE_MAX, "%s=%s", move->key, move->value); + if (simple_pattern_matches(rc->splabels, move->key) || + simple_pattern_matches(rc->splabels, cmp)) { + break; + } + + move = move->next; + } + + RRDCALC *next = rc->next; + if(!move) { + info("Health configuration for alarm '%s' cannot be applied, because the host %s does not have the label(s) '%s'", + rc->name, + host->hostname, + rc->labels); + + if(host->alarms == alarms) { + rrdcalc_unlink_and_free(host, rc); + } else + rrdcalc_foreach_unlink_and_free(host, rc); + + } + + rc = next; + } +} + +void rrdcalc_labels_unlink_alarm_from_host(RRDHOST *host) { + rrdhost_check_rdlock(host); + netdata_rwlock_rdlock(&host->labels.labels_rwlock); + + rrdcalc_labels_unlink_alarm_loop(host, host->alarms); + rrdcalc_labels_unlink_alarm_loop(host, host->alarms_with_foreach); + + netdata_rwlock_unlock(&host->labels.labels_rwlock); +} + +void rrdcalc_labels_unlink() { + rrd_rdlock(); + + RRDHOST *host; + rrdhost_foreach_read(host) { + if (unlikely(!host->health_enabled)) + continue; + + if (host->labels.head) { + rrdhost_wrlock(host); + + rrdcalc_labels_unlink_alarm_from_host(host); + + rrdhost_unlock(host); + } + } + + rrd_unlock(); +} + // ---------------------------------------------------------------------------- // Alarm |