alarming: make native nagios support to dhcpd-pools

This commit makes integrating the command with nagios much easier.

$ dhcpd-pools -c dhcpd.conf -l dhcpd.leases --critical 80 --warning 75
CRITICAL: dhcpd-pools: Ranges; crit: 14 warn: 22 ok: 220 Shared nets; crit: 1 warn: 0 ok: 4

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Sami Kerola 2012-06-24 15:32:50 +02:00
parent 5a307703c9
commit 42dd80aeac
6 changed files with 161 additions and 2 deletions

View file

@ -129,6 +129,25 @@ Print total summary header
.PD
.RE
.TP
\fB\-\-warning\fR=\fIpercent\fR
Turn on alarm output format, and specify percentage number which will
cause an alarm. If either a range or shared network will exceed
warning level return value of the command is
.BR 1 .
If critical level is not speficied it defaults to
.BR 90 .
The
.I percent
argument allows fractions to be used. Alarm output is intented to be
used with monitoring, such as Nagios.
.TP
\fB\-\-critical\fR=\fIpercent\fR
The option is similar to warning, with exception of return value which
is
.BR 2 .
If warning level is not specified it defaults to
.BR 80 .
.TP
\fB\-v\fR, \fB\-\-version\fR
Print version information to standard output and exit successfully.
.TP

View file

@ -45,4 +45,8 @@ static const unsigned int SHARED_NETWORKS = 8192;
/* Maximum number of ranges */
unsigned int RANGES;
/* Alarming defaults */
#define ALARM_WARN 80
#define ALARM_CRIT 90
#endif /* DEFAULTS_H */

View file

@ -52,6 +52,7 @@ extern char *malloc();
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <limits.h>
#include "defaults.h"
#include "dhcpd-pools.h"
@ -62,6 +63,11 @@ int main(int argc, char **argv)
int option_index = 0;
char *tmp;
struct range_t *tmp_ranges;
enum {
OPT_WARN = CHAR_MAX + 1,
OPT_CRIT
};
int ret_val;
/* Options for getopt_long */
static struct option const long_options[] = {
@ -74,6 +80,8 @@ int main(int argc, char **argv)
{"limit", required_argument, NULL, 'L'},
{"version", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{"warning", required_argument, NULL, OPT_WARN},
{"critical", required_argument, NULL, OPT_CRIT},
{NULL, 0, NULL, 0}
};
@ -87,6 +95,9 @@ int main(int argc, char **argv)
/* Make sure string has zero lenght if there is no
* command line option */
config.output_file[0] = '\0';
/* Alarming defaults. */
config.warning = ALARM_WARN;
config.critical = ALARM_CRIT;
/* File location defaults */
strncpy(config.dhcpdconf_file, DHCPDCONF_FILE, MAXLEN - 1);
@ -160,6 +171,14 @@ int main(int argc, char **argv)
}
}
break;
case OPT_WARN:
strcpy(config.output_format, "a");
config.warning = strtod_or_err(optarg, "illegal argument");
break;
case OPT_CRIT:
strcpy(config.output_format, "a");
config.critical = strtod_or_err(optarg, "illegal argument");
break;
case 'v':
/* Print version */
print_version();
@ -178,6 +197,9 @@ int main(int argc, char **argv)
case 't':
output_analysis = output_txt;
break;
case 'a':
output_analysis = output_alarming;
break;
case 'h':
output_analysis = output_html;
break;
@ -214,10 +236,10 @@ int main(int argc, char **argv)
flip_ranges(ranges, tmp_ranges);
}
free(tmp_ranges);
output_analysis();
ret_val = output_analysis();
clean_up();
return (EXIT_SUCCESS);
return (ret_val);
}
/* Global allocations, counter resets etc */

View file

