added fping alarms and various aesthetic improvements to alarms
Costa Tsaousis (ktsaou) committed
Jan 26, 2017 at 02:42 UTC
6a0aee81aba1b0dabdb6dddd0ef37056a65855a1
8 files changed
+265
-121
conf.d/Makefile.am
+1
@@ -64,6 +64,7 @@ dist_healthconfig_DATA = \
64
health.d/disks.conf \
65
health.d/elasticsearch.conf \
66
health.d/entropy.conf \
67
+ health.d/fping.conf \
68
health.d/haproxy.conf \
69
health.d/ipc.conf \
70
health.d/ipfs.conf \
conf.d/health.d/disks.conf
+1
-1
@@ -88,7 +88,7 @@ families: *
88
template: out_of_disk_space_time
89
on: disk.space
90
families: *
91
- calc: ($disk_fill_rate > 0) ? ($avail / $disk_fill_rate) : (0)
91
+ calc: ($disk_fill_rate > 0) ? ($avail / $disk_fill_rate) : (inf)
92
units: hours
93
every: 10s
94
warn: $this > 0 and $this < (($status >= $WARNING) ? (48) : (8))
conf.d/health.d/fping.conf
new
+26
@@ -0,0 +1,26 @@
1
+template: host_health
2
+families: *
3
+ on: fping.latency
4
+ calc: $average != nan
5
+ units: up/down
6
+ every: 10s
7
+ crit: $this == 0
8
+ info: the ping status
9
+ delay: down 30m multiplier 1.5 max 2h
10
+ to: sysadmin
11
+
12
+template: packet_loss
13
+families: *
14
+ on: fping.quality
15
+ lookup: average -10m of returned
16
+ calc: 100 - $this
17
+ green: 1
18
+ red: 10
19
+ units: %
20
+ every: 10s
21
+ warn: $this > $green
22
+ crit: $this > $red
23
+ info: the percentage of packet loss
24
+ delay: down 30m multiplier 1.5 max 2h
25
+ to: sysadmin
26
+
conf.d/health.d/memcached.conf
+1
-1
@@ -42,7 +42,7 @@ template: cache_fill_rate
42
43
template: out_of_cache_space_time
44
on: memcached.cache
45
- calc: ($cache_fill_rate > 0) ? ($available / $cache_fill_rate) : (0)
45
+ calc: ($cache_fill_rate > 0) ? ($available / $cache_fill_rate) : (inf)
46
units: hours
47
every: 10s
48
warn: $this > 0 and $this < (($status >= $WARNING) ? (48) : (8))
conf.d/health.d/mysql.conf
+2
-2
@@ -49,7 +49,7 @@ template: mysql_10s_table_locks_waited
49
50
template: mysql_10s_waited_locks_ratio
51
on: mysql.table_locks
52
- calc: ($mysql_10s_table_locks_waited * 100) / ($mysql_10s_table_locks_waited + $mysql_10s_table_locks_immediate)
52
+ calc: ( ($mysql_10s_table_locks_waited + $mysql_10s_table_locks_immediate) > 0 ) ? (($mysql_10s_table_locks_waited * 100) / ($mysql_10s_table_locks_waited + $mysql_10s_table_locks_immediate)) : 0
53
units: %
54
every: 10s
55
warn: $this > (($status >= $WARNING) ? (10) : (25))
@@ -65,7 +65,7 @@ template: mysql_10s_waited_locks_ratio
65
template: mysql_replication
66
on: mysql.slave_status
67
calc: ($sql_running == -1 OR $io_running == -1)?0:1
68
- units: status
68
+ units: ok/failed
69
every: 10s
70
crit: $this == 0
71
delay: down 5m multiplier 1.5 max 1h
src/web_buffer_svg.c
+221
-104
@@ -368,10 +368,179 @@ cleanup:
368
return len - i;
369
}
370
371
-static inline const char *fix_units(const char *units) {
372
- if(!units || !*units || !strcmp(units, "empty") || !strcmp(units, "null")) return "";
373
- if(!strcmp(units, "percentage") || !strcmp(units, "percent") || !strcmp(units, "pcent")) return "%";
374
- return units;
371
+static inline int fix_value_and_units(char *value_string, size_t value_string_len, calculated_number value, const char **units_ptr, int value_is_null) {
372
+ static uint32_t
373
+ hash_seconds = 0,
374
+ hash_seconds_ago = 0,
375
+ hash_minutes = 0,
376
+ hash_minutes_ago = 0,
377
+ hash_hours = 0,
378
+ hash_hours_ago = 0,
379
+ hash_onoff = 0,
380
+ hash_updown = 0,
381
+ hash_okerror = 0,
382
+ hash_okfailed = 0,
383
+ hash_empty = 0,
384
+ hash_null = 0,
385
+ hash_percentage = 0,
386
+ hash_percent = 0,
387
+ hash_pcent = 0;
388
+
389
+ if(unlikely(!hash_seconds)) {
390
+ hash_seconds = simple_hash("seconds");
391
+ hash_seconds_ago = simple_hash("seconds ago");
392
+ hash_minutes = simple_hash("minutes");
393
+ hash_minutes_ago = simple_hash("minutes ago");
394
+ hash_hours = simple_hash("hours");
395
+ hash_hours_ago = simple_hash("hours ago");
396
+ hash_onoff = simple_hash("on/off");
397
+ hash_updown = simple_hash("up/down");
398
+ hash_okerror = simple_hash("ok/error");
399
+ hash_okfailed = simple_hash("ok/failed");
400
+ hash_empty = simple_hash("empty");
401
+ hash_null = simple_hash("null");
402
+ hash_percentage = simple_hash("percentage");
403
+ hash_percent = simple_hash("percent");
404
+ hash_pcent = simple_hash("pcent");
405
+ }
406
+
407
+ const char *units = (units_ptr)?*units_ptr:NULL;
408
+ if(unlikely(!units)) units = "";
409
+
410
+ uint32_t hash_units = simple_hash(units);
411
+
412
+ if(unlikely((hash_units == hash_seconds && !strcmp(units, "seconds")) || (hash_units == hash_seconds_ago && !strcmp(units, "seconds ago")))) {
413
+ if(value == 0.0) {
414
+ snprintfz(value_string, value_string_len, "%s", "now");
415
+ units = "";
416
+ goto finish;
417
+ }
418
+ else if(isnan(value) || isinf(value)) {
419
+ snprintfz(value_string, value_string_len, "%s", "never");
420
+ units = "";
421
+ goto finish;
422
+ }
423
+
424
+ const char *suffix = (hash_units == hash_seconds_ago)?" ago":"";
425
+
426
+ size_t s = (size_t)value;
427
+ size_t d = s / 86400;
428
+ s = s % 86400;
429
+
430
+ size_t h = s / 3600;
431
+ s = s % 3600;
432
+
433
+ size_t m = s / 60;
434
+ s = s % 60;
435
+
436
+ if(d)
437
+ snprintfz(value_string, value_string_len, "%zu %s %02zu:%02zu:%02zu%s", d, (d == 1)?"day":"days", h, m, s, suffix);
438
+ else
439
+ snprintfz(value_string, value_string_len, "%02zu:%02zu:%02zu%s", h, m, s, suffix);
440
+
441
+ units = "";
442
+ }
443
+
444
+ else if(unlikely((hash_units == hash_minutes && !strcmp(units, "minutes")) || (hash_units == hash_minutes_ago && !strcmp(units, "minutes ago")))) {
445
+ if(value == 0.0) {
446
+ snprintfz(value_string, value_string_len, "%s", "now");
447
+ units = "";
448
+ goto finish;
449
+ }
450
+ else if(isnan(value) || isinf(value)) {
451
+ snprintfz(value_string, value_string_len, "%s", "never");
452
+ units = "";
453
+ goto finish;
454
+ }
455
+
456
+ const char *suffix = (hash_units == hash_minutes_ago)?" ago":"";
457
+
458
+ size_t m = (size_t)value;
459
+ size_t d = m / (60 * 24);
460
+ m = m % (60 * 24);
461
+
462
+ size_t h = m / 60;
463
+ m = m % 60;
464
+
465
+ if(d)
466
+ snprintfz(value_string, value_string_len, "%zud %02zuh %02zum%s", d, h, m, suffix);
467
+ else
468
+ snprintfz(value_string, value_string_len, "%zuh %zum%s", h, m, suffix);
469
+
470
+ units = "";
471
+ }
472
+
473
+ else if(unlikely((hash_units == hash_hours && !strcmp(units, "hours")) || (hash_units == hash_hours_ago && !strcmp(units, "hours ago")))) {
474
+ if(value == 0.0) {
475
+ snprintfz(value_string, value_string_len, "%s", "now");
476
+ units = "";
477
+ goto finish;
478
+ }
479
+ else if(isnan(value) || isinf(value)) {
480
+ snprintfz(value_string, value_string_len, "%s", "never");
481
+ units = "";
482
+ goto finish;
483
+ }
484
+
485
+ const char *suffix = (hash_units == hash_hours_ago)?" ago":"";
486
+
487
+ size_t h = (size_t)value;
488
+ size_t d = h / 24;
489
+ h = h % 24;
490
+
491
+ if(d)
492
+ snprintfz(value_string, value_string_len, "%zud %zuh%s", d, h, suffix);
493
+ else
494
+ snprintfz(value_string, value_string_len, "%zuh%s", h, suffix);
495
+
496
+ units = "";
497
+ }
498
+
499
+ else if(unlikely(hash_units == hash_onoff && !strcmp(units, "on/off"))) {
500
+ snprintfz(value_string, value_string_len, "%s", (value != 0.0)?"on":"off");
501
+ units = "";
502
+ }
503
+
504
+ else if(unlikely(hash_units == hash_updown && !strcmp(units, "up/down"))) {
505
+ snprintfz(value_string, value_string_len, "%s", (value != 0.0)?"up":"down");
506
+ units = "";
507
+ }
508
+
509
+ else if(unlikely(hash_units == hash_okerror && !strcmp(units, "ok/error"))) {
510
+ snprintfz(value_string, value_string_len, "%s", (value != 0.0)?"ok":"error");
511
+ units = "";
512
+ }
513
+
514
+ else if(unlikely(hash_units == hash_okfailed && !strcmp(units, "ok/failed"))) {
515
+ snprintfz(value_string, value_string_len, "%s", (value != 0.0)?"ok":"failed");
516
+ units = "";
517
+ }
518
+
519
+ else if(unlikely(hash_units == hash_empty && !strcmp(units, "empty")))
520
+ units = "";
521
+
522
+ else if(unlikely(hash_units == hash_null && !strcmp(units, "null")))
523
+ units = "";
524
+
525
+ else if(unlikely(hash_units == hash_percentage && !strcmp(units, "percentage")))
526
+ units = "%";
527
+
528
+ else if(unlikely(hash_units == hash_percent && !strcmp(units, "percent")))
529
+ units = "%";
530
+
531
+ else if(unlikely(hash_units == hash_pcent && !strcmp(units, "pcent")))
532
+ units = "%";
533
+
534
+ else if(unlikely(value_is_null)) {
535
+ strcpy(value_string, "-");
536
+ units = "";
537
+ }
538
+ else
539
+ return 0;
540
+
541
+finish:
542
+ if(units_ptr) *units_ptr = units;
543
+ return 1;
544
}
545
546
static inline const char *color_map(const char *color) {
@@ -392,6 +561,9 @@ static inline const char *color_map(const char *color) {
561
}
562
563
static inline void calc_colorz(const char *color, char *final, size_t len, calculated_number value, int value_is_null) {
564
+ if(isnan(value) || isinf(value))
565
+ value = 0.0;
566
+
567
char color_buffer[256 + 1] = "";
568
char value_buffer[256 + 1] = "";
569
char comparison = '>';
@@ -502,17 +674,6 @@ static inline void calc_colorz(const char *color, char *final, size_t len, calcu
674
#define COLOR_STRING_SIZE 100
675
676
void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const char *units, const char *label_color, const char *value_color, int value_is_null, int precision) {
505
- static uint32_t hash_seconds = 0, hash_seconds_ago = 0, hash_minutes = 0, hash_minutes_ago = 0, hash_hours = 0, hash_hours_ago = 0;
506
-
507
- if(unlikely(!hash_seconds)) {
508
- hash_seconds = simple_hash("seconds");
509
- hash_seconds_ago = simple_hash("seconds ago");
510
- hash_minutes = simple_hash("minutes");
511
- hash_minutes_ago = simple_hash("minutes ago");
512
- hash_hours = simple_hash("hours");
513
- hash_hours_ago = simple_hash("hours ago");
514
- }
515
-
677
char label_buffer[LABEL_STRING_SIZE + 1]
678
, value_color_buffer[COLOR_STRING_SIZE + 1]
679
, value_string[VALUE_STRING_SIZE + 1]
@@ -529,107 +690,63 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
690
if(unlikely(!value_color || !*value_color))
691
value_color = (value_is_null)?"#999":"#4c1";
692
532
- units = fix_units(units);
693
calc_colorz(value_color, value_color_buffer, COLOR_STRING_SIZE, value, value_is_null);
694
535
- char *separator = "";
536
- if(unlikely(isalnum(*units)))
537
- separator = " ";
695
+ if(!fix_value_and_units(value_string, VALUE_STRING_SIZE, value, &units, value_is_null)) {
696
+ // we have to print the value
697
539
- uint32_t hash_units = simple_hash(units);
698
+ if(isnan(value) || isinf(value))
699
+ value = 0.0;
700
541
- if(unlikely((hash_units == hash_seconds && !strcmp(units, "seconds")) || (hash_units == hash_seconds_ago && !strcmp(units, "seconds ago")))) {
542
- char *suffix = (hash_units == hash_seconds_ago)?" ago":"";
543
-
544
- size_t s = (size_t)value;
545
- size_t d = s / 86400;
546
- s = s % 86400;
547
-
548
- size_t h = s / 3600;
549
- s = s % 3600;
550
-
551
- size_t m = s / 60;
552
- s = s % 60;
701
+ char *separator = "";
702
+ if(unlikely(isalnum(*units)))
703
+ separator = " ";
704
554
- if(d)
555
- snprintfz(value_string, VALUE_STRING_SIZE, "%zu %s %02zu:%02zu:%02zu%s", d, (d == 1)?"day":"days", h, m, s, suffix);
556
- else
557
- snprintfz(value_string, VALUE_STRING_SIZE, "%02zu:%02zu:%02zu%s", h, m, s, suffix);
558
- }
705
+ if(precision < 0) {
706
+ int len, lstop = 0, trim_zeros = 1;
707
560
- else if(unlikely((hash_units == hash_minutes && !strcmp(units, "minutes")) || (hash_units == hash_minutes_ago && !strcmp(units, "minutes ago")))) {
561
- char *suffix = (hash_units == hash_minutes_ago)?" ago":"";
562
-
563
- size_t m = (size_t)value;
564
- size_t d = m / (60 * 24);
565
- m = m % (60 * 24);
566
-
567
- size_t h = m / 60;
568
- m = m % 60;
569
-
570
- if(d)
571
- snprintfz(value_string, VALUE_STRING_SIZE, "%zud %02zuh %02zum%s", d, h, m, suffix);
572
- else
573
- snprintfz(value_string, VALUE_STRING_SIZE, "%zuh %zum%s", h, m, suffix);
574
- }
575
-
576
- else if(unlikely((hash_units == hash_hours && !strcmp(units, "hours")) || (hash_units == hash_hours_ago && !strcmp(units, "hours ago")))) {
577
- char *suffix = (hash_units == hash_hours_ago)?" ago":"";
578
-
579
- size_t h = (size_t)value;
580
- size_t d = h / 24;
581
- h = h % 24;
582
-
583
- if(d)
584
- snprintfz(value_string, VALUE_STRING_SIZE, "%zud %zuh%s", d, h, suffix);
585
- else
586
- snprintfz(value_string, VALUE_STRING_SIZE, "%zuh%s", h, suffix);
587
- }
588
-
589
- else if(unlikely(value_is_null))
590
- strcpy(value_string, "-");
591
-
592
- else if(precision < 0) {
593
- int len, lstop = 0, trim_zeros = 1;
708
+ calculated_number abs = value;
709
+ if(isless(value, 0)) {
710
+ lstop = 1;
711
+ abs = -value;
712
+ }
713
595
- calculated_number abs = value;
596
- if(isless(value, 0)) {
597
- lstop = 1;
598
- abs = -value;
599
- }
714
+ if(isgreaterequal(abs, 1000)) {
715
+ len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.0Lf", (long double) value);
716
+ trim_zeros = 0;
717
+ }
718
+ else if(isgreaterequal(abs, 100)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.1Lf", (long double) value);
719
+ else if(isgreaterequal(abs, 1)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.2Lf", (long double) value);
720
+ else if(isgreaterequal(abs, 0.1)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.3Lf", (long double) value);
721
+ else len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.4Lf", (long double) value);
722
+
723
+ if(unlikely(trim_zeros)) {
724
+ int l;
725
+ // remove trailing zeros from the decimal part
726
+ for(l = len - 1; l > lstop; l--) {
727
+ if(likely(value_string[l] == '0')) {
728
+ value_string[l] = '\0';
729
+ len--;
730
+ }
731
601
- if(isgreaterequal(abs, 1000)) { len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.0Lf", (long double)value); trim_zeros = 0; }
602
- else if(isgreaterequal(abs, 100)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.1Lf", (long double)value);
603
- else if(isgreaterequal(abs, 1)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.2Lf", (long double)value);
604
- else if(isgreaterequal(abs, 0.1)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.3Lf", (long double)value);
605
- else len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.4Lf", (long double)value);
606
-
607
- if(unlikely(trim_zeros)) {
608
- int l;
609
- // remove trailing zeros from the decimal part
610
- for(l = len - 1; l > lstop ; l--) {
611
- if(likely(value_string[l] == '0')) {
612
- value_string[l] = '\0';
613
- len--;
614
- }
732
+ else if(unlikely(value_string[l] == '.')) {
733
+ value_string[l] = '\0';
734
+ len--;
735
+ break;
736
+ }
737
616
- else if(unlikely(value_string[l] == '.')) {
617
- value_string[l] = '\0';
618
- len--;
619
- break;
738
+ else
739
+ break;
740
}
621
-
622
- else
623
- break;
741
}
625
- }
742
627
- if(len >= 0)
628
- snprintfz(&value_string[len], VALUE_STRING_SIZE - len, "%s%s", separator, units);
629
- }
630
- else {
631
- if(precision > 50) precision = 50;
632
- snprintfz(value_string, VALUE_STRING_SIZE, "%0.*Lf%s%s", precision, (long double)value, separator, units);
743
+ if(len >= 0)
744
+ snprintfz(&value_string[len], VALUE_STRING_SIZE - len, "%s%s", separator, units);
745
+ }
746
+ else {
747
+ if(precision > 50) precision = 50;
748
+ snprintfz(value_string, VALUE_STRING_SIZE, "%0.*Lf%s%s", precision, (long double) value, separator, units);
749
+ }
750
}
751
752
// we need to copy the label, since verdana11_width may write to it
src/web_client.c
+7
-10
@@ -982,9 +982,6 @@ int web_client_api_request_v1_badge(struct web_client *w, char *url) {
982
);
983
984
if(rc) {
985
- calculated_number n = rc->value;
986
- if(isnan(n) || isinf(n)) n = 0;
987
-
985
if (refresh > 0) {
986
buffer_sprintf(w->response.header, "Refresh: %d\r\n", refresh);
987
w->response.data->expires = now_realtime_sec() + refresh;
@@ -1020,13 +1017,13 @@ int web_client_api_request_v1_badge(struct web_client *w, char *url) {
1017
}
1018
1019
buffer_svg(w->response.data,
1023
- label,
1024
- rc->value * multiply / divide,
1025
- units,
1026
- label_color,
1027
- value_color,
1028
- 0,
1029
- precision);
1020
+ label,
1021
+ (isnan(rc->value)||isinf(rc->value)) ? rc->value : rc->value * multiply / divide,
1022
+ units,
1023
+ label_color,
1024
+ value_color,
1025
+ 0,
1026
+ precision);
1027
ret = 200;
1028
}
1029
else {
web/index.html
+6
-3
@@ -1572,10 +1572,13 @@
1572
+ ((typeof alarm.crit !== 'undefined')?('<tr><td width="10%" style="text-align:right">critical when</td><td><span style="font-family: monospace; color: #e05d44; font-weight: bold;">' + alarm.crit + '</span></td></tr>'):'');
1573
1574
if(full === true) {
1575
- html += ((typeof alarm.lookup_after !== 'undefined')?('<tr><td width="10%" style="text-align:right">db lookup</td><td>' + alarm_lookup_explain(alarm, chart) + '</td></tr>'):'')
1575
+ var units = chart.units;
1576
+ if(units === '%') units = '%';
1577
+
1578
+ html += ((typeof alarm.lookup_after !== 'undefined')?('<tr><td width="10%" style="text-align:right">db lookup</td><td>' + alarm_lookup_explain(alarm, chart) + '</td></tr>'):'')
1579
+ ((typeof alarm.calc !== 'undefined')?('<tr><td width="10%" style="text-align:right">calculation</td><td><span style="font-family: monospace;">' + alarm.calc + '</span></td></tr>'):'')
1577
- + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green threshold</td><td><code>' + chart.green + ' ' + chart.units + '</code></td></tr>'):'')
1578
- + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red threshold</td><td><code>' + chart.red + ' ' + chart.units + '</code></td></tr>'):'');
1580
+ + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green threshold</td><td><code>' + chart.green + ' ' + units + '</code></td></tr>'):'')
1581
+ + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red threshold</td><td><code>' + chart.red + ' ' + units + '</code></td></tr>'):'');
1582
}
1583
1584
var delay = '';