diff options
author | Sven Nierlein <sven@consol.de> | 2024-02-23 18:24:28 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-23 18:24:28 +0100 |
commit | 117cd8e4b826e471e795536228628d817df33f5a (patch) | |
tree | 4ce82a1ad714f95e0bb790aa9396f059bf5a3677 /plugins | |
parent | 0c01f2946ed21f5e7977b5503f9c9f00e72fd708 (diff) | |
download | monitoring-plugins-117cd8e4b826e471e795536228628d817df33f5a.tar.gz |
check_disk increase alert precision (#1989)
* check_disk increase alert precision
Free disk percentage value was rounded to a full integer meaning it alerted about ~1% percent too early. This is about 10GB on a 1TB disk.
The warning and critical thresholds already support float values, so just the percentage calculation needs to be improved.
old:
./check_disk -w 35% -c 20% -p / -f -vvv
Thresholds(pct) for / warn: 35.000000 crit 20.000000
calling stat on /
For /, used_pct=65 free_pct=35 used_units=286451 free_units=156651 total_units=443102 used_inodes_pct=11 free_inodes_pct=89 fsp.fsu_blocksize=4096 mult=1048576
Freespace_units result=0
Freespace% result=1
Usedspace_units result=0
Usedspace_percent result=0
Usedinodes_percent result=0
Freeinodes_percent result=0
DISK WARNING - free space: WARNING [ / 156651MiB (35% inode=89%)];| /=300365643776B;302006979788;371700898201;0;464626122752
new:
./check_disk -w 35% -c 20% -p / -f -vvv
Thresholds(pct) for / warn: 35.000000 crit 20.000000
calling stat on /
For /, used_pct=64.649722 free_pct=35.350278 used_units=286464 free_units=156637 total_units=443102 used_inodes_pct=10.016183 free_inodes_pct=89.983817 fsp.fsu_blocksize=4096 mult=1048576
Freespace_units result=0
Freespace% result=0
Usedspace_units result=0
Usedspace_percent result=0
Usedinodes_percent result=0
Freeinodes_percent result=0
DISK OK - free space: / 156637MiB (35.4% inode=90%);| /=300379275264B;302006979788;371700898201;0;464626122752
* check_disk: adjust test case to support float precision
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/check_disk.c | 28 | ||||
-rw-r--r-- | plugins/t/check_disk.t | 2 |
2 files changed, 7 insertions, 23 deletions
diff --git a/plugins/check_disk.c b/plugins/check_disk.c index c6bba243..0d84ecd2 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c | |||
@@ -46,7 +46,7 @@ const char *email = "devel@monitoring-plugins.org"; | |||
46 | #include <stdarg.h> | 46 | #include <stdarg.h> |
47 | #include "fsusage.h" | 47 | #include "fsusage.h" |
48 | #include "mountlist.h" | 48 | #include "mountlist.h" |
49 | #include "intprops.h" /* necessary for TYPE_MAXIMUM */ | 49 | #include <float.h> |
50 | #if HAVE_LIMITS_H | 50 | #if HAVE_LIMITS_H |
51 | # include <limits.h> | 51 | # include <limits.h> |
52 | #endif | 52 | #endif |
@@ -325,7 +325,7 @@ main (int argc, char **argv) | |||
325 | get_stats (path, &fsp); | 325 | get_stats (path, &fsp); |
326 | 326 | ||
327 | if (verbose >= 3) { | 327 | if (verbose >= 3) { |
328 | printf ("For %s, used_pct=%g free_pct=%g used_units=%lu free_units=%lu total_units=%lu used_inodes_pct=%g free_inodes_pct=%g fsp.fsu_blocksize=%lu mult=%lu\n", | 328 | printf ("For %s, used_pct=%f free_pct=%f used_units=%lu free_units=%lu total_units=%lu used_inodes_pct=%f free_inodes_pct=%f fsp.fsu_blocksize=%lu mult=%lu\n", |
329 | me->me_mountdir, | 329 | me->me_mountdir, |
330 | path->dused_pct, | 330 | path->dused_pct, |
331 | path->dfree_pct, | 331 | path->dfree_pct, |
@@ -431,7 +431,7 @@ main (int argc, char **argv) | |||
431 | } else { | 431 | } else { |
432 | xasprintf(&flag_header, ""); | 432 | xasprintf(&flag_header, ""); |
433 | } | 433 | } |
434 | xasprintf (&output, "%s%s %s %llu%s (%.0f%%", | 434 | xasprintf (&output, "%s%s %s %llu%s (%.1f%%", |
435 | output, flag_header, | 435 | output, flag_header, |
436 | (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, | 436 | (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, |
437 | path->dfree_units, | 437 | path->dfree_units, |
@@ -461,24 +461,8 @@ main (int argc, char **argv) | |||
461 | 461 | ||
462 | double calculate_percent(uintmax_t value, uintmax_t total) { | 462 | double calculate_percent(uintmax_t value, uintmax_t total) { |
463 | double pct = -1; | 463 | double pct = -1; |
464 | /* I don't understand the below, but it is taken from coreutils' df */ | 464 | if(value <= DBL_MAX && total != 0) { |
465 | /* Seems to be calculating pct, in the best possible way */ | 465 | pct = (double)value / total * 100.0; |
466 | if (value <= TYPE_MAXIMUM(uintmax_t) / 100 | ||
467 | && total != 0) { | ||
468 | uintmax_t u100 = value * 100; | ||
469 | pct = u100 / total + (u100 % total != 0); | ||
470 | } else { | ||
471 | /* Possible rounding errors - see coreutils' df for more explanation */ | ||
472 | double u = value; | ||
473 | double t = total; | ||
474 | if (t) { | ||
475 | long int lipct = pct = u * 100 / t; | ||
476 | double ipct = lipct; | ||
477 | |||
478 | /* Like 'pct = ceil (dpct);', but without ceil - from coreutils again */ | ||
479 | if (ipct - 1 < pct && pct <= ipct + 1) | ||
480 | pct = ipct + (ipct < pct); | ||
481 | } | ||
482 | } | 466 | } |
483 | return pct; | 467 | return pct; |
484 | } | 468 | } |
@@ -1130,7 +1114,7 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) { | |||
1130 | } | 1114 | } |
1131 | /* finally calculate percentages for either plain FS or summed up group */ | 1115 | /* finally calculate percentages for either plain FS or summed up group */ |
1132 | p->dused_pct = calculate_percent( p->used, p->used + p->available ); /* used + available can never be > uintmax */ | 1116 | p->dused_pct = calculate_percent( p->used, p->used + p->available ); /* used + available can never be > uintmax */ |
1133 | p->dfree_pct = 100 - p->dused_pct; | 1117 | p->dfree_pct = 100.0 - p->dused_pct; |
1134 | p->dused_inodes_percent = calculate_percent(p->inodes_total - p->inodes_free, p->inodes_total); | 1118 | p->dused_inodes_percent = calculate_percent(p->inodes_total - p->inodes_free, p->inodes_total); |
1135 | p->dfree_inodes_percent = 100 - p->dused_inodes_percent; | 1119 | p->dfree_inodes_percent = 100 - p->dused_inodes_percent; |
1136 | 1120 | ||
diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t index bf8dd362..e0dd70eb 100644 --- a/plugins/t/check_disk.t +++ b/plugins/t/check_disk.t | |||
@@ -44,7 +44,7 @@ my @perf_data = sort(split(/ /, $result->perf_output)); | |||
44 | # Calculate avg_free free on mountpoint1 and mountpoint2 | 44 | # Calculate avg_free free on mountpoint1 and mountpoint2 |
45 | # because if you check in the middle, you should get different errors | 45 | # because if you check in the middle, you should get different errors |
46 | $_ = $result->output; | 46 | $_ = $result->output; |
47 | my ($free_on_mp1, $free_on_mp2) = (m/\((\d+)%.*\((\d+)%/); | 47 | my ($free_on_mp1, $free_on_mp2) = (m/\((\d+\.\d+)%.*\((\d+\.\d+)%/); |
48 | die "Cannot parse output: $_" unless ($free_on_mp1 && $free_on_mp2); | 48 | die "Cannot parse output: $_" unless ($free_on_mp1 && $free_on_mp2); |
49 | my $avg_free = ceil(($free_on_mp1+$free_on_mp2)/2); | 49 | my $avg_free = ceil(($free_on_mp1+$free_on_mp2)/2); |
50 | my ($more_free, $less_free); | 50 | my ($more_free, $less_free); |