mirror of
git://git.code.sf.net/p/dhcpd-pools/code
synced 2025-12-16 15:57:00 +00:00
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:
parent
5a307703c9
commit
42dd80aeac
6 changed files with 161 additions and 2 deletions
|
|
@ -129,6 +129,25 @@ Print total summary header
|
||||||
.PD
|
.PD
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.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
|
\fB\-v\fR, \fB\-\-version\fR
|
||||||
Print version information to standard output and exit successfully.
|
Print version information to standard output and exit successfully.
|
||||||
.TP
|
.TP
|
||||||
|
|
|
||||||
|
|
@ -45,4 +45,8 @@ static const unsigned int SHARED_NETWORKS = 8192;
|
||||||
/* Maximum number of ranges */
|
/* Maximum number of ranges */
|
||||||
unsigned int RANGES;
|
unsigned int RANGES;
|
||||||
|
|
||||||
|
/* Alarming defaults */
|
||||||
|
#define ALARM_WARN 80
|
||||||
|
#define ALARM_CRIT 90
|
||||||
|
|
||||||
#endif /* DEFAULTS_H */
|
#endif /* DEFAULTS_H */
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ extern char *malloc();
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
#include "dhcpd-pools.h"
|
#include "dhcpd-pools.h"
|
||||||
|
|
@ -62,6 +63,11 @@ int main(int argc, char **argv)
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
struct range_t *tmp_ranges;
|
struct range_t *tmp_ranges;
|
||||||
|
enum {
|
||||||
|
OPT_WARN = CHAR_MAX + 1,
|
||||||
|
OPT_CRIT
|
||||||
|
};
|
||||||
|
int ret_val;
|
||||||
|
|
||||||
/* Options for getopt_long */
|
/* Options for getopt_long */
|
||||||
static struct option const long_options[] = {
|
static struct option const long_options[] = {
|
||||||
|
|
@ -74,6 +80,8 @@ int main(int argc, char **argv)
|
||||||
{"limit", required_argument, NULL, 'L'},
|
{"limit", required_argument, NULL, 'L'},
|
||||||
{"version", no_argument, NULL, 'v'},
|
{"version", no_argument, NULL, 'v'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
|
{"warning", required_argument, NULL, OPT_WARN},
|
||||||
|
{"critical", required_argument, NULL, OPT_CRIT},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -87,6 +95,9 @@ int main(int argc, char **argv)
|
||||||
/* Make sure string has zero lenght if there is no
|
/* Make sure string has zero lenght if there is no
|
||||||
* command line option */
|
* command line option */
|
||||||
config.output_file[0] = '\0';
|
config.output_file[0] = '\0';
|
||||||
|
/* Alarming defaults. */
|
||||||
|
config.warning = ALARM_WARN;
|
||||||
|
config.critical = ALARM_CRIT;
|
||||||
|
|
||||||
/* File location defaults */
|
/* File location defaults */
|
||||||
strncpy(config.dhcpdconf_file, DHCPDCONF_FILE, MAXLEN - 1);
|
strncpy(config.dhcpdconf_file, DHCPDCONF_FILE, MAXLEN - 1);
|
||||||
|
|
@ -160,6 +171,14 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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':
|
case 'v':
|
||||||
/* Print version */
|
/* Print version */
|
||||||
print_version();
|
print_version();
|
||||||
|
|
@ -178,6 +197,9 @@ int main(int argc, char **argv)
|
||||||
case 't':
|
case 't':
|
||||||
output_analysis = output_txt;
|
output_analysis = output_txt;
|
||||||
break;
|
break;
|
||||||
|
case 'a':
|
||||||
|
output_analysis = output_alarming;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
output_analysis = output_html;
|
output_analysis = output_html;
|
||||||
break;
|
break;
|
||||||
|
|
@ -214,10 +236,10 @@ int main(int argc, char **argv)
|
||||||
flip_ranges(ranges, tmp_ranges);
|
flip_ranges(ranges, tmp_ranges);
|
||||||
}
|
}
|
||||||
free(tmp_ranges);
|
free(tmp_ranges);
|
||||||
output_analysis();
|
ret_val = output_analysis();
|
||||||
|
|
||||||
clean_up();
|
clean_up();
|
||||||
return (EXIT_SUCCESS);
|
return (ret_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Global allocations, counter resets etc */
|
/* Global allocations, counter resets etc */
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,8 @@ struct configuration_t {
|
||||||
int reverse_order;
|
int reverse_order;
|
||||||
char *output_file;
|
char *output_file;
|
||||||
int output_limit[2];
|
int output_limit[2];
|
||||||
|
double warning;
|
||||||
|
double critical;
|
||||||
};
|
};
|
||||||
struct shared_network_t {
|
struct shared_network_t {
|
||||||
char *name;
|
char *name;
|
||||||
|
|
@ -177,6 +179,7 @@ void *safe_malloc(const size_t size)
|
||||||
void *safe_realloc(void *__restrict ptr, const size_t size);
|
void *safe_realloc(void *__restrict ptr, const size_t size);
|
||||||
char *safe_strdup(const char *__restrict str) __attribute__ ((nonnull(1)));
|
char *safe_strdup(const char *__restrict str) __attribute__ ((nonnull(1)));
|
||||||
int xstrstr(char *__restrict a, char *__restrict b, int len);
|
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);
|
int close_stream(FILE * stream);
|
||||||
void close_stdout(void);
|
void close_stdout(void);
|
||||||
void print_version(void) __attribute__ ((noreturn));
|
void print_version(void) __attribute__ ((noreturn));
|
||||||
|
|
@ -207,6 +210,7 @@ int output_txt(void);
|
||||||
int output_html(void);
|
int output_html(void);
|
||||||
int output_xml(void);
|
int output_xml(void);
|
||||||
int output_csv(void);
|
int output_csv(void);
|
||||||
|
int output_alarming(void);
|
||||||
/* Memory release, file closing etc */
|
/* Memory release, file closing etc */
|
||||||
void clean_up(void);
|
void clean_up(void);
|
||||||
/* Hash functions */
|
/* Hash functions */
|
||||||
|
|
|
||||||
25
src/other.c
25
src/other.c
|
|
@ -136,6 +136,28 @@ char *safe_strdup(const char *restrict str)
|
||||||
return ret;
|
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)
|
void flip_ranges(struct range_t *restrict ranges, struct range_t *restrict tmp_ranges)
|
||||||
{
|
{
|
||||||
unsigned int i = num_ranges - 1, j;
|
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\
|
-o, --output=FILE output into a file\n\
|
||||||
-L, --limit=NR output limit mask 77 - 00\n");
|
-L, --limit=NR output limit mask 77 - 00\n");
|
||||||
fprintf(out, "\
|
fprintf(out, "\
|
||||||
|
--warning=PERC set warning alarming limit\n\
|
||||||
|
--critical=PERC set critical alarming limit\n");
|
||||||
|
fprintf(out, "\
|
||||||
-v, --version version information\n\
|
-v, --version version information\n\
|
||||||
-h, --help this screen\n\
|
-h, --help this screen\n\
|
||||||
\n\
|
\n\
|
||||||
|
|
|
||||||
85
src/output.c
85
src/output.c
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <langinfo.h>
|
#include <langinfo.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -788,3 +789,87 @@ int output_csv(void)
|
||||||
}
|
}
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue