[Nagiosplug-devel] check_http plugin feature

Per-Arne Wallstroem per-arne.wallstrom at enlight.net
Mon Feb 13 10:06:00 CET 2006


Hi List,

We are using the check_http plugin to check our webapps. We use the
regex feature of check_http but needed a way to match more than a 
single regex on a page, and also the ability to match for words that 
we do not expect to be present (certain error messages). 

The check_http of 1.4.2 plugins (which we are currently using) did 
not allow us to do this, and supported only one single regex match.
We did not want to create yet another http plugin, so so we made a 
patch for it. The patch can be found below.

It introduces 2 command options:

 -j, --invert-match
    Invert the sense of next regex (must precede -r or -R)
 -r, --regex, --ereg=STRING 
    Can be present more than once on a command line.

I'm not a programmer, so maybe the code could be written more 
elegant...

Enjoy,
-- 
Kind regards / Med vänliga hälsningar,
Per-Arne Wallström
____________________________________________________

     Per-Arne Wallström
     System Administrator

     Enlight AB
     Direct +46 (0)90 71 71 26
     Fax +090 71 71 99
     Mobile +46 (0)70 609 0559
     Hagaplan 1, 903 36 Umeå, Sweden
     enlight.net
____________________________________________________

     Assuring Knowledge

--- plugins/check_http.orig	2006-02-13 16:13:30.344818411 +0100
+++ plugins/check_http.c	2006-02-13 18:12:52.357068769 +0100
@@ -73,10 +73,15 @@
 #ifdef HAVE_REGEX_H
 enum {
 	REGS = 2,
-	MAX_RE_SIZE = 256
+	MAX_RE_SIZE = 256,
+	MAX_RE_PREGS = 256
 };
 #include <regex.h>
-regex_t preg;
+int num_preg = 0;
+int num_match = 0;
+int re_invert_reg = 0;
+int re_invert[MAX_RE_PREGS];
+regex_t preg[MAX_RE_PREGS];
 regmatch_t pmatch[REGS];
 char regexp[MAX_RE_SIZE];
 char errbuf[MAX_INPUT_BUFFER];
@@ -215,6 +220,7 @@
 		{"regex", required_argument, 0, 'r'},
 		{"ereg", required_argument, 0, 'r'},
 		{"eregi", required_argument, 0, 'R'},
+		{"invert-match", no_argument, 0, 'j'},
  		{"linespan", no_argument, 0, 'l'},
 		{"onredirect", required_argument, 0, 'f'},
 		{"certificate", required_argument, 0, 'C'},
