]> arthur.barton.de Git - netdata.git/commitdiff
added fping alarms and various aesthetic improvements to alarms
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Thu, 26 Jan 2017 00:42:11 +0000 (02:42 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Thu, 26 Jan 2017 00:42:11 +0000 (02:42 +0200)
conf.d/Makefile.am
conf.d/health.d/disks.conf
conf.d/health.d/fping.conf [new file with mode: 0644]
conf.d/health.d/memcached.conf
conf.d/health.d/mysql.conf
src/web_buffer_svg.c
src/web_client.c
web/index.html

index b725e249e8fe7c67e27496a7ac871bdf295f3fd0..e17d8fa929f547cddcb790218cd7472127c346b5 100644 (file)
@@ -64,6 +64,7 @@ dist_healthconfig_DATA = \
     health.d/disks.conf \
     health.d/elasticsearch.conf \
     health.d/entropy.conf \
+    health.d/fping.conf \
     health.d/haproxy.conf \
     health.d/ipc.conf \
     health.d/ipfs.conf \
index 0549bac268b51ea0034c1b8b6edc025d5d2a05d2..ff2d6a605ad3bdae4b9fa3e519356295bc7cb9f5 100644 (file)
@@ -88,7 +88,7 @@ families: *
 template: out_of_disk_space_time
       on: disk.space
 families: *
-    calc: ($disk_fill_rate > 0) ? ($avail / $disk_fill_rate) : (0)
+    calc: ($disk_fill_rate > 0) ? ($avail / $disk_fill_rate) : (inf)
    units: hours
    every: 10s
     warn: $this > 0 and $this < (($status >= $WARNING)  ? (48) : (8))
diff --git a/conf.d/health.d/fping.conf b/conf.d/health.d/fping.conf
new file mode 100644 (file)
index 0000000..3cafddb
--- /dev/null
@@ -0,0 +1,26 @@
+template: host_health
+families: *
+      on: fping.latency
+    calc: $average != nan
+   units: up/down
+   every: 10s
+    crit: $this == 0
+    info: the ping status
+   delay: down 30m multiplier 1.5 max 2h
+      to: sysadmin
+
+template: packet_loss
+families: *
+      on: fping.quality
+  lookup: average -10m of returned
+    calc: 100 - $this
+   green: 1
+     red: 10
+   units: %
+   every: 10s
+    warn: $this > $green
+    crit: $this > $red
+    info: the percentage of packet loss
+   delay: down 30m multiplier 1.5 max 2h
+      to: sysadmin
+
index 7917e36afb61f031c91e1e52cc39ccccc4aa68f2..d248ef57a7204966a41ae9d2cf73f3dc917dddd3 100644 (file)
@@ -42,7 +42,7 @@ template: cache_fill_rate
 
 template: out_of_cache_space_time
       on: memcached.cache
-    calc: ($cache_fill_rate > 0) ? ($available / $cache_fill_rate) : (0)
+    calc: ($cache_fill_rate > 0) ? ($available / $cache_fill_rate) : (inf)
    units: hours
    every: 10s
     warn: $this > 0 and $this < (($status >= $WARNING)  ? (48) : (8))
index 78773e5b5b0b141489d334cbdbaf0b5bbe535b11..1eeb993f039a59742d9bfc9c551513d5b2d97878 100644 (file)
@@ -49,7 +49,7 @@ template: mysql_10s_table_locks_waited
 
 template: mysql_10s_waited_locks_ratio
       on: mysql.table_locks
-    calc: ($mysql_10s_table_locks_waited * 100) / ($mysql_10s_table_locks_waited + $mysql_10s_table_locks_immediate)
+    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
    units: %
    every: 10s
     warn: $this > (($status >= $WARNING)  ? (10) : (25))
@@ -65,7 +65,7 @@ template: mysql_10s_waited_locks_ratio
 template: mysql_replication
       on: mysql.slave_status
     calc: ($sql_running == -1 OR $io_running == -1)?0:1
-   units: status
+   units: ok/failed
    every: 10s
     crit: $this == 0
    delay: down 5m multiplier 1.5 max 1h
index 0f8f3d7dac8a2829c841e96b770d7a1b95eef8f7..31b193a5097d847929e9522b490220d130e38e63 100644 (file)
@@ -368,10 +368,179 @@ cleanup:
     return len - i;
 }
 
