@cryptotaxi247 / netdata-1 / commits / 6a0aee81a

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&nbsp;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&nbsp;lookup</td><td>' + alarm_lookup_explain(alarm, chart) + '</td></tr>'):'')
1575 + var units = chart.units;
1576 + if(units === '%') units = '&#37;';
1577 +
1578 + html += ((typeof alarm.lookup_after !== 'undefined')?('<tr><td width="10%" style="text-align:right">db&nbsp;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&nbsp;threshold</td><td><code>' + chart.green + ' ' + chart.units + '</code></td></tr>'):'')
1578 - + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red&nbsp;threshold</td><td><code>' + chart.red + ' ' + chart.units + '</code></td></tr>'):'');
1580 + + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green&nbsp;threshold</td><td><code>' + chart.green + ' ' + units + '</code></td></tr>'):'')
1581 + + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red&nbsp;threshold</td><td><code>' + chart.red + ' ' + units + '</code></td></tr>'):'');
1582 }
1583
1584 var delay = '';