@@ -246,7 +252,7 @@
 	}
 
 	while (1) {
-		c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:T:I:a:e:p:s:R:r:u:f:C:nlLSm:M:N", longopts, &option);
+		c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:T:I:a:e:p:s:R:r:u:f:C:nlLSm:M:Nj", longopts, &option);
 		if (c == -1 || c == EOF)
 			break;
 
@@ -382,18 +388,33 @@
  		case 'l': /* linespan */
  			cflags &= ~REG_NEWLINE;
  			break;
+		case 'j': /* invert next regex */
+			if (num_preg < MAX_RE_PREGS) {
+				re_invert_reg = 1;
+			}
+			break;
 		case 'R': /* regex */
 			cflags |= REG_ICASE;
 		case 'r': /* regex */
-			strncpy (regexp, optarg, MAX_RE_SIZE - 1);
-			regexp[MAX_RE_SIZE - 1] = 0;
-			errcode = regcomp (&preg, regexp, cflags);
-			if (errcode != 0) {
-				(void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
-				printf (_("Could Not Compile Regular Expression: %s"), errbuf);
-				return ERROR;
+			if (num_preg < MAX_RE_PREGS) {
+				strncpy (regexp, optarg, MAX_RE_SIZE - 1);
+				regexp[MAX_RE_SIZE - 1] = 0;
+				errcode = regcomp (&preg[num_preg], regexp, cflags);
+				if (errcode != 0) {
+					(void) regerror (errcode, &preg[num_preg], errbuf, MAX_INPUT_BUFFER);
+					printf (_("Could Not Compile Regular Expression: %s"), errbuf);
+					return ERROR;
+				}
+				/* Should the result be inverted? */
+				re_invert[num_preg] = re_invert_reg;
+				re_invert_reg = 0;
+				num_preg++;
+				break;
+			}
+			else {
+				usage4(_("Too many regular expressions"));
+				break;
 			}
-			break;
 #endif
 		case '4':
 			address_family = AF_INET;
@@ -781,6 +802,7 @@
 	char *auth;
 	int http_status;
 	int i = 0;
+	int match = 1;
 	size_t pagesize = 0;
 	char *full_page;
 	char *buf;
@@ -1048,27 +1070,59 @@
 		}
 	}
 #ifdef HAVE_REGEX_H
-	if (strlen (regexp)) {
-		errcode = regexec (&preg, page, REGS, pmatch, 0);
-		if (errcode == 0) {
+	if (num_preg) {
+		for (i = 0; i < num_preg; i++) {
+			errcode = regexec (&preg[i], page, REGS, pmatch, 0);
+
+			switch (errcode) {
+			case 0:
+				match = 1;
+				break;
+			case REG_NOMATCH: 
+				match = 0; 
+				break;
+			default:
+				regerror (errcode, &preg[i], errbuf, MAX_INPUT_BUFFER);
+				printf (_("CRITICAL - Execute Error: %s\n"), errbuf);
+				exit (STATE_CRITICAL);
+				break;
+			}
+			
+			if (re_invert[i] == 0) {
+				if (match) {
+					num_match++;
+				}
+				else {
+					printf (_("CRITICAL - pattern not found%s|%s %s\n"),
+				        (display_html ? "</A>" : ""),
+				        perfd_time (elapsed_time), perfd_size (pagesize));
+					exit (STATE_CRITICAL);
+				}
+			}
+			else { /* Inverted match. */
+				if (match) {
+					printf (_("CRITICAL - pattern found%s|%s %s\n"),
+				        (display_html ? "</A>" : ""),
+				        perfd_time (elapsed_time), perfd_size (pagesize));
+					exit (STATE_CRITICAL);
+				}
+				else {
+					num_match++;
+				}
+			}
+		}
+
+		if (num_preg == num_match) {
 			printf (_("HTTP OK %s - %.3f second response time %s%s|%s %s\n"),
 			        status_line, elapsed_time,
-			        timestamp, (display_html ? "</A>" : ""),
+		        	timestamp, (display_html ? "</A>" : ""),
 			        perfd_time (elapsed_time), perfd_size (pagesize));
 			exit (STATE_OK);
 		}
 		else {
-			if (errcode == REG_NOMATCH) {
-				printf (_("CRITICAL - pattern not found%s|%s %s\n"),
-				        (display_html ? "</A>" : ""),
-				        perfd_time (elapsed_time), perfd_size (pagesize));
-				exit (STATE_CRITICAL);
-			}
-			else {
-				regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
-				printf (_("CRITICAL - Execute Error: %s\n"), errbuf);
-				exit (STATE_CRITICAL);
-			}
+			/* Should not happen */
+			printf(("CRITICAL - not all patterns were checked\n"));
+			exit(STATE_CRITICAL);
 		}
 	}
 #endif
@@ -1497,6 +1551,8 @@
 
 #ifdef HAVE_REGEX_H
 	printf (_("\
+ -j, --invert-match\n\
+    Invert the sense of next regex (must precede -r or -R)\n\
  -l, --linespan\n\
     Allow regex to span newlines (must precede -r or -R)\n\
  -r, --regex, --ereg=STRING\n\
@@ -1566,7 +1622,7 @@
 Usage: %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n\
                   [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L]\n\
                   [-a auth] [-f <ok | warn | critcal | follow>] [-e <expect>]\n\
-                  [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n\
+                  [-s string] [-l] [-j] [-r <regex> | -R <case-insensitive regex>]\n\
                   [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] \n\
                   [-M <age>] [-A string] [-k string]\n", progname);
 }







More information about the Devel mailing list