-static inline const char *fix_units(const char *units) {
-    if(!units || !*units || !strcmp(units, "empty") || !strcmp(units, "null")) return "";
-    if(!strcmp(units, "percentage") || !strcmp(units, "percent") || !strcmp(units, "pcent")) return "%";
-    return units;
+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) {
+    static uint32_t
+            hash_seconds = 0,
+            hash_seconds_ago = 0,
+            hash_minutes = 0,
+            hash_minutes_ago = 0,
+            hash_hours = 0,
+            hash_hours_ago = 0,
+            hash_onoff = 0,
+            hash_updown = 0,
+            hash_okerror = 0,
+            hash_okfailed = 0,
+            hash_empty = 0,
+            hash_null = 0,
+            hash_percentage = 0,
+            hash_percent = 0,
+            hash_pcent = 0;
+
+    if(unlikely(!hash_seconds)) {
+        hash_seconds     = simple_hash("seconds");
+        hash_seconds_ago = simple_hash("seconds ago");
+        hash_minutes     = simple_hash("minutes");
+        hash_minutes_ago = simple_hash("minutes ago");
+        hash_hours       = simple_hash("hours");
+        hash_hours_ago   = simple_hash("hours ago");
+        hash_onoff       = simple_hash("on/off");
+        hash_updown      = simple_hash("up/down");
+        hash_okerror     = simple_hash("ok/error");
+        hash_okfailed    = simple_hash("ok/failed");
+        hash_empty       = simple_hash("empty");
+        hash_null        = simple_hash("null");
+        hash_percentage  = simple_hash("percentage");
+        hash_percent     = simple_hash("percent");
+        hash_pcent       = simple_hash("pcent");
+    }
+
+    const char *units = (units_ptr)?*units_ptr:NULL;
+    if(unlikely(!units)) units = "";
+
+    uint32_t hash_units = simple_hash(units);
+
+    if(unlikely((hash_units == hash_seconds && !strcmp(units, "seconds")) || (hash_units == hash_seconds_ago && !strcmp(units, "seconds ago")))) {
+        if(value == 0.0) {
+            snprintfz(value_string, value_string_len, "%s", "now");
+            units = "";
+            goto finish;
+        }
+        else if(isnan(value) || isinf(value)) {
+            snprintfz(value_string, value_string_len, "%s", "never");
+            units = "";
+            goto finish;
+        }
+
+        const char *suffix = (hash_units == hash_seconds_ago)?" ago":"";
+
+        size_t s = (size_t)value;
+        size_t d = s / 86400;
+        s = s % 86400;
+
+        size_t h = s / 3600;
+        s = s % 3600;
+
+        size_t m = s / 60;
+        s = s % 60;
+
+        if(d)
+            snprintfz(value_string, value_string_len, "%zu %s %02zu:%02zu:%02zu%s", d, (d == 1)?"day":"days", h, m, s, suffix);
+        else
+            snprintfz(value_string, value_string_len, "%02zu:%02zu:%02zu%s", h, m, s, suffix);
+
+        units = "";
+    }
+
+    else if(unlikely((hash_units == hash_minutes && !strcmp(units, "minutes")) || (hash_units == hash_minutes_ago && !strcmp(units, "minutes ago")))) {
+        if(value == 0.0) {
+            snprintfz(value_string, value_string_len, "%s", "now");
+            units = "";
+            goto finish;
+        }
+        else if(isnan(value) || isinf(value)) {
+            snprintfz(value_string, value_string_len, "%s", "never");
+            units = "";
+            goto finish;
+        }
+
+        const char *suffix = (hash_units == hash_minutes_ago)?" ago":"";
+
+        size_t m = (size_t)value;
+        size_t d = m / (60 * 24);
+        m = m % (60 * 24);
+
+        size_t h = m / 60;
+        m = m % 60;
+
+        if(d)
+            snprintfz(value_string, value_string_len, "%zud %02zuh %02zum%s", d, h, m, suffix);
+        else
+            snprintfz(value_string, value_string_len, "%zuh %zum%s", h, m, suffix);
+
+        units = "";
+    }
+
+    else if(unlikely((hash_units == hash_hours && !strcmp(units, "hours")) || (hash_units == hash_hours_ago && !strcmp(units, "hours ago")))) {
+        if(value == 0.0) {
+            snprintfz(value_string, value_string_len, "%s", "now");
+            units = "";
+            goto finish;
+        }
+        else if(isnan(value) || isinf(value)) {
+            snprintfz(value_string, value_string_len, "%s", "never");
+            units = "";
+            goto finish;
+        }
+
+        const char *suffix = (hash_units == hash_hours_ago)?" ago":"";
+
+        size_t h = (size_t)value;
+        size_t d = h / 24;
+        h = h % 24;
+
+        if(d)
+            snprintfz(value_string, value_string_len, "%zud %zuh%s", d, h, suffix);
+        else
+            snprintfz(value_string, value_string_len, "%zuh%s", h, suffix);
+
+        units = "";
+    }
+
+    else if(unlikely(hash_units == hash_onoff && !strcmp(units, "on/off"))) {
+        snprintfz(value_string, value_string_len, "%s", (value != 0.0)?"on":"off");
+        units = "";
+    }
+
+    else if(unlikely(hash_units == hash_updown && !strcmp(units, "up/down"))) {
+        snprintfz(value_string, value_string_len, "%s", (value != 0.0)?"up":"down");
+        units = "";
+    }
+
+    else if(unlikely(hash_units == hash_okerror && !strcmp(units, "ok/error"))) {
+        snprintfz(value_string, value_string_len, "%s", (value != 0.0)?"ok":"error");
+        units = "";
+    }
+
+    else if(unlikely(hash_units == hash_okfailed && !strcmp(units, "ok/failed"))) {
+        snprintfz(value_string, value_string_len, "%s", (value != 0.0)?"ok":"failed");
+        units = "";
+    }
+
+    else if(unlikely(hash_units == hash_empty && !strcmp(units, "empty")))
+        units = "";
+
+    else if(unlikely(hash_units == hash_null && !strcmp(units, "null")))
+        units = "";
+
+    else if(unlikely(hash_units == hash_percentage && !strcmp(units, "percentage")))
+        units = "%";
+
+    else if(unlikely(hash_units == hash_percent && !strcmp(units, "percent")))
+        units = "%";
+
+    else if(unlikely(hash_units == hash_pcent && !strcmp(units, "pcent")))
+        units = "%";
+
+    else if(unlikely(value_is_null)) {
+        strcpy(value_string, "-");
+        units = "";
+    }
+    else
+        return 0;
+
+finish:
+    if(units_ptr) *units_ptr = units;
+    return 1;
 }
 
 static inline const char *color_map(const char *color) {
@@ -392,6 +561,9 @@ static inline const char *color_map(const char *color) {
 }
 
 static inline void calc_colorz(const char *color, char *final, size_t len, calculated_number value, int value_is_null) {
+    if(isnan(value) || isinf(value))
+        value = 0.0;
+
     char color_buffer[256 + 1] = "";
     char value_buffer[256 + 1] = "";
     char comparison = '>';
@@ -502,17 +674,6 @@ static inline void calc_colorz(const char *color, char *final, size_t len, calcu
 #define COLOR_STRING_SIZE 100
 
 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) {
-    static uint32_t hash_seconds = 0, hash_seconds_ago = 0, hash_minutes = 0, hash_minutes_ago = 0, hash_hours = 0, hash_hours_ago = 0;
-
-    if(unlikely(!hash_seconds)) {
-        hash_seconds     = simple_hash("seconds");
-        hash_seconds_ago = simple_hash("seconds ago");
-        hash_minutes     = simple_hash("minutes");
-        hash_minutes_ago = simple_hash("minutes ago");
-        hash_hours       = simple_hash("hours");
-        hash_hours_ago   = simple_hash("hours ago");
-    }
-
     char      label_buffer[LABEL_STRING_SIZE + 1]
             , value_color_buffer[COLOR_STRING_SIZE + 1]
             , value_string[VALUE_STRING_SIZE + 1]
@@ -529,107 +690,63 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
     if(unlikely(!value_color || !*value_color))
         value_color = (value_is_null)?"#999":"#4c1";
 
-    units = fix_units(units);
     calc_colorz(value_color, value_color_buffer, COLOR_STRING_SIZE, value, value_is_null);
 
-    char *separator = "";
-    if(unlikely(isalnum(*units)))
-        separator = " ";
+    if(!fix_value_and_units(value_string, VALUE_STRING_SIZE, value, &units, value_is_null)) {
+        // we have to print the value
 
-    uint32_t hash_units = simple_hash(units);
+        if(isnan(value) || isinf(value))
+            value = 0.0;
 
-    if(unlikely((hash_units == hash_seconds && !strcmp(units, "seconds")) || (hash_units == hash_seconds_ago && !strcmp(units, "seconds ago")))) {
-        char *suffix = (hash_units == hash_seconds_ago)?" ago":"";
-
-        size_t s = (size_t)value;
-        size_t d = s / 86400;
-        s = s % 86400;
-
-        size_t h = s / 3600;
-        s = s % 3600;
-
-        size_t m = s / 60;
-        s = s % 60;
+        char *separator = "";
+        if(unlikely(isalnum(*units)))
+            separator = " ";
 
-        if(d)
-            snprintfz(value_string, VALUE_STRING_SIZE, "%zu %s %02zu:%02zu:%02zu%s", d, (d == 1)?"day":"days", h, m, s, suffix);
-        else
-            snprintfz(value_string, VALUE_STRING_SIZE, "%02zu:%02zu:%02zu%s", h, m, s, suffix);
-    }
+        if(precision < 0) {
+            int len, lstop = 0, trim_zeros = 1;
 
-    else if(unlikely((hash_units == hash_minutes && !strcmp(units, "minutes")) || (hash_units == hash_minutes_ago && !strcmp(units, "minutes ago")))) {
-        char *suffix = (hash_units == hash_minutes_ago)?" ago":"";
-
-        size_t m = (size_t)value;
-        size_t d = m / (60 * 24);
-        m = m % (60 * 24);
-
-        size_t h = m / 60;
-        m = m % 60;
-
-        if(d)
-            snprintfz(value_string, VALUE_STRING_SIZE, "%zud %02zuh %02zum%s", d, h, m, suffix);
-        else
-            snprintfz(value_string, VALUE_STRING_SIZE, "%zuh %zum%s", h, m, suffix);
-    }
-
-    else if(unlikely((hash_units == hash_hours && !strcmp(units, "hours")) || (hash_units == hash_hours_ago && !strcmp(units, "hours ago")))) {
-        char *suffix = (hash_units == hash_hours_ago)?" ago":"";
-
-        size_t h = (size_t)value;
-        size_t d = h / 24;
-        h = h % 24;
-
-        if(d)
-            snprintfz(value_string, VALUE_STRING_SIZE, "%zud %zuh%s", d, h, suffix);
-        else
-            snprintfz(value_string, VALUE_STRING_SIZE, "%zuh%s", h, suffix);
-    }
-
-    else if(unlikely(value_is_null))
-        strcpy(value_string, "-");
-
-    else if(precision < 0) {
-        int len, lstop = 0, trim_zeros = 1;
+            calculated_number abs = value;
+            if(isless(value, 0)) {
+                lstop = 1;
+                abs = -value;
+            }
 
-        calculated_number abs = value;
-        if(isless(value, 0)) {
-            lstop = 1;
-            abs = -value;
-        }
+            if(isgreaterequal(abs, 1000)) {
+                len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.0Lf", (long double) value);
+                trim_zeros = 0;
+            }
+            else if(isgreaterequal(abs, 100)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.1Lf", (long double) value);
+            else if(isgreaterequal(abs, 1))   len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.2Lf", (long double) value);
+            else if(isgreaterequal(abs, 0.1)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.3Lf", (long double) value);
+            else                              len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.4Lf", (long double) value);
+
+            if(unlikely(trim_zeros)) {
+                int l;
+                // remove trailing zeros from the decimal part
+                for(l = len - 1; l > lstop; l--) {
+                    if(likely(value_string[l] == '0')) {
+                        value_string[l] = '\0';
+                        len--;
+                    }
 
-        if(isgreaterequal(abs, 1000))     { len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.0Lf", (long double)value); trim_zeros = 0; }
-        else if(isgreaterequal(abs, 100))   len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.1Lf", (long double)value);
-        else if(isgreaterequal(abs, 1))     len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.2Lf", (long double)value);
-        else if(isgreaterequal(abs, 0.1))   len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.3Lf", (long double)value);
-        else                                len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.4Lf", (long double)value);
-
-        if(unlikely(trim_zeros)) {
-            int l;
-            // remove trailing zeros from the decimal part
-            for(l = len - 1; l > lstop ; l--) {
-                if(likely(value_string[l] == '0')) {
-                    value_string[l] = '\0';
-                    len--;
-                }
+                    else if(unlikely(value_string[l] == '.')) {
+                        value_string[l] = '\0';
+                        len--;
+                        break;
+                    }
 
-                else if(unlikely(value_string[l] == '.')) {
-                    value_string[l] = '\0';
-                    len--;
-                    break;
+                    else
+                        break;
                 }
-
-                else
-                    break;
             }
-        }
 
-        if(len >= 0)
-            snprintfz(&value_string[len], VALUE_STRING_SIZE - len, "%s%s", separator, units);
-    }
-    else {
-        if(precision > 50) precision = 50;
-        snprintfz(value_string, VALUE_STRING_SIZE, "%0.*Lf%s%s", precision, (long double)value, separator, units);
+            if(len >= 0)
+                snprintfz(&value_string[len], VALUE_STRING_SIZE - len, "%s%s", separator, units);
+        }
+        else {
+            if(precision > 50) precision = 50;
+            snprintfz(value_string, VALUE_STRING_SIZE, "%0.*Lf%s%s", precision, (long double) value, separator, units);
+        }
     }
 
     // we need to copy the label, since verdana11_width may write to it
index 4b6ccf6469e7d1c9070be807028dd949c6294941..7932a5260e56778bd010454cfb37240113cf5789 100644 (file)
@@ -982,9 +982,6 @@ int web_client_api_request_v1_badge(struct web_client *w, char *url) {
             );
 
     if(rc) {
-        calculated_number n = rc->value;
-        if(isnan(n) || isinf(n)) n = 0;
-
         if (refresh > 0) {
             buffer_sprintf(w->response.header, "Refresh: %d\r\n", refresh);
             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) {
         }
 
         buffer_svg(w->response.data,
-                   label,
-                   rc->value * multiply / divide,
-                   units,
-                   label_color,
-                   value_color,
-                   0,
-                   precision);
+                label,
+                (isnan(rc->value)||isinf(rc->value)) ? rc->value : rc->value * multiply / divide,
+                units,
+                label_color,
+                value_color,
+                0,
+                precision);
         ret = 200;
     }
     else {
index d8e1282344daca504ae02de53fc4991bfa4988d2..e95e31513aabd23fd494642c238d56b5b107bc27 100644 (file)
                         + ((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>'):'');
 
                     if(full === true) {
-                            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>'):'')
+                        var units = chart.units;
+                        if(units === '%') units = '&#37;';
+
+                        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>'):'')
                             + ((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>'):'')
-                            + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green&nbsp;threshold</td><td><code>' + chart.green + ' ' + chart.units + '</code></td></tr>'):'')
-                            + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red&nbsp;threshold</td><td><code>' + chart.red + ' ' + chart.units + '</code></td></tr>'):'');
+                            + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green&nbsp;threshold</td><td><code>' + chart.green + ' ' + units + '</code></td></tr>'):'')
+                            + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red&nbsp;threshold</td><td><code>' + chart.red + ' ' + units + '</code></td></tr>'):'');
                     }
 
                     var delay = '';