Nagios plugin to parse JSON from an HTTP response

Update 2015-10-07: This plugin has evolved – please check the latest README for up to date details.

 

Hello all !  I wrote a plugin for Nagios that will parse JSON from an HTTP response.  If that sounds interesting to you, feel free to check out my check_http_json repo on Github.  The plugin has been tested with Ruby 1.8.7 and 1.9.3.  Pull requests welcome !

Usage: ./check_http_json.rb -u  -e  -w  -c 
-h, --help                       Help info.
-v, --verbose                    Additional human output.
-u, --uri URI                    Target URI. Incompatible with -f.
    --user USERNAME              HTTP basic authentication username.
    --pass PASSWORD              HTTP basic authentication password.
-f, --file PATH                  Target file. Incompatible with -u.
-e, --element ELEMENT            Desired element (ex. foo=>bar=>ish is foo.bar.ish).
-E, --element_regex REGEX        Desired element expressed as regular expression.
-d, --delimiter CHARACTER        Element delimiter (default is period).
-w, --warn VALUE                 Warning threshold (integer).
-c, --crit VALUE                 Critical threshold (integer).
-r, --result STRING              Expected string result. No need for -w or -c.
-R, --result_regex REGEX         Expected string result expressed as regular expression. No need for -w or -c.
-W, --result_warn STRING         Warning if element is [string]. -C is required.
-C, --result_crit STRING         Critical if element is [string]. -W is required.
-t, --timeout SECONDS            Wait before HTTP timeout.

The --warn and --crit arguments conform to the Nagios threshold format guidelines.

If a simple result of either string or regular expression (-r or -R) is specified :

  • A match is OK and anything else is CRIT.
  • The warn / crit thresholds will be ignored.

If the warn and crit results (-W and -C) are specified :

  • A match is WARN or CRIT and anything else is OK.
  • The warn / crit thresholds will be ignored.

Note that (-r or -R) and (-W and -C) are mutually exclusive.

Note also that the response must be pure JSON. Bad things happen if this isn’t the case.

How you choose to implement the plugin is, of course, up to you.  Here’s one suggestion:

# check json from http
define command{
 command_name    check_http_json-string
 command_line    /etc/nagios3/plugins/check_http_json.rb -u 'http://$HOSTNAME$:$ARG1$/$ARG2$' -e '$ARG3$' -r '$ARG4$'
}
define command{
 command_name    check_http_json-int
 command_line    /etc/nagios3/plugins/check_http_json.rb -u 'http://$HOSTNAME$:$ARG1$/$ARG2$' -e '$ARG3$' -w '$ARG4$' -c '$ARG5$'
}

# make use of http json check
define service{
 service_description     elasticsearch-cluster-status
 check_command           check_http_json-string!9200!_cluster/health!status!green
}
define service{
 service_description     elasticsearch-cluster-nodes
 check_command           check_http_json-int!9200!_cluster/health!number_of_nodes!4:!3:
}

Author: phrawzty

I have a computer.

3 thoughts on “Nagios plugin to parse JSON from an HTTP response”

  1. Dear Dan, may I ask you how to address the entry DOB in the following JSON response using your plugin? Thanks for help and sorry about pointing to such an old post 😉 Regards, Reinhard

    {
    “responseHeader”:{
    “status”:0,
    “QTime”:1,
    “params”:{
    “indent”:”true”,
    “q”:”firstName:MyFirstName ANDnlastName:MyLastName ANDncity:MyCity”,
    “wt”:”json”}},
    “response”:{“numFound”:1,”start”:0,”docs”:[
    {
    “id”:”37858200″,
    “Sex”:”M”,
    “firstName”:”MyFirstName”,
    “lastName”:”MyLastName”,
    “DOB”:”12345678″,
    “zipCode”:”1234″,
    “city”:”MyCity”,
    “streetName”:”MyStreet”,
    “streetNumber”:”1″,
    “Status”:”U”,
    “Wikex_Pers”:”12″,
    “Wikex_PAC”:”12″,
    “Wikex_Raster”:”12″,
    “_version_”:12345678}]
    }}

    Like

    1. Hello,

      You probably tried specifying the element as response.docs.DOB and the plugin couldn’t find it, right? 🙂 Pro tip: you can use the element_regex feature to help you track down cases like this. Consider:

      $ ./check_http_json.rb -f ./reinhard.json -E DOB -r 12345678
      OK: response.docs.0.DOB is 12345678

      As you can see, the dotted path contains a zero, which solves your problem but raises a new question: why is there a zero at all? If you look at the JSON again, you can see that the data structure described by response.docs is an array, which adds a layer of abstraction that needs to be labelled. In Ruby, arrays are referenced positionally (starting with zero), which is exactly where the label comes from.

      Hope that helps!

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s