added units and info to alarms and templates - now all alarm badges are a log more nice
Costa Tsaousis committed
Aug 27, 2016 at 20:26 UTC
bb64457c9125fa134495ec30b9e6733594bace0d
21 files changed
+190
-47
conf.d/health.d/apache.conf
+3
@@ -7,4 +7,7 @@ template: apache_last_collected_secs
7
every: 10s
8
warn: $this > ( 5 * $update_every)
9
crit: $this > (10 * $update_every)
10
+ units: seconds ago
11
+ info: number of seconds since the last successful data collection
12
+
13
conf.d/health.d/cpu.conf
+6
@@ -4,15 +4,21 @@ template: 5min_cpu_pcent
4
lookup: average -5m unaligned of user,system,nice,softirq,irq,guest,guest_nice
5
every: 1m
6
warn: $this > 90
7
+ units: %
8
+ info: average cpu utilization for the last 5 minutes
9
10
template: 5min_iowait_cpu_pcent
11
on: system.cpu
12
lookup: average -5m unaligned of iowait
13
every: 1m
14
warn: $this > 10
15
+ units: %
16
+ info: average wait I/O for the last 5 minutes
17
18
template: 20min_steal_cpu_pcent
19
on: system.cpu
20
lookup: average -20m unaligned of steal
21
every: 5m
22
warn: $this > 10
23
+ units: %
24
+ info: average stolen CPU time for the last 20 minutes
conf.d/health.d/disks.conf
+10
@@ -11,6 +11,8 @@ template: disk_full_percent
11
every: 1m
12
warn: $this > 80
13
crit: $this > 95
14
+ units: %
15
+ info: current disk space usage
16
17
18
# -----------------------------------------------------------------------------
@@ -29,6 +31,8 @@ template: disk_fill_rate
31
lookup: max -1s at -30m unaligned of avail
32
calc: ($this - $avail) / ($now - $after)
33
every: 15s
34
+ units: MB/s
35
+ info: average rate the disk fills up (positive), or frees up (negative) space, for the last 30 minutes
36
37
38
# calculate the hours remaining
@@ -41,6 +45,8 @@ template: disk_full_after_hours
45
every: 10s
46
warn: $this > 0 and $this < 48
47
crit: $this > 0 and $this < 24
48
+ units: hours
49
+ info: estimated time the disk will run out of space, if the system continues to add data with the rate of the last 30 minutes
50
51
52
# -----------------------------------------------------------------------------
@@ -58,6 +64,8 @@ template: 10min_disk_utilization
64
red: 98
65
warn: $this > $green
66
crit: $this > $red
67
+ units: %
68
+ info: the percentage of time the disk was busy, during the last 10 minutes
69
70
71
# raise an alarm if the disk backlog
@@ -73,3 +81,5 @@ template: 10min_disk_backlog
81
red: 2000
82
warn: $this > $green
83
crit: $this > $red
84
+ units: ms
85
+ info: average of the kernel estimated disk backlog, for the last 10 minutes
conf.d/health.d/entropy.conf
+2
@@ -9,3 +9,5 @@
9
every: 1m
10
warn: $this < 200
11
crit: $this < 100
12
+ units: entries
13
+ info: minimum entries in the random numbers pool (entropy), for the last 30 minutes
conf.d/health.d/memcached.conf
+9
-4
@@ -2,12 +2,13 @@
2
# make sure memcached is running
3
4
template: memcached_last_collected_secs
5
- on: memcached.connections
5
+ on: memcached.cache
6
calc: $now - $last_collected_t
7
every: 10s
8
warn: $this > ( 5 * $update_every)
9
crit: $this > (10 * $update_every)
10
-
10
+ units: seconds ago
11
+ info: number of seconds since the last successful data collection
12
13
14
# detect if memcached cache is full
@@ -18,7 +19,8 @@ template: cache_full_pcent
19
every: 10s
20
warn: $this > 80
21
crit: $this > 90
21
-
22
+ units: %
23
+ info: current cache memory usage
24
25
26
# find the rate memcached cache is filling
@@ -28,7 +30,8 @@ template: cache_fill_rate
30
lookup: max -1s at -30m unaligned of available
31
calc: ($this - $available) / ($now - $after)
32
every: 15s
31
-
33
+ units: KB/s
34
+ info: average rate the cache fills up (positive), or frees up (negative) space, for the last 30 minutes
35
36
37
# find the hours remaining until memcached cache is full
@@ -39,3 +42,5 @@ template: cache_full_after_hours
42
every: 10s
43
warn: $this > 0 and $this < 48
44
crit: $this > 0 and $this < 24
45
+ units: hours
46
+ info: estimated time the cache will run out of space, if the system continues to add data with the rate of the last 30 minutes
conf.d/health.d/named.conf
+2
@@ -7,4 +7,6 @@ template: named_last_collected_secs
7
every: 10s
8
warn: $this > ( 5 * $update_every)
9
crit: $this > (10 * $update_every)
10
+ units: seconds ago
11
+ info: number of seconds since the last successful data collection
12
conf.d/health.d/net.conf
+4
@@ -8,6 +8,8 @@ template: 30min_packet_drops
8
lookup: sum -30m unaligned absolute
9
every: 1m
10
crit: $this > 0
11
+ units: packets
12
+ info: dropped packets in the last 30 minutes
13
14
15
# check if an interface is having FIFO
@@ -20,4 +22,6 @@ template: 30min_fifo_errors
22
lookup: sum -30m unaligned absolute
23
every: 1m
24
crit: $this > 0
25
+ units: errors
26
+ info: network interface fifo errors in the last 30 minutes
27
conf.d/health.d/nginx.conf
+2
@@ -7,4 +7,6 @@ template: nginx_last_collected_secs
7
every: 10s
8
warn: $this > ( 5 * $update_every)
9
crit: $this > (10 * $update_every)
10
+ units: seconds ago
11
+ info: number of seconds since the last successful data collection
12
conf.d/health.d/qos.conf
+2
-1
@@ -8,4 +8,5 @@
8
# lookup: sum -10m unaligned absolute
9
# every: 30s
10
# warn: $this > 0
11
-
11
+# units: packets
12
+# info: dropped packets in the last 30 minutes
conf.d/health.d/ram.conf
+2
@@ -5,3 +5,5 @@
5
every: 10s
6
warn: $this > 80
7
crit: $this > 90
8
+ units: %
9
+ info: system RAM usage
conf.d/health.d/redis.conf
+2
@@ -7,4 +7,6 @@ template: redis_last_collected_secs
7
every: 10s
8
warn: $this > ( 5 * $update_every)
9
crit: $this > (10 * $update_every)
10
+ units: seconds ago
11
+ info: number of seconds since the last successful data collection
12
conf.d/health.d/squid.conf
+2
@@ -7,4 +7,6 @@ template: squid_last_collected_secs
7
every: 10s
8
warn: $this > ( 5 * $update_every)
9
crit: $this > (10 * $update_every)
10
+ units: seconds ago
11
+ info: number of seconds since the last successful data collection
12
conf.d/health.d/swap.conf
+5
-1
@@ -1,5 +1,5 @@
1
2
- alarm: 30min_pcent_of_ram_swapped_out
2
+ alarm: 30min_ram_swapped_out
3
on: system.swapio
4
lookup: sum -30m unaligned absolute of out
5
# we have to convert KB to MB by dividing $this (i.e. the result of the lookup) with 1024
@@ -7,6 +7,8 @@
7
every: 1m
8
warn: $this > 1
9
crit: $this > 10
10
+ units: % of RAM
11
+ info: the sum of all memory swapped out during the last 30 minutes, as a percentage of the available RAM
12
13
alarm: pcent_of_ram_in_swap
14
on: system.swap
@@ -14,3 +16,5 @@
16
every: 10s
17
warn: $this > 10
18
crit: $this > 50
19
+ units: % of RAM
20
+ info: the currently used swap space, as a percentage of the available RAM
plugins.d/alarm-email.sh
+6
-2
@@ -31,6 +31,10 @@ old_value="${7}" # the previous value
31
src="${8}" # the line number and file the alarm has been configured
32
duration="${9}" # the duration in seconds the previous state took
33
non_clear_duration="${10}" # the total duration in seconds this is non-clear
34
+units="${11}" # the units of the value
35
+info="${12}" # a short description of the alarm
36
+
37
+[ ! -z "${info}" ] && info=" <br/>${info}"
38
39
# get the system hostname
40
hostname="${NETDATA_HOSTNAME}"
@@ -93,7 +97,7 @@ severity="${status}"
97
raised_for="<br/>(was ${old_status,,} for $(duration4human ${duration}))"
98
status_message="status unknown"
99
color="grey"
96
-alarm="${name} = ${value}"
100
+alarm="${name} = ${value} ${units}"
101
102
# prepare the title based on status
103
case "${status}" in
@@ -200,7 +204,7 @@ Content-Type: text/html
204
<tr style="margin:0;padding:0">
205
<td style="font-size:18px;vertical-align:top;margin:0;padding:0 0 20px"
206
align="left" valign="top">
203
- <span>${alarm}</span>
207
+ <span>${alarm}${info}</span>
208
<span style="display:block;color:#666666;font-size:12px;font-weight:300;line-height:1;text-transform:uppercase">Alarm</span>
209
</td>
210
</tr>
src/common.c
+1
-3
@@ -916,9 +916,7 @@ int vsnprintfz(char *dst, size_t n, const char *fmt, va_list args) {
916
int size = vsnprintf(dst, n, fmt, args);
917
918
if (unlikely((size_t) size > n)) {
919
- // there is bug in vsnprintf() and it returns
920
- // a number higher to len, but it does not
921
- // overflow the buffer.
919
+ // truncated
920
size = (int)n;
921
}
922
src/health.c
+96
-14
@@ -467,6 +467,8 @@ static void rrdsetcalc_link(RRDSET *st, RRDCALC *rc) {
467
468
snprintfz(fullname, RRDVAR_MAX_LENGTH, "%s.%s", st->name, rc->name);
469
rc->hostname = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, fullname, RRDVAR_TYPE_CALCULATED, &rc->value);
470
+
471
+ if(!rc->units) rc->units = strdupz(st->units);
472
}
473
474
static inline int rrdcalc_is_matching_this_rrdset(RRDCALC *rc, RRDSET *st) {
@@ -604,8 +606,9 @@ static inline uint32_t rrdcalc_fullname(char *fullname, size_t len, const char *
606
return simple_hash(fullname);
607
}
608
607
-static inline RRDCALC *rrdcalc_create(RRDHOST *host, const char *name, const char *chart, const char *dimensions, int group_method,
608
- int after, int before, int update_every, uint32_t options,
609
+static inline RRDCALC *rrdcalc_create(RRDHOST *host, const char *name, const char *chart, const char *dimensions,
610
+ const char *units, const char *info,
611
+ int group_method, int after, int before, int update_every, uint32_t options,
612
calculated_number green, calculated_number red,
613
const char *exec, const char *source,
614
const char *calc, const char *warn, const char *crit) {
@@ -639,6 +642,8 @@ static inline RRDCALC *rrdcalc_create(RRDHOST *host, const char *name, const cha
642
643
if(exec) rc->exec = strdupz(exec);
644
if(source) rc->source = strdupz(source);
645
+ if(units) rc->units = strdupz(units);
646
+ if(info) rc->info = strdupz(info);
647
648
if(calc) {
649
rc->calculation = expression_parse(calc, NULL, NULL);
@@ -706,11 +711,14 @@ void rrdcalc_free(RRDHOST *host, RRDCALC *rc) {
711
expression_free(rc->warning);
712
expression_free(rc->critical);
713
709
- freez(rc->source);
714
freez(rc->name);
715
freez(rc->chart);
716
+ freez(rc->family);
717
freez(rc->dimensions);
718
freez(rc->exec);
719
+ freez(rc->source);
720
+ freez(rc->units);
721
+ freez(rc->info);
722
freez(rc);
723
}
724
@@ -724,7 +732,7 @@ void rrdcalctemplate_link_matching(RRDSET *st) {
732
if(rt->hash_context == st->hash_context && !strcmp(rt->context, st->context)) {
733
734
RRDCALC *rc = rrdcalc_create(st->rrdhost, rt->name, st->id,
727
- rt->dimensions, rt->group, rt->after, rt->before, rt->update_every, rt->options,
735
+ rt->dimensions, rt->units, rt->info, rt->group, rt->after, rt->before, rt->update_every, rt->options,
736
rt->green, rt->red, rt->exec, rt->source,
737
(rt->calculation)?rt->calculation->source:NULL,
738
(rt->warning)?rt->warning->source:NULL,
@@ -766,11 +774,13 @@ static inline void rrdcalctemplate_free(RRDHOST *host, RRDCALCTEMPLATE *rt) {
774
expression_free(rt->warning);
775
expression_free(rt->critical);
776
769
- freez(rt->dimensions);
770
- freez(rt->context);
777
freez(rt->name);
778
freez(rt->exec);
779
+ freez(rt->context);
780
freez(rt->source);
781
+ freez(rt->units);
782
+ freez(rt->info);
783
+ freez(rt->dimensions);
784
freez(rt);
785
}
786
@@ -790,6 +800,8 @@ static inline void rrdcalctemplate_free(RRDHOST *host, RRDCALCTEMPLATE *rt) {
800
#define HEALTH_WARN_KEY "warn"
801
#define HEALTH_CRIT_KEY "crit"
802
#define HEALTH_EXEC_KEY "exec"
803
+#define HEALTH_UNITS_KEY "units"
804
+#define HEALTH_INFO_KEY "info"
805
806
static inline int rrdcalc_add_alarm_from_config(RRDHOST *host, RRDCALC *rc) {
807
{
@@ -1034,10 +1046,17 @@ static inline char *health_source_file(size_t line, const char *path, const char
1046
return strdupz(buffer);
1047
}
1048
1049
+static inline void strip_quotes(char *s) {
1050
+ while(*s) {
1051
+ if(*s == '\'' || *s == '"') *s = ' ';
1052
+ s++;
1053
+ }
1054
+}
1055
+
1056
int health_readfile(const char *path, const char *filename) {
1057
debug(D_HEALTH, "Health configuration reading file '%s/%s'", path, filename);
1058
1040
- static uint32_t hash_alarm = 0, hash_template = 0, hash_on = 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;
1059
+ static uint32_t hash_alarm = 0, hash_template = 0, hash_on = 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;
1060
char buffer[HEALTH_CONF_MAX_LINE + 1];
1061
1062
if(unlikely(!hash_alarm)) {
@@ -1052,6 +1071,8 @@ int health_readfile(const char *path, const char *filename) {
1071
hash_crit = simple_uhash(HEALTH_CRIT_KEY);
1072
hash_exec = simple_uhash(HEALTH_EXEC_KEY);
1073
hash_every = simple_uhash(HEALTH_EVERY_KEY);
1074
+ hash_units = simple_hash(HEALTH_UNITS_KEY);
1075
+ hash_info = simple_hash(HEALTH_INFO_KEY);
1076
}
1077
1078
snprintfz(buffer, HEALTH_CONF_MAX_LINE, "%s/%s", path, filename);
@@ -1229,6 +1250,28 @@ int health_readfile(const char *path, const char *filename) {
1250
}
1251
rc->exec = strdupz(value);
1252
}
1253
+ else if(hash == hash_units && !strcasecmp(key, HEALTH_UNITS_KEY)) {
1254
+ if(rc->units) {
1255
+ if(strcmp(rc->units, value))
1256
+ info("Health configuration at line %zu of file '%s/%s' for alarm '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
1257
+ line, path, filename, rc->name, key, rc->units, value, value);
1258
+
1259
+ freez(rc->units);
1260
+ }
1261
+ rc->units = strdupz(value);
1262
+ strip_quotes(rc->units);
1263
+ }
1264
+ else if(hash == hash_info && !strcasecmp(key, HEALTH_INFO_KEY)) {
1265
+ if(rc->info) {
1266
+ if(strcmp(rc->info, value))
1267
+ info("Health configuration at line %zu of file '%s/%s' for alarm '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
1268
+ line, path, filename, rc->name, key, rc->info, value, value);
1269
+
1270
+ freez(rc->info);
1271
+ }
1272
+ rc->info = strdupz(value);
1273
+ strip_quotes(rc->info);
1274
+ }
1275
else {
1276
error("Health configuration at line %zu of file '%s/%s' for alarm '%s' has unknown key '%s'.",
1277
line, path, filename, rc->name, key);
@@ -1309,6 +1352,28 @@ int health_readfile(const char *path, const char *filename) {
1352
}
1353
rt->exec = strdupz(value);
1354
}
1355
+ else if(hash == hash_units && !strcasecmp(key, HEALTH_UNITS_KEY)) {
1356
+ if(rt->units) {
1357
+ if(strcmp(rt->units, value))
1358
+ info("Health configuration at line %zu of file '%s/%s' for template '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
1359
+ line, path, filename, rt->name, key, rt->units, value, value);
1360
+
1361
+ freez(rt->units);
1362
+ }
1363
+ rt->units = strdupz(value);
1364
+ strip_quotes(rt->units);
1365
+ }
1366
+ else if(hash == hash_info && !strcasecmp(key, HEALTH_INFO_KEY)) {
1367
+ if(rt->info) {
1368
+ if(strcmp(rt->info, value))
1369
+ info("Health configuration at line %zu of file '%s/%s' for template '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
1370
+ line, path, filename, rt->name, key, rt->info, value, value);
1371
+
1372
+ freez(rt->info);
1373
+ }
1374
+ rt->info = strdupz(value);
1375
+ strip_quotes(rt->info);
1376
+ }
1377
else {
1378
error("Health configuration at line %zu of file '%s/%s' for template '%s' has unknown key '%s'.",
1379
line, path, filename, rt->name, key);
@@ -1428,6 +1493,8 @@ static inline void health_alarm_entry2json_nolock(BUFFER *wb, ALARM_ENTRY *ae) {
1493
"\t\t\"exec\":\"%s\",\n"
1494
"\t\t\"exec_code\":%d,\n"
1495
"\t\t\"source\":\"%s\",\n"
1496
+ "\t\t\"units\":\"%s\",\n"
1497
+ "\t\t\"info\":\"%s\",\n"
1498
"\t\t\"when\":%lu,\n"
1499
"\t\t\"duration\":%lu,\n"
1500
"\t\t\"non_clear_duration\":%lu,\n"
@@ -1444,6 +1511,8 @@ static inline void health_alarm_entry2json_nolock(BUFFER *wb, ALARM_ENTRY *ae) {
1511
ae->exec?ae->exec:health_default_exec,
1512
ae->exec_code,
1513
ae->source,
1514
+ ae->units?ae->units:"",
1515
+ ae->info?ae->info:"",
1516
(unsigned long)ae->when,
1517
(unsigned long)ae->duration,
1518
(unsigned long)ae->non_clear_duration,
@@ -1489,7 +1558,9 @@ static inline void health_rrdcalc2json_nolock(BUFFER *wb, RRDCALC *rc) {
1558
"\t\t\t\"active\": %s,\n"
1559
"\t\t\t\"exec\": \"%s\",\n"
1560
"\t\t\t\"source\": \"%s\",\n"
1492
- "\t\t\t\"status\": \"%s\",\n"
1561
+ "\t\t\t\"units\": \"%s\",\n"
1562
+ "\t\t\t\"info\": \"%s\",\n"
1563
+ "\t\t\t\"status\": \"%s\",\n"
1564
"\t\t\t\"last_status_change\": %lu,\n"
1565
"\t\t\t\"last_updated\": %lu,\n"
1566
"\t\t\t\"next_update\": %lu,\n"
@@ -1501,6 +1572,8 @@ static inline void health_rrdcalc2json_nolock(BUFFER *wb, RRDCALC *rc) {
1572
, (rc->rrdset)?"true":"false"
1573
, rc->exec?rc->exec:health_default_exec
1574
, rc->source
1575
+ , rc->units?rc->units:""
1576
+ , rc->info?rc->info:""
1577
, rrdcalc_status2string(rc->status)
1578
, (unsigned long)rc->last_status_change
1579
, (unsigned long)rc->last_updated
@@ -1677,7 +1750,7 @@ static inline void health_alarm_execute(ALARM_ENTRY *ae) {
1750
const char *exec = ae->exec;
1751
if(!exec) exec = health_default_exec;
1752
1680
- snprintfz(buffer, FILENAME_MAX, "exec %s '%s' '%s' '%s' '%s' '%s' '%0.0Lf' '%0.0Lf' '%s' '%u' '%u'",
1753
+ snprintfz(buffer, FILENAME_MAX, "exec %s '%s' '%s' '%s' '%s' '%s' '%0.0Lf' '%0.0Lf' '%s' '%u' '%u' '%s' '%s'",
1754
exec,
1755
ae->name,
1756
ae->chart?ae->chart:"NOCAHRT",
@@ -1688,7 +1761,9 @@ static inline void health_alarm_execute(ALARM_ENTRY *ae) {
1761
ae->old_value,
1762
ae->source?ae->source:"UNKNOWN",
1763
(uint32_t)ae->duration,
1691
- (uint32_t)ae->non_clear_duration
1764
+ (uint32_t)ae->non_clear_duration,
1765
+ ae->units?ae->units:"",
1766
+ ae->info?ae->info:""
1767
);
1768
1769
ae->notifications |= HEALTH_ENTRY_NOTIFICATIONS_EXEC_RUN;
@@ -1726,7 +1801,9 @@ static inline void health_alarm_log(RRDHOST *host, time_t when,
1801
const char *exec, time_t duration,
1802
calculated_number old_value, calculated_number new_value,
1803
int old_status, int new_status,
1729
- const char *source
1804
+ const char *source,
1805
+ const char *units,
1806
+ const char *info
1807
) {
1808
ALARM_ENTRY *ae = callocz(1, sizeof(ALARM_ENTRY));
1809
ae->name = strdupz(name);
@@ -1742,6 +1819,8 @@ static inline void health_alarm_log(RRDHOST *host, time_t when,
1819
1820
if(exec) ae->exec = strdupz(exec);
1821
if(source) ae->source = strdupz(source);
1822
+ if(units) ae->units = strdupz(units);
1823
+ if(info) ae->info = strdupz(info);
1824
1825
ae->id = host->health_log.nextid++;
1826
ae->when = when;
@@ -1827,10 +1906,13 @@ static inline void health_alarm_log_process(RRDHOST *host) {
1906
while(ae) {
1907
ALARM_ENTRY *t = ae->next;
1908
1830
- freez(ae->family);
1831
- freez(ae->chart);
1909
freez(ae->name);
1910
+ freez(ae->chart);
1911
+ freez(ae->family);
1912
freez(ae->exec);
1913
+ freez(ae->source);
1914
+ freez(ae->units);
1915
+ freez(ae->info);
1916
freez(ae);
1917
1918
ae = t;
@@ -2071,7 +2153,7 @@ void *health_main(void *ptr) {
2153
}
2154
2155
if(status != rc->status) {
2074
- health_alarm_log(&localhost, time(NULL), rc->name, rc->rrdset->id, rc->rrdset->family, rc->exec, now - rc->last_status_change, rc->old_value, rc->value, rc->status, status, rc->source);
2156
+ health_alarm_log(&localhost, time(NULL), rc->name, rc->rrdset->id, rc->rrdset->family, rc->exec, now - rc->last_status_change, rc->old_value, rc->value, rc->status, status, rc->source, rc->units, rc->info);
2157
rc->last_status_change = now;
2158
rc->status = status;
2159
}
src/health.h
+7
@@ -129,6 +129,8 @@ typedef struct rrdcalc {
129
uint32_t hash_chart;
130
131
char *source; // the source of this calculation
132
+ char *units;
133
+ char *info;
134
135
char *dimensions; // the chart dimensions
136
@@ -185,6 +187,8 @@ typedef struct rrdcalctemplate {
187
uint32_t hash_context;
188
189
char *source; // the source of this template
190
+ char *units;
191
+ char *info;
192
193
char *dimensions;
194
@@ -230,6 +234,9 @@ typedef struct alarm_entry {
234
int exec_code;
235
236
char *source;
237
+ char *units;
238
+ char *info;
239
+
240
calculated_number old_value;
241
calculated_number new_value;
242
int old_status;
src/web_buffer.c
+1
-5
@@ -189,11 +189,7 @@ void buffer_sprintf(BUFFER *wb, const char *fmt, ...)
189
va_end(args);
190
191
if(unlikely(wrote >= len)) {
192
- // there is bug in vsnprintf() and it returns
193
- // a number higher to len, but it does not
194
- // overflow the buffer.
195
- // our buffer overflow detector will log it
196
- // if it does.
192
+ // truncated
193
buffer_overflow_check(wb);
194
195
debug(D_WEB_BUFFER, "web_buffer_sprintf(): increasing web_buffer at position %zu, size = %zu\n", wb->len, wb->size);
src/web_buffer_svg.c
+13
-7
@@ -529,7 +529,7 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
529
strcpy(value_string, "-");
530
531
else if(precision < 0) {
532
- size_t len, l, lstop = 0;
532
+ int len, l, lstop = 0;
533
534
calculated_number abs = value;
535
if(isless(value, 0)) {
@@ -537,25 +537,31 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
537
abs = -value;
538
}
539
540
- if(isgreaterequal(abs, 1000)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.0Lf%s%s", (long double)value, separator, units);
541
- else if(isgreaterequal(abs, 100)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.1Lf%s%s", (long double)value, separator, units);
542
- else if(isgreaterequal(abs, 1)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.2Lf%s%s", (long double)value, separator, units);
543
- else if(isgreaterequal(abs, 0.1)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.3Lf%s%s", (long double)value, separator, units);
544
- else len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.4Lf%s%s", (long double)value, separator, units);
540
+ if(isgreaterequal(abs, 1000)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.0Lf", (long double)value);
541
+ else if(isgreaterequal(abs, 100)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.1Lf", (long double)value);
542
+ else if(isgreaterequal(abs, 1)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.2Lf", (long double)value);
543
+ else if(isgreaterequal(abs, 0.1)) len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.3Lf", (long double)value);
544
+ else len = snprintfz(value_string, VALUE_STRING_SIZE, "%0.4Lf", (long double)value);
545
546
// remove trailing zeros
547
for(l = len - 1; l > lstop ; l--) {
548
- if(likely(value_string[l] == '0'))
548
+ if(likely(value_string[l] == '0')) {
549
value_string[l] = '\0';
550
+ len--;
551
+ }
552
553
else if(unlikely(value_string[l] == '.')) {
554
value_string[l] = '\0';
555
+ len--;
556
break;
557
}
558
559
else
560
break;
561
}
562
+
563
+ if(len >= 0)
564
+ snprintfz(&value_string[len], VALUE_STRING_SIZE - len, "%s%s", separator, units);
565
}
566
else {
567
if(precision > 50) precision = 50;
src/web_client.c
+6
-2
@@ -876,8 +876,12 @@ int web_client_api_request_v1_badge(struct web_client *w, char *url) {
876
label = st->name;
877
}
878
if(!units) {
879
- if(alarm)
880
- units = "";
879
+ if(alarm) {
880
+ if(rc->units)
881
+ units = rc->units;
882
+ else
883
+ units = "";
884
+ }
885
else if(options & RRDR_OPTION_PERCENTAGE)
886
units = "%";
887
else
web/index.html
+9
-8
@@ -2403,9 +2403,9 @@ function renderChartsAndMenu(data) {
2403
}
2404
2405
function alarmsUpdateModal() {
2406
- var active = '<h3>Raised Alarms</h3>';
2407
- var all = '<h3>All Running Alarms</h3>';
2408
- var log = '<h3>Alarm Log</h3>';
2406
+ var active = '<h3>Raised Alarms</h3><table class="table">';
2407
+ var all = '<h3>All Running Alarms</h3><table class="table">';
2408
+ var log = '<h3>Alarm Log</h3><table class="table"><tr><th>When</th><th>Chart</th><th>Alarm</th><th>Status</th></tr>';
2409
var footer = '<hr/>These are <a href="https://github.com/firehol/netdata/wiki/Generating-Badges" target="_blank">netdata badges</a>. You can copy and paste their URLs to embed them in any web page. Their color indicates the state of the alarm: <b>red</b> is critical, <b>orange</b> is warning, <b>bright green</b> is ok, <b>light grey</b> is undefined (i.e. no data or no status), <b>black</b> is not initialized.';
2410
2411
NETDATA.alarms.get('all', function(data) {
@@ -2447,20 +2447,22 @@ function alarmsUpdateModal() {
2447
if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL') {
2448
if(!active_family_added) {
2449
active_family_added = true;
2450
- active += '<h4>' + x + '</h4>';
2450
+ active += '<tr><th class="text-center"><h4>' + x + '</h4></th><th></th></tr>';
2451
}
2452
- active += '<embed><img src="' + NETDATA.serverDefault + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto&_=' + now.toString()+ '"></img></embed><br/>';
2452
+ active += '<tr><td class="text-center" style="vertical-align:middle"><embed><img src="' + NETDATA.serverDefault + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto&_=' + now.toString()+ '"></img></embed></td><td>' + alarm.info + '</td></tr>';
2453
count_active++;
2454
}
2455
2456
if(!all_family_added) {
2457
all_family_added = true;
2458
- all += '<h4>' + x + '</h4>';
2458
+ all += '<tr><th class="text-center"><h4>' + x + '</h4></th><th></th></tr>';
2459
}
2460
- all += '<embed><img src="' + NETDATA.serverDefault + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto&_=' + now.toString()+ '"></img></embed><br/>';
2460
+ all += '<tr><td class="text-center" style="vertical-align:middle"><embed><img src="' + NETDATA.serverDefault + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto&_=' + now.toString()+ '"></img></embed></td><td>' + alarm.info + '</td></tr>';
2461
count_all++;
2462
}
2463
}
2464
+ active += "</table>";
2465
+ all += "</table>";
2466
2467
if(!count_active)
2468
active += "<h4>Everything is normal. No raised alarms.</h4>";
@@ -2482,7 +2484,6 @@ function alarmsUpdateModal() {
2484
return;
2485
}
2486
2485
- log += '<table class="table"><tr><th>When</th><th>Chart</th><th>Alarm</th><th>Status</th></tr>';
2487
var i = 0;
2488
var len = data.length;
2489
if(len > 50) len = 50;