aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--plugins/check_http.c24
-rw-r--r--plugins/check_mysql.c76
-rw-r--r--plugins/check_snmp.c41
-rwxr-xr-xplugins/tests/check_http.t13
5 files changed, 134 insertions, 23 deletions
diff --git a/NEWS b/NEWS
index 446d8e48..df2652f9 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ This file documents the major additions and syntax changes between releases.
Add --without-{dbi,ldap,radius} options to ./configure
Made Verbose output of check_sensors compliant (Gabriele Tozzi)
New switch -E/--extended-perfdata for check_http to print additional performance data (Sebastian Nohn)
+ New check_http -d option to specify a string to expect within the response headers
Add support for executing queries to check_pgsql
Let check_pgsql accept a UNIX socket directory as hostname
New check_pgsql -o option to specify additional connection parameters
@@ -23,6 +24,8 @@ This file documents the major additions and syntax changes between releases.
New check_procs -k option to ignore kernel threads (on Linux)
Let check_procs use /proc/<PID>/exe (if available) instead of getpid(2), unless -T is specified
Let check_mysql support SSL
+ Let check_mysql add perfromance metrics for all checks
+ New check_snmp --offset option to allow for adding/substracting an offset value to sensor data
FIXES
Change the MAIL FROM command generated by check_smtp to be RFC compliant
diff --git a/plugins/check_http.c b/plugins/check_http.c
index 6db38e8c..ea7a6736 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -100,7 +100,9 @@ char *user_agent;
int server_url_length;
int server_expect_yn = 0;
char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT;
+char header_expect[MAX_INPUT_BUFFER] = "";
char string_expect[MAX_INPUT_BUFFER] = "";
+char output_header_search[30] = "";
char output_string_search[30] = "";
char *warning_thresholds = NULL;
char *critical_thresholds = NULL;
@@ -205,6 +207,7 @@ process_arguments (int argc, char **argv)
{"port", required_argument, 0, 'p'},
{"authorization", required_argument, 0, 'a'},
{"proxy_authorization", required_argument, 0, 'b'},
+ {"header-string", required_argument, 0, 'd'},
{"string", required_argument, 0, 's'},
{"expect", required_argument, 0, 'e'},
{"regex", required_argument, 0, 'r'},
@@ -243,7 +246,7 @@ process_arguments (int argc, char **argv)
}
while (1) {
- c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:e:p:s:R:r:u:f:C:nlLS::m:M:N:E", longopts, &option);
+ c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:nlLS::m:M:N:E", longopts, &option);
if (c == -1 || c == EOF)
break;
@@ -392,6 +395,10 @@ process_arguments (int argc, char **argv)
free(http_method);
http_method = strdup (optarg);
break;
+ case 'd': /* string or substring */
+ strncpy (header_expect, optarg, MAX_INPUT_BUFFER - 1);
+ header_expect[MAX_INPUT_BUFFER - 1] = 0;
+ break;
case 's': /* string or substring */
strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1);
string_expect[MAX_INPUT_BUFFER - 1] = 0;
@@ -1085,6 +1092,17 @@ check_http (void)
}
/* Page and Header content checks go here */
+ if (strlen (header_expect)) {
+ if (!strstr (header, header_expect)) {
+ strncpy(&output_header_search[0],header_expect,sizeof(output_header_search));
+ if(output_header_search[sizeof(output_header_search)-1]!='\0') {
+ bcopy("...",&output_header_search[sizeof(output_header_search)-4],4);
+ }
+ xasprintf (&msg, _("%sheader '%s' not found on '%s://%s:%d%s', "), msg, output_header_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url);
+ result = STATE_CRITICAL;
+ }
+ }
+
if (strlen (string_expect)) {
if (!strstr (page, string_expect)) {
@@ -1434,6 +1452,8 @@ print_help (void)
printf (" %s", _("the first (status) line of the server response (default: "));
printf ("%s)\n", HTTP_EXPECT);
printf (" %s\n", _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)"));
+ printf (" %s\n", "-d, --header-string=STRING");
+ printf (" %s\n", _("String to expect in the response headers"));
printf (" %s\n", "-s, --string=STRING");
printf (" %s\n", _("String to expect in the content"));
printf (" %s\n", "-u, --url=PATH");
@@ -1535,7 +1555,7 @@ print_usage (void)
printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname);
printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-a auth]\n");
printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport>]\n");
- printf (" [-e <expect>] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n");
+ printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n");
printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n");
printf (" [-A string] [-k string] [-S <version>] [--sni] [-C <warn_age>[,<crit_age>]]\n");
printf (" [-T <content-type>] [-j method]\n");
diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c
index ad3d86f3..11d4a2fd 100644
--- a/plugins/check_mysql.c
+++ b/plugins/check_mysql.c
@@ -59,6 +59,32 @@ unsigned int db_port = MYSQL_PORT;
int check_slave = 0, warn_sec = 0, crit_sec = 0;
int verbose = 0;
+static double warning_time = 0;
+static double critical_time = 0;
+
+#define LENGTH_METRIC_UNIT 6
+static const char *metric_unit[LENGTH_METRIC_UNIT] = {
+ "Open_files",
+ "Open_tables",
+ "Qcache_free_memory",
+ "Qcache_queries_in_cache",
+ "Threads_connected",
+ "Threads_running"
+};
+
+#define LENGTH_METRIC_COUNTER 9
+static const char *metric_counter[LENGTH_METRIC_COUNTER] = {
+ "Connections",
+ "Qcache_hits",
+ "Qcache_inserts",
+ "Qcache_lowmem_prunes",
+ "Qcache_not_cached",
+ "Queries",
+ "Questions",
+ "Table_locks_waited",
+ "Uptime"
+};
+
thresholds *my_threshold = NULL;
int process_arguments (int, char **);
@@ -79,6 +105,9 @@ main (int argc, char **argv)
char *result = NULL;
char *error = NULL;
char slaveresult[SLAVERESULTSIZE];
+ char* perf;
+
+ perf = strdup ("");
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
@@ -126,6 +155,37 @@ main (int argc, char **argv)
die (STATE_CRITICAL, "%s\n", mysql_error (&mysql));
}
+ /* try to fetch some perf data */
+ if (mysql_query (&mysql, "show global status") == 0) {
+ if ( (res = mysql_store_result (&mysql)) == NULL) {
+ error = strdup(mysql_error(&mysql));
+ mysql_close (&mysql);
+ die (STATE_CRITICAL, _("status store_result error: %s\n"), error);
+ }
+
+ while ( (row = mysql_fetch_row (res)) != NULL) {
+ int i;
+
+ for(i = 0; i < LENGTH_METRIC_UNIT; i++) {
+ if (strcmp(row[0], metric_unit[i]) == 0) {
+ xasprintf(&perf, "%s%s ", perf, perfdata(metric_unit[i],
+ atol(row[1]), "", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0));
+ continue;
+ }
+ }
+ for(i = 0; i < LENGTH_METRIC_COUNTER; i++) {
+ if (strcmp(row[0], metric_counter[i]) == 0) {
+ xasprintf(&perf, "%s%s ", perf, perfdata(metric_counter[i],
+ atol(row[1]), "c", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0));
+ continue;
+ }
+ }
+ }
+ /* remove trailing space */
+ if (strlen(perf) > 0)
+ perf[strlen(perf) - 1] = '\0';
+ }
+
if(check_slave) {
/* check the slave status */
if (mysql_query (&mysql, "show slave status") != 0) {
@@ -218,11 +278,17 @@ main (int argc, char **argv)
status = get_status(value, my_threshold);
+ xasprintf (&perf, "%s %s", perf, fperfdata ("seconds behind master", value, "s",
+ TRUE, (double) warning_time,
+ TRUE, (double) critical_time,
+ FALSE, 0,
+ FALSE, 0));
+
if (status == STATE_WARNING) {
- printf("SLOW_SLAVE %s: %s\n", _("WARNING"), slaveresult);
+ printf("SLOW_SLAVE %s: %s|%s\n", _("WARNING"), slaveresult, perf);
exit(STATE_WARNING);
} else if (status == STATE_CRITICAL) {
- printf("SLOW_SLAVE %s: %s\n", _("CRITICAL"), slaveresult);
+ printf("SLOW_SLAVE %s: %s|%s\n", _("CRITICAL"), slaveresult, perf);
exit(STATE_CRITICAL);
}
}
@@ -237,9 +303,9 @@ main (int argc, char **argv)
/* print out the result of stats */
if (check_slave) {
- printf ("%s %s\n", result, slaveresult);
+ printf ("%s %s|%s\n", result, slaveresult, perf);
} else {
- printf ("%s\n", result);
+ printf ("%s|%s\n", result, perf);
}
return STATE_OK;
@@ -339,9 +405,11 @@ process_arguments (int argc, char **argv)
break;
case 'w':
warning = optarg;
+ warning_time = strtod (warning, NULL);
break;
case 'c':
critical = optarg;
+ critical_time = strtod (critical, NULL);
break;
case 'V': /* version */
print_revision (progname, NP_VERSION);
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c
index 7c5d0ec5..7c3bc4b9 100644
--- a/plugins/check_snmp.c
+++ b/plugins/check_snmp.c
@@ -63,6 +63,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
#define L_CALCULATE_RATE CHAR_MAX+1
#define L_RATE_MULTIPLIER CHAR_MAX+2
#define L_INVERT_SEARCH CHAR_MAX+3
+#define L_OFFSET CHAR_MAX+4
/* Gobble to string - stop incrementing c when c[0] match one of the
* characters in s */
@@ -138,6 +139,7 @@ char *output_delim;
char *miblist = NULL;
int needmibs = FALSE;
int calculate_rate = 0;
+double offset = 0.0;
int rate_multiplier = 1;
state_data *previous_state;
double previous_value[MAX_OIDS];
@@ -274,35 +276,36 @@ main (int argc, char **argv)
snmpcmd = strdup (PATH_TO_SNMPGET);
}
- /* 9 arguments to pass before authpriv options + 1 for host and numoids. Add one for terminating NULL */
- command_line = calloc (9 + numauthpriv + 1 + numoids + 1, sizeof (char *));
+ /* 10 arguments to pass before authpriv options + 1 for host and numoids. Add one for terminating NULL */
+ command_line = calloc (10 + numauthpriv + 1 + numoids + 1, sizeof (char *));
command_line[0] = snmpcmd;
- command_line[1] = strdup ("-t");
- xasprintf (&command_line[2], "%d", timeout_interval);
- command_line[3] = strdup ("-r");
- xasprintf (&command_line[4], "%d", retries);
- command_line[5] = strdup ("-m");
- command_line[6] = strdup (miblist);
- command_line[7] = "-v";
- command_line[8] = strdup (proto);
+ command_line[1] = strdup ("-Le");
+ command_line[2] = strdup ("-t");
+ xasprintf (&command_line[3], "%d", timeout_interval);
+ command_line[4] = strdup ("-r");
+ xasprintf (&command_line[5], "%d", retries);
+ command_line[6] = strdup ("-m");
+ command_line[7] = strdup (miblist);
+ command_line[8] = "-v";
+ command_line[9] = strdup (proto);
for (i = 0; i < numauthpriv; i++) {
- command_line[9 + i] = authpriv[i];
+ command_line[10 + i] = authpriv[i];
}
- xasprintf (&command_line[9 + numauthpriv], "%s:%s", server_address, port);
+ xasprintf (&command_line[10 + numauthpriv], "%s:%s", server_address, port);
/* This is just for display purposes, so it can remain a string */
- xasprintf(&cl_hidden_auth, "%s -t %d -r %d -m %s -v %s %s %s:%s",
+ xasprintf(&cl_hidden_auth, "%s -Le -t %d -r %d -m %s -v %s %s %s:%s",
snmpcmd, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto, "[authpriv]",
server_address, port);
for (i = 0; i < numoids; i++) {
- command_line[9 + numauthpriv + 1 + i] = oids[i];
+ command_line[10 + numauthpriv + 1 + i] = oids[i];
xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]);
}
- command_line[9 + numauthpriv + 1 + numoids] = NULL;
+ command_line[10 + numauthpriv + 1 + numoids] = NULL;
if (verbose)
printf ("%s\n", cl_hidden_auth);
@@ -429,7 +432,7 @@ main (int argc, char **argv)
ptr = strpbrk (show, "0123456789");
if (ptr == NULL)
die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show);
- response_value[i] = strtod (ptr, NULL);
+ response_value[i] = strtod (ptr, NULL) + offset;
if(calculate_rate) {
if (previous_state!=NULL) {
@@ -618,6 +621,7 @@ process_arguments (int argc, char **argv)
{"next", no_argument, 0, 'n'},
{"rate", no_argument, 0, L_CALCULATE_RATE},
{"rate-multiplier", required_argument, 0, L_RATE_MULTIPLIER},
+ {"offset", required_argument, 0, L_OFFSET},
{"invert-search", no_argument, 0, L_INVERT_SEARCH},
{"perf-oids", no_argument, 0, 'O'},
{0, 0, 0, 0}
@@ -832,6 +836,9 @@ process_arguments (int argc, char **argv)
if(!is_integer(optarg)||((rate_multiplier=atoi(optarg))<=0))
usage2(_("Rate multiplier must be a positive integer"),optarg);
break;
+ case L_OFFSET:
+ offset=strtod(optarg,NULL);
+ break;
case L_INVERT_SEARCH:
invert_search=1;
break;
@@ -1080,6 +1087,8 @@ print_help (void)
printf (" %s\n", _("Enable rate calculation. See 'Rate Calculation' below"));
printf (" %s\n", "--rate-multiplier");
printf (" %s\n", _("Converts rate per second. For example, set to 60 to convert to per minute"));
+ printf (" %s\n", "--offset=OFFSET");
+ printf (" %s\n", _("Add/substract the specified OFFSET to numeric sensor data"));
/* Tests Against Strings */
printf (" %s\n", "-s, --string=STRING");
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t
index 9f97abdc..c3085e13 100755
--- a/plugins/tests/check_http.t
+++ b/plugins/tests/check_http.t
@@ -17,7 +17,7 @@ use Test::More;
use NPTest;
use FindBin qw($Bin);
-my $common_tests = 66;
+my $common_tests = 70;
my $ssl_only_tests = 8;
# Check that all dependent modules are available
eval {
@@ -151,6 +151,10 @@ sub run_server {
unshift @persist, $c;
delete($persist[1000]);
next MAINLOOP;
+ } elsif ($r->url->path eq "/header_check") {
+ $c->send_basic_header;
+ $c->send_header('foo');
+ $c->send_crlf;
} else {
$c->send_error(HTTP::Status->RC_FORBIDDEN);
}
@@ -223,6 +227,13 @@ sub run_common_tests {
is( $result->return_code, 2, "Missing string check");
like( $result->output, qr%HTTP CRITICAL: HTTP/1\.1 200 OK - string 'NonRootWithOver30charsAndM...' not found on 'https?://127\.0\.0\.1:\d+/file/root'%, "Shows search string and location");
+ $result = NPTest->testCmd( "$command -u /header_check -d foo" );
+ is( $result->return_code, 0, "header_check search for string");
+ like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - 96 bytes in [\d\.]+ second/', "Output correct" );
+
+ $result = NPTest->testCmd( "$command -u /header_check -d bar" );
+ is( $result->return_code, 2, "Missing header string check");
+ like( $result->output, qr%^HTTP CRITICAL: HTTP/1\.1 200 OK - header 'bar' not found on 'https?://127\.0\.0\.1:\d+/header_check'%, "Shows search string and location");
my $cmd;
$cmd = "$command -u /slow";