@ -102,6 +102,8 @@ struct configuration_t {
int reverse_order;
char *output_file;
int output_limit[2];
double warning;
double critical;
};
struct shared_network_t {
char *name;
@ -177,6 +179,7 @@ void *safe_malloc(const size_t size)
void *safe_realloc(void *__restrict ptr, const size_t size);
char *safe_strdup(const char *__restrict str) __attribute__ ((nonnull(1)));
int xstrstr(char *__restrict a, char *__restrict b, int len);
double strtod_or_err(const char *__restrict str, const char *__restrict errmesg);
int close_stream(FILE * stream);
void close_stdout(void);
void print_version(void) __attribute__ ((noreturn));
@ -207,6 +210,7 @@ int output_txt(void);
int output_html(void);
int output_xml(void);
int output_csv(void);
int output_alarming(void);
/* Memory release, file closing etc */
void clean_up(void);
/* Hash functions */

View file

@ -136,6 +136,28 @@ char *safe_strdup(const char *restrict str)
return ret;
}
/* Return percentage value */
double strtod_or_err(const char *str, const char *errmesg)
{
double num;
char *end = NULL;
if (str == NULL || *str == '\0')
goto err;
errno = 0;
num = strtod(str, &end);
if (errno || str == end || (end && *end))
goto err;
return num;
err:
if (errno)
err(EXIT_FAILURE, "%s: '%s'", errmesg, str);
errx(EXIT_FAILURE, "%s: '%s'", errmesg, str);
}
void flip_ranges(struct range_t *restrict ranges, struct range_t *restrict tmp_ranges)
{
unsigned int i = num_ranges - 1, j;
@ -237,6 +259,9 @@ This is ISC dhcpd pools usage analyzer.\n\
-o, --output=FILE output into a file\n\
-L, --limit=NR output limit mask 77 - 00\n");
fprintf(out, "\
--warning=PERC set warning alarming limit\n\
--critical=PERC set critical alarming limit\n");
fprintf(out, "\
-v, --version version information\n\
-h, --help this screen\n\
\n\

View file

@ -37,6 +37,7 @@
#include <arpa/inet.h>
#include <err.h>
#include <errno.h>
#include <langinfo.h>
#include <netinet/in.h>
#include <stdio.h>
@ -788,3 +789,87 @@ int output_csv(void)
}
return 0;
}
int output_alarming(void)
{
FILE *outfile;
struct range_t *range_p;
struct shared_network_t *shared_p;
int i;
float perc;
int rw = 0, rc = 0, ro = 0, sw = 0, sc = 0, so = 0;
int ret_val, ret;
range_p = ranges;
shared_p = shared_networks;
if (config.output_file[0]) {
outfile = fopen(config.output_file, "w+");
if (outfile == NULL) {
err(EXIT_FAILURE, "output_alarming: %s",
config.output_file);
}
} else {
outfile = stdout;
}
if (config.output_limit[1] & output_limit_bit_1) {
for (i = 0; i < num_ranges; i++) {
perc = (float)(100 * range_p->count) /
(range_p->last_ip - range_p->first_ip - 1);
if (config.critical < perc)
rc++;
else if (config.warning < perc)
rw++;
else
ro++;
range_p++;
}
}
if (config.output_limit[1] & output_limit_bit_2) {
for (i = 0; i < num_shared_networks; i++) {
perc = (float)(100 * shared_p->used) /
shared_p->available;
if (config.critical < perc)
sc++;
else if (config.warning < perc)
sw++;
else
so++;
shared_p++;
}
}
if (0 < rc || 0 < sc) {
ret_val = 2;
fprintf(outfile, "CRITICAL: %s: ",
program_invocation_short_name);
} else if (0 < rw || 0 < sw) {
ret_val = 1;
fprintf(outfile, "WARNING: %s: ",
program_invocation_short_name);
} else {
ret_val = 0;
fprintf(outfile, "OK: ");
}
if (config.output_limit[0] & output_limit_bit_1) {
fprintf(outfile, "Ranges; crit: %d warn: %d ok: %d ", rc, rw,
ro);
}
if (config.output_limit[0] & output_limit_bit_2) {
fprintf(outfile, "Shared nets; crit: %d warn: %d ok: %d", sc,
sw, so);
}
fprintf(outfile, "\n");
if (outfile == stdout) {
ret = fflush(stdout);
if (ret) {
warn("output_alarming: fflush");
}
} else {
ret = close_stream(outfile);
if (ret) {
warn("output_alarming: fclose");
}
}
return ret_val;
}