I have this command defined:

define command{
command_name check_http_sane
command_line $USER1$/check_http -H $HOSTNAME$ -r "HTTP/1.1 (200|301|302|303|304|307|401|418|426)"
}

When I run it manually on command line, it works fine, but nagios (2.6) reports a "pattern not found" error. Do I need to escape something?


Edit: As stated below, I solved it by replacing check_http with my own script which works (good enough for our use case, anyway). Script: http://pastebin.com/hNmz6Wa1

link|improve this question

50% accept rate
feedback

3 Answers

The source code for check_http.c says the -r option checks the headers and the page contents. The problem you are seeing is probably the Nagios command macro interpreter trying to replace something in your regex string.

You should try escaping all of your (,| and ) characters. If that doesn't work, try just the parentheses and just the pipes. You might also try using single quotes instead of double quotes.

link|improve this answer
feedback
up vote 1 down vote accepted

Since escaping didn't work either (and it does work without on command line, whyever) and I didn't want to spend more time debugging it, I wrote my own Nagios plugin to replace check_http, which works like a charm (might publish it, if there's interest).


Here is the plugin:

#!/usr/bin/python
import httplib,sys

def make_request (uri):
    if "http://" in uri:
        uri = uri.split("http://")[1]
    if "/" in uri:
        host = uri.split("/")[0]
        selector = "/"+uri.split("/",1)[1]
    else:
        host = uri
        selector = "/"
    if sys.version_info < (2,6):
        h = httplib.HTTPConnection (host)
    else:
        h = httplib.HTTPConnection (host,timeout=10)
    h.request ("GET", selector)
    r = h.getresponse()
    headers = {}
    for pair in r.getheaders():
        headers[pair[0]] = pair[1]
    return (r.status, r.reason, headers, r.read())

def request_content (uri):
    loop = 0
    while loop < 30:
        try:
            response = make_request (uri)
        except:
            return (2, "HTTP_TAO CRITICAL - Unable to connect")

        if 300 <= response[0] <= 400:
            if not "location" in response[2]:
                return (1, "HTTP_TAO WARNING: Unexpected response: %i %s" % (response[0],response[1]))
            uri = response[2]["location"]
            loop += 1
        elif (response[0] == 200) or (len(sys.argv) > 2 and str(response[0]) in sys.argv[2:]):
            return (0, "HTTP_TAO OK: Status Code %i, %i bytes read" % (response[0], len (response[3])))
        else:
            return (1, "HTTP_TAO WARNING: Unexpected response: %i %s" % (response[0],response[1]))

    return (2, "HTTP_TAO CRITICAL: Loop limit reached after 30 redirects")

if __name__ == "__main__":
    if len (sys.argv) == 1:
        print "USAGE: check_http_tao HOSTNAME list of allowed status codes\n\tWith HOSTNAME being the FQDN/IP of the target host, optionally followed by a list of accepted status codes (3xx will be attempted to resolve and 200 accepted by default)"
        sys.exit (1)
    retval = request_content (sys.argv[1])
    print retval[1]
    sys.exit(retval[0])
link|improve this answer
2  
Publish and be damned ! – Iain Feb 21 at 15:03
Publish! <!-- Minlength --> – Bart De Vos Feb 21 at 15:18
pastebin.com/hNmz6Wa1 – Creshal Feb 21 at 15:44
feedback

Your assertion that this "works fine" on the command line is questionable. When I run it manually, it does not "work fine":

./check_http -H localhost -r "HTTP/1.1 (200|301|302|303|304|307|401|418|426)" HTTP CRITICAL: HTTP/1.1 302 Found - pattern not found - 650 bytes in 0.001 second response time |time=0.001410s;;;0.000000 size=650B;;;0

As Jeff Strunk suggests, you need to escape the parentheses (so the shell does not consume them), like this:

./check_http -H localhost -r "HTTP/1.1 \(200|301|302|303|304|307|401|418|426\)" HTTP OK: HTTP/1.1 302 Found - 650 bytes in 0.001 second response time |time=0.001425s;;;0.000000 size=650B;;;0

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.