added more fping alarms; added the ability to have alarms that never send CLEAR notifications (needed for alarms that detect an tremendous increase, but soon after that they are cleared)
Costa Tsaousis (ktsaou) committed
Jan 27, 2017 at 02:18 UTC
8463363f54890f3afca01f43119a30516834c8e4
7 files changed
+288
-114
conf.d/health.d/fping.conf
+31
-4
@@ -1,18 +1,45 @@
1
-template: host_health
1
+
2
+template: fping_last_collected_secs
3
+families: *
4
+ on: fping.latency
5
+ calc: $now - $last_collected_t
6
+ units: seconds ago
7
+ every: 10s
8
+ warn: $this > (($status >= $WARNING) ? ($update_every) : ( 5 * $update_every))
9
+ crit: $this > (($status == $CRITICAL) ? ($update_every) : (60 * $update_every))
10
+ delay: down 5m multiplier 1.5 max 1h
11
+ info: number of seconds since the last successful data collection
12
+ to: sysadmin
13
+
14
+template: host_reachable
15
families: *
16
on: fping.latency
17
calc: $average != nan
18
units: up/down
19
every: 10s
20
crit: $this == 0
8
- info: the ping status
21
+ info: states if the remote host is reachable
22
+ delay: down 30m multiplier 1.5 max 2h
23
+ to: sysadmin
24
+
25
+template: host_latency
26
+families: *
27
+ on: fping.latency
28
+ lookup: average -10s unaligned of average
29
+ units: ms
30
+ every: 10s
31
+ green: 100
32
+ red: 500
33
+ warn: $this > $green OR $max > $red
34
+ crit: $this > $red
35
+ info: avergae round trip delay during the last 10 seconds
36
delay: down 30m multiplier 1.5 max 2h
37
to: sysadmin
38
39
template: packet_loss
40
families: *
41
on: fping.quality
15
- lookup: average -10m of returned
42
+ lookup: average -10m unaligned of returned
43
calc: 100 - $this
44
green: 1
45
red: 10
@@ -20,7 +47,7 @@ families: *
47
every: 10s
48
warn: $this > $green
49
crit: $this > $red
23
- info: the percentage of packet loss
50
+ info: packet loss percentage
51
delay: down 30m multiplier 1.5 max 2h
52
to: sysadmin
53
conf.d/health.d/net.conf
+2
-1
@@ -116,6 +116,7 @@ families: *
116
units: %
117
warn: $this > (($status >= $WARNING)?(200):(1000))
118
crit: $this > (($status >= $WARNING)?(1000):(2000))
119
+options: no-clear-notification
120
info: the % of the rate of received packets in the last 10 seconds, compared to the rate of the last minute
120
- to: silent
121
+ to: sysadmin
122
conf.d/health.d/tcp_resets.conf
+4
-2
@@ -28,8 +28,9 @@
28
every: 10s
29
warn: $this > ((($1m_ipv4_tcp_resets_sent < 5)?(5):($1m_ipv4_tcp_resets_sent)) * (($status >= $WARNING) ? (1) : (4)))
30
delay: up 0 down 60m multiplier 1.2 max 2h
31
+options: no-clear-notification
32
info: average TCP RESETS this host is sending, over the last 10 seconds (this can be an indication that a port scan is made, or that a service running on this host has crashed)
32
- to: silent
33
+ to: sysadmin
34
35
# -----------------------------------------------------------------------------
36
# tcp resets this host receives
@@ -48,5 +49,6 @@
49
every: 10s
50
warn: $this > ((($1m_ipv4_tcp_resets_received < 5)?(5):($1m_ipv4_tcp_resets_received)) * (($status >= $WARNING) ? (1) : (4)))
51
delay: up 0 down 60m multiplier 1.2 max 2h
52
+options: no-clear-notification
53
info: average TCP RESETS this host is receiving, over the last 10 seconds (this can be an indication that a service this host needs, has crashed)
52
- to: silent
54
+ to: sysadmin
src/health.c
+232
-94
@@ -359,17 +359,26 @@ static inline void health_alarm_log_load(RRDHOST *host) {
359
// ----------------------------------------------------------------------------
360
// health alarm log management
361
362
-static inline void health_alarm_log(RRDHOST *host,
363
- uint32_t alarm_id, uint32_t alarm_event_id,
364
- time_t when,
365
- const char *name, const char *chart, const char *family,
366
- const char *exec, const char *recipient, time_t duration,
367
- calculated_number old_value, calculated_number new_value,
368
- int old_status, int new_status,
369
- const char *source,
370
- const char *units,
371
- const char *info,
372
- int delay
362
+static inline void health_alarm_log(
363
+ RRDHOST *host,
364
+ uint32_t alarm_id,
365
+ uint32_t alarm_event_id,
366
+ time_t when,
367
+ const char *name,
368
+ const char *chart,
369
+ const char *family,
370
+ const char *exec,
371
+ const char *recipient,
372
+ time_t duration,
373
+ calculated_number old_value,
374
+ calculated_number new_value,
375
+ int old_status,
376
+ int new_status,
377
+ const char *source,
378
+ const char *units,
379
+ const char *info,
380
+ int delay,
381
+ uint32_t flags
382
) {
383
debug(D_HEALTH, "Health adding alarm log entry with id: %u", host->health_log.next_log_id);
384
@@ -408,6 +417,8 @@ static inline void health_alarm_log(RRDHOST *host,
417
ae->delay = delay;
418
ae->delay_up_to_timestamp = when + delay;
419
420
+ ae->flags |= flags;
421
+
422
if(ae->old_status == RRDCALC_STATUS_WARNING || ae->old_status == RRDCALC_STATUS_CRITICAL)
423
ae->non_clear_duration += ae->duration;
424
@@ -1106,7 +1117,27 @@ static void rrdsetcalc_link(RRDSET *st, RRDCALC *rc) {
1117
1118
{
1119
time_t now = now_realtime_sec();
1109
- health_alarm_log(st->rrdhost, rc->id, rc->next_event_id++, now, rc->name, rc->rrdset->id, rc->rrdset->family, rc->exec, rc->recipient, now - rc->last_status_change, rc->old_value, rc->value, rc->status, RRDCALC_STATUS_UNINITIALIZED, rc->source, rc->units, rc->info, 0);
1120
+ health_alarm_log(
1121
+ st->rrdhost,
1122
+ rc->id,
1123
+ rc->next_event_id++,
1124
+ now,
1125
+ rc->name,
1126
+ rc->rrdset->id,
1127
+ rc->rrdset->family,
1128
+ rc->exec,
1129
+ rc->recipient,
1130
+ now - rc->last_status_change,
1131
+ rc->old_value,
1132
+ rc->value,
1133
+ rc->status,
1134
+ RRDCALC_STATUS_UNINITIALIZED,
1135
+ rc->source,
1136
+ rc->units,
1137
+ rc->info,
1138
+ 0,
1139
+ 0
1140
+ );
1141
}
1142
}
1143
@@ -1144,7 +1175,27 @@ inline void rrdsetcalc_unlink(RRDCALC *rc) {
1175
1176
{
1177
time_t now = now_realtime_sec();
1147
- health_alarm_log(st->rrdhost, rc->id, rc->next_event_id++, now, rc->name, rc->rrdset->id, rc->rrdset->family, rc->exec, rc->recipient, now - rc->last_status_change, rc->old_value, rc->value, rc->status, RRDCALC_STATUS_REMOVED, rc->source, rc->units, rc->info, 0);
1178
+ health_alarm_log(
1179
+ st->rrdhost,
1180
+ rc->id,
1181
+ rc->next_event_id++,
1182
+ now,
1183
+ rc->name,
1184
+ rc->rrdset->id,
1185
+ rc->rrdset->family,
1186
+ rc->exec,
1187
+ rc->recipient,
1188
+ now - rc->last_status_change,
1189
+ rc->old_value,
1190
+ rc->value,
1191
+ rc->status,
1192
+ RRDCALC_STATUS_REMOVED,
1193
+ rc->source,
1194
+ rc->units,
1195
+ rc->info,
1196
+ 0,
1197
+ 0
1198
+ );
1199
}
1200
1201
RRDHOST *host = st->rrdhost;
@@ -1483,6 +1534,7 @@ static inline void rrdcalctemplate_free(RRDHOST *host, RRDCALCTEMPLATE *rt) {
1534
#define HEALTH_UNITS_KEY "units"
1535
#define HEALTH_INFO_KEY "info"
1536
#define HEALTH_DELAY_KEY "delay"
1537
+#define HEALTH_OPTIONS_KEY "options"
1538
1539
static inline int rrdcalc_add_alarm_from_config(RRDHOST *host, RRDCALC *rc) {
1540
if(!rc->chart) {
@@ -1713,6 +1765,33 @@ static inline int health_parse_delay(
1765
return 1;
1766
}
1767
1768
+static inline uint32_t health_parse_options(const char *s) {
1769
+ uint32_t options = 0;
1770
+ char buf[100+1] = "";
1771
+
1772
+ while(*s) {
1773
+ buf[0] = '\0';
1774
+
1775
+ // skip spaces
1776
+ while(*s && isspace(*s))
1777
+ s++;
1778
+
1779
+ // find the next space
1780
+ size_t count = 0;
1781
+ while(*s && count < 100 && !isspace(*s))
1782
+ buf[count++] = *s++;
1783
+
1784
+ if(buf[0]) {
1785
+ buf[count] = '\0';
1786
+
1787
+ if(!strcasecmp(buf, "no-clear-notification") || !strcasecmp(buf, "no-clear"))
1788
+ options |= RRDCALC_FLAG_NO_CLEAR_NOTIFICATION;
1789
+ }
1790
+ }
1791
+
1792
+ return options;
1793
+}
1794
+
1795
static inline int health_parse_db_lookup(
1796
size_t line, const char *path, const char *file, char *string,
1797
int *group_method, int *after, int *before, int *every,
@@ -1841,7 +1920,25 @@ static inline void strip_quotes(char *s) {
1920
int health_readfile(const char *path, const char *filename) {
1921
debug(D_HEALTH, "Health configuration reading file '%s/%s'", path, filename);
1922
1844
- 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;
1923
+ static uint32_t
1924
+ hash_alarm = 0,
1925
+ hash_template = 0,
1926
+ hash_on = 0,
1927
+ hash_families = 0,
1928
+ hash_calc = 0,
1929
+ hash_green = 0,
1930
+ hash_red = 0,
1931
+ hash_warn = 0,
1932
+ hash_crit = 0,
1933
+ hash_exec = 0,
1934
+ hash_every = 0,
1935
+ hash_lookup = 0,
1936
+ hash_units = 0,
1937
+ hash_info = 0,
1938
+ hash_recipient = 0,
1939
+ hash_delay = 0,
1940
+ hash_options = 0;
1941
+
1942
char buffer[HEALTH_CONF_MAX_LINE + 1];
1943
1944
if(unlikely(!hash_alarm)) {
@@ -1861,6 +1958,7 @@ int health_readfile(const char *path, const char *filename) {
1958
hash_info = simple_hash(HEALTH_INFO_KEY);
1959
hash_recipient = simple_hash(HEALTH_RECIPIENT_KEY);
1960
hash_delay = simple_uhash(HEALTH_DELAY_KEY);
1961
+ hash_options = simple_uhash(HEALTH_OPTIONS_KEY);
1962
}
1963
1964
snprintfz(buffer, HEALTH_CONF_MAX_LINE, "%s/%s", path, filename);
@@ -2073,6 +2171,9 @@ int health_readfile(const char *path, const char *filename) {
2171
else if(hash == hash_delay && !strcasecmp(key, HEALTH_DELAY_KEY)) {
2172
health_parse_delay(line, path, filename, value, &rc->delay_up_duration, &rc->delay_down_duration, &rc->delay_max_duration, &rc->delay_multiplier);
2173
}
2174
+ else if(hash == hash_options && !strcasecmp(key, HEALTH_OPTIONS_KEY)) {
2175
+ rc->options |= health_parse_options(value);
2176
+ }
2177
else {
2178
error("Health configuration at line %zu of file '%s/%s' for alarm '%s' has unknown key '%s'.",
2179
line, path, filename, rc->name, key);
@@ -2194,6 +2295,9 @@ int health_readfile(const char *path, const char *filename) {
2295
else if(hash == hash_delay && !strcasecmp(key, HEALTH_DELAY_KEY)) {
2296
health_parse_delay(line, path, filename, value, &rt->delay_up_duration, &rt->delay_down_duration, &rt->delay_max_duration, &rt->delay_multiplier);
2297
}
2298
+ else if(hash == hash_options && !strcasecmp(key, HEALTH_OPTIONS_KEY)) {
2299
+ rt->options |= health_parse_options(value);
2300
+ }
2301
else {
2302
error("Health configuration at line %zu of file '%s/%s' for template '%s' has unknown key '%s'.",
2303
line, path, filename, rt->name, key);
@@ -2316,65 +2420,70 @@ static inline void health_string2json(BUFFER *wb, const char *prefix, const char
2420
}
2421
2422
static inline void health_alarm_entry2json_nolock(BUFFER *wb, ALARM_ENTRY *ae, RRDHOST *host) {
2319
- buffer_sprintf(wb, "\n\t{\n"
2320
- "\t\t\"hostname\": \"%s\",\n"
2321
- "\t\t\"unique_id\": %u,\n"
2322
- "\t\t\"alarm_id\": %u,\n"
2323
- "\t\t\"alarm_event_id\": %u,\n"
2324
- "\t\t\"name\": \"%s\",\n"
2325
- "\t\t\"chart\": \"%s\",\n"
2326
- "\t\t\"family\": \"%s\",\n"
2327
- "\t\t\"processed\": %s,\n"
2328
- "\t\t\"updated\": %s,\n"
2329
- "\t\t\"exec_run\": %lu,\n"
2330
- "\t\t\"exec_failed\": %s,\n"
2331
- "\t\t\"exec\": \"%s\",\n"
2332
- "\t\t\"recipient\": \"%s\",\n"
2333
- "\t\t\"exec_code\": %d,\n"
2334
- "\t\t\"source\": \"%s\",\n"
2335
- "\t\t\"units\": \"%s\",\n"
2336
- "\t\t\"info\": \"%s\",\n"
2337
- "\t\t\"when\": %lu,\n"
2338
- "\t\t\"duration\": %lu,\n"
2339
- "\t\t\"non_clear_duration\": %lu,\n"
2340
- "\t\t\"status\": \"%s\",\n"
2341
- "\t\t\"old_status\": \"%s\",\n"
2342
- "\t\t\"delay\": %d,\n"
2343
- "\t\t\"delay_up_to_timestamp\": %lu,\n"
2344
- "\t\t\"updated_by_id\": %u,\n"
2345
- "\t\t\"updates_id\": %u,\n"
2346
- "\t\t\"value_string\": \"%s\",\n"
2347
- "\t\t\"old_value_string\": \"%s\",\n",
2348
- host->hostname,
2349
- ae->unique_id,
2350
- ae->alarm_id,
2351
- ae->alarm_event_id,
2352
- ae->name,
2353
- ae->chart,
2354
- ae->family,
2355
- (ae->flags & HEALTH_ENTRY_FLAG_PROCESSED)?"true":"false",
2356
- (ae->flags & HEALTH_ENTRY_FLAG_UPDATED)?"true":"false",
2357
- (unsigned long)ae->exec_run_timestamp,
2358
- (ae->flags & HEALTH_ENTRY_FLAG_EXEC_FAILED)?"true":"false",
2359
- ae->exec?ae->exec:health.health_default_exec,
2360
- ae->recipient?ae->recipient:health.health_default_recipient,
2361
- ae->exec_code,
2362
- ae->source,
2363
- ae->units?ae->units:"",
2364
- ae->info?ae->info:"",
2365
- (unsigned long)ae->when,
2366
- (unsigned long)ae->duration,
2367
- (unsigned long)ae->non_clear_duration,
2368
- rrdcalc_status2string(ae->new_status),
2369
- rrdcalc_status2string(ae->old_status),
2370
- ae->delay,
2371
- (unsigned long)ae->delay_up_to_timestamp,
2372
- ae->updated_by_id,
2373
- ae->updates_id,
2374
- ae->new_value_string,
2375
- ae->old_value_string
2423
+ buffer_sprintf(wb,
2424
+ "\n\t{\n"
2425
+ "\t\t\"hostname\": \"%s\",\n"
2426
+ "\t\t\"unique_id\": %u,\n"
2427
+ "\t\t\"alarm_id\": %u,\n"
2428
+ "\t\t\"alarm_event_id\": %u,\n"
2429
+ "\t\t\"name\": \"%s\",\n"
2430
+ "\t\t\"chart\": \"%s\",\n"
2431
+ "\t\t\"family\": \"%s\",\n"
2432
+ "\t\t\"processed\": %s,\n"
2433
+ "\t\t\"updated\": %s,\n"
2434
+ "\t\t\"exec_run\": %lu,\n"
2435
+ "\t\t\"exec_failed\": %s,\n"
2436
+ "\t\t\"exec\": \"%s\",\n"
2437
+ "\t\t\"recipient\": \"%s\",\n"
2438
+ "\t\t\"exec_code\": %d,\n"
2439
+ "\t\t\"source\": \"%s\",\n"
2440
+ "\t\t\"units\": \"%s\",\n"
2441
+ "\t\t\"info\": \"%s\",\n"
2442
+ "\t\t\"when\": %lu,\n"
2443
+ "\t\t\"duration\": %lu,\n"
2444
+ "\t\t\"non_clear_duration\": %lu,\n"
2445
+ "\t\t\"status\": \"%s\",\n"
2446
+ "\t\t\"old_status\": \"%s\",\n"
2447
+ "\t\t\"delay\": %d,\n"
2448
+ "\t\t\"delay_up_to_timestamp\": %lu,\n"
2449
+ "\t\t\"updated_by_id\": %u,\n"
2450
+ "\t\t\"updates_id\": %u,\n"
2451
+ "\t\t\"value_string\": \"%s\",\n"
2452
+ "\t\t\"old_value_string\": \"%s\",\n"
2453
+ , host->hostname
2454
+ , ae->unique_id
2455
+ , ae->alarm_id
2456
+ , ae->alarm_event_id
2457
+ , ae->name
2458
+ , ae->chart
2459
+ , ae->family
2460
+ , (ae->flags & HEALTH_ENTRY_FLAG_PROCESSED)?"true":"false"
2461
+ , (ae->flags & HEALTH_ENTRY_FLAG_UPDATED)?"true":"false"
2462
+ , (unsigned long)ae->exec_run_timestamp
2463
+ , (ae->flags & HEALTH_ENTRY_FLAG_EXEC_FAILED)?"true":"false"
2464
+ , ae->exec?ae->exec:health.health_default_exec
2465
+ , ae->recipient?ae->recipient:health.health_default_recipient
2466
+ , ae->exec_code
2467
+ , ae->source
2468
+ , ae->units?ae->units:""
2469
+ , ae->info?ae->info:""
2470
+ , (unsigned long)ae->when
2471
+ , (unsigned long)ae->duration
2472
+ , (unsigned long)ae->non_clear_duration
2473
+ , rrdcalc_status2string(ae->new_status)
2474
+ , rrdcalc_status2string(ae->old_status)
2475
+ , ae->delay
2476
+ , (unsigned long)ae->delay_up_to_timestamp
2477
+ , ae->updated_by_id
2478
+ , ae->updates_id
2479
+ , ae->new_value_string
2480
+ , ae->old_value_string
2481
);
2482
2483
+ if(unlikely(ae->flags & HEALTH_ENTRY_FLAG_NO_CLEAR_NOTIFICATION)) {
2484
+ buffer_strcat(wb, "\t\t\"no_clear_notification\": true,\n");
2485
+ }
2486
+
2487
buffer_strcat(wb, "\t\t\"value\":");
2488
buffer_rrd_value(wb, ae->new_value);
2489
buffer_strcat(wb, ",\n");
@@ -2430,30 +2539,34 @@ static inline void health_rrdcalc2json_nolock(BUFFER *wb, RRDCALC *rc) {
2539
"\t\t\t\"delay_multiplier\": %f,\n"
2540
"\t\t\t\"delay\": %d,\n"
2541
"\t\t\t\"delay_up_to_timestamp\": %lu,\n"
2433
- , rc->chart, rc->name
2434
- , (unsigned long)rc->id
2435
- , rc->name
2436
- , rc->chart
2437
- , (rc->rrdset && rc->rrdset->family)?rc->rrdset->family:""
2438
- , (rc->rrdset)?"true":"false"
2439
- , rc->exec?rc->exec:health.health_default_exec
2440
- , rc->recipient?rc->recipient:health.health_default_recipient
2441
- , rc->source
2442
- , rc->units?rc->units:""
2443
- , rc->info?rc->info:""
2444
- , rrdcalc_status2string(rc->status)
2445
- , (unsigned long)rc->last_status_change
2446
- , (unsigned long)rc->last_updated
2447
- , (unsigned long)rc->next_update
2448
- , rc->update_every
2449
- , rc->delay_up_duration
2450
- , rc->delay_down_duration
2451
- , rc->delay_max_duration
2452
- , rc->delay_multiplier
2453
- , rc->delay_last
2454
- , (unsigned long)rc->delay_up_to_timestamp
2542
+ , rc->chart, rc->name
2543
+ , (unsigned long)rc->id
2544
+ , rc->name
2545
+ , rc->chart
2546
+ , (rc->rrdset && rc->rrdset->family)?rc->rrdset->family:""
2547
+ , (rc->rrdset)?"true":"false"
2548
+ , rc->exec?rc->exec:health.health_default_exec
2549
+ , rc->recipient?rc->recipient:health.health_default_recipient
2550
+ , rc->source
2551
+ , rc->units?rc->units:""
2552
+ , rc->info?rc->info:""
2553
+ , rrdcalc_status2string(rc->status)
2554
+ , (unsigned long)rc->last_status_change
2555
+ , (unsigned long)rc->last_updated
2556
+ , (unsigned long)rc->next_update
2557
+ , rc->update_every
2558
+ , rc->delay_up_duration
2559
+ , rc->delay_down_duration
2560
+ , rc->delay_max_duration
2561
+ , rc->delay_multiplier
2562
+ , rc->delay_last
2563
+ , (unsigned long)rc->delay_up_to_timestamp
2564
);
2565
2566
+ if(unlikely(rc->options & RRDCALC_FLAG_NO_CLEAR_NOTIFICATION)) {
2567
+ buffer_strcat(wb, "\t\t\t\"no_clear_notification\": true,\n");
2568
+ }
2569
+
2570
if(RRDCALC_HAS_DB_LOOKUP(rc)) {
2571
if(rc->dimensions && *rc->dimensions)
2572
health_string2json(wb, "\t\t\t", "lookup_dimensions", rc->dimensions, ",\n");
@@ -2619,6 +2732,11 @@ static inline void health_alarm_execute(RRDHOST *host, ALARM_ENTRY *ae) {
2732
goto done;
2733
}
2734
2735
+ if(unlikely(ae->new_status <= RRDCALC_STATUS_CLEAR && ae->flags & HEALTH_ENTRY_FLAG_NO_CLEAR_NOTIFICATION)) {
2736
+ // do not send notifications for disabled statuses
2737
+ goto done;
2738
+ }
2739
+
2740
// find the previous notification for the same alarm
2741
// which we have run the exec script
2742
{
@@ -3102,7 +3220,27 @@ void *health_main(void *ptr) {
3220
3221
rc->delay_last = delay;
3222
rc->delay_up_to_timestamp = now + delay;
3105
- health_alarm_log(&localhost, rc->id, rc->next_event_id++, now, rc->name, rc->rrdset->id, rc->rrdset->family, rc->exec, rc->recipient, now - rc->last_status_change, rc->old_value, rc->value, rc->status, status, rc->source, rc->units, rc->info, rc->delay_last);
3223
+ health_alarm_log(
3224
+ &localhost,
3225
+ rc->id,
3226
+ rc->next_event_id++,
3227
+ now,
3228
+ rc->name,
3229
+ rc->rrdset->id,
3230
+ rc->rrdset->family,
3231
+ rc->exec,
3232
+ rc->recipient,
3233
+ now - rc->last_status_change,
3234
+ rc->old_value,
3235
+ rc->value,
3236
+ rc->status,
3237
+ status,
3238
+ rc->source,
3239
+ rc->units,
3240
+ rc->info,
3241
+ rc->delay_last,
3242
+ (rc->options & RRDCALC_FLAG_NO_CLEAR_NOTIFICATION)?HEALTH_ENTRY_FLAG_NO_CLEAR_NOTIFICATION:0
3243
+ );
3244
rc->last_status_change = now;
3245
rc->status = status;
3246
}
src/health.h
+14
-12
@@ -119,13 +119,14 @@ typedef struct rrddimvar {
119
#define RRDCALC_STATUS_WARNING 3
120
#define RRDCALC_STATUS_CRITICAL 4
121
122
-#define RRDCALC_FLAG_DB_ERROR 0x00000001
123
-#define RRDCALC_FLAG_DB_NAN 0x00000002
124
-/* #define RRDCALC_FLAG_DB_STALE 0x00000004 */
125
-#define RRDCALC_FLAG_CALC_ERROR 0x00000008
126
-#define RRDCALC_FLAG_WARN_ERROR 0x00000010
127
-#define RRDCALC_FLAG_CRIT_ERROR 0x00000020
128
-#define RRDCALC_FLAG_RUNNABLE 0x00000040
122
+#define RRDCALC_FLAG_DB_ERROR 0x00000001
123
+#define RRDCALC_FLAG_DB_NAN 0x00000002
124
+/* #define RRDCALC_FLAG_DB_STALE 0x00000004 */
125
+#define RRDCALC_FLAG_CALC_ERROR 0x00000008
126
+#define RRDCALC_FLAG_WARN_ERROR 0x00000010
127
+#define RRDCALC_FLAG_CRIT_ERROR 0x00000020
128
+#define RRDCALC_FLAG_RUNNABLE 0x00000040
129
+#define RRDCALC_FLAG_NO_CLEAR_NOTIFICATION 0x80000000
130
131
typedef struct rrdcalc {
132
uint32_t id; // the unique id of this alarm
@@ -274,11 +275,12 @@ typedef struct rrdcalctemplate {
275
276
#define RRDCALCTEMPLATE_HAS_CALCULATION(rt) ((rt)->after)
277
277
-#define HEALTH_ENTRY_FLAG_PROCESSED 0x00000001
278
-#define HEALTH_ENTRY_FLAG_UPDATED 0x00000002
279
-#define HEALTH_ENTRY_FLAG_EXEC_RUN 0x00000004
280
-#define HEALTH_ENTRY_FLAG_EXEC_FAILED 0x00000008
281
-#define HEALTH_ENTRY_FLAG_SAVED 0x10000000
278
+#define HEALTH_ENTRY_FLAG_PROCESSED 0x00000001
279
+#define HEALTH_ENTRY_FLAG_UPDATED 0x00000002
280
+#define HEALTH_ENTRY_FLAG_EXEC_RUN 0x00000004
281
+#define HEALTH_ENTRY_FLAG_EXEC_FAILED 0x00000008
282
+#define HEALTH_ENTRY_FLAG_SAVED 0x10000000
283
+#define HEALTH_ENTRY_FLAG_NO_CLEAR_NOTIFICATION 0x80000000
284
285
typedef struct alarm_entry {
286
uint32_t unique_id;
web/dashboard.js
+4
@@ -6104,6 +6104,10 @@ var NETDATA = window.NETDATA || {};
6104
// console.log('alarm' + entry.unique_id + ' switch to CLEAR from ' + entry.old_status);
6105
return;
6106
}
6107
+ if(entry.no_clear_notification === true) {
6108
+ // console.log('alarm' + entry.unique_id + ' is CLEAR but has no_clear_notification flag');
6109
+ return;
6110
+ }
6111
title = name + ' back to normal (' + entry.value_string.toString() + ')';
6112
icon = 'images/check-mark-2-128-green.png'
6113
interaction = false;
web/index.html
+1
-1
@@ -3288,4 +3288,4 @@
3288
</div>
3289
</body>
3290
</html>
3291
-<script type="text/javascript" src="dashboard.js?v20170126-1"></script>
3291
+<script type="text/javascript" src="dashboard.js?v20170127-1"></script>