diff --git a/README.md b/README.md index 6630b4e..91f1589 100644 --- a/README.md +++ b/README.md @@ -149,4 +149,66 @@ define command{ ``` OK: Status OK.|'Containers'=1;0;1000 'Images'=11;0;0 'NEventsListener'=3;0;0 'NFd'=10;0;0 'NGoroutines'=14;0;0 'SwapLimit'=1;0;0 +``` + +### Docker Container Monitor Example Plugin + +`check_http_json.py` is generic enough to read and evaluate rules on any HTTP endpoint that returns JSON. In this example we'll get the status of a specific container using it's ID which camn be found by using the list containers endpoint (`curl http://127.0.0.1:4243/containers/json?all=1`). + +##### Connection information + +* Host = 127.0.0.1:4243 +* Path = /containers/2356e8ccb3de8308ccb16cf8f5d157bc85ded5c3d8327b0dfb11818222b6f615/json + +##### Rules for "aliveness" + +* Verify that the key `ID` exists and is equal to the value `2356e8ccb3de8308ccb16cf8f5d157bc85ded5c3d8327b0dfb11818222b6f615` +* Verify that the key `State.Running` has a value of `True` + +#### Service Definition + +`localhost.cfg` + +``` + +define service { + use local-service + host_name localhost + service_description Docker container liveness check + check_command check_my_container + } + +``` + +#### Command Definition with Arguments + +`commands.cfg` + +``` + +define command{ + command_name check_my_container + command_line /usr/bin/python /usr/local/nagios/libexec/plugins/check_http_json.py -H 127.0.0.1:4243 -p /containers/2356e8ccb3de8308ccb16cf8f5d157bc85ded5c3d8327b0dfb11818222b6f615/json -q ID,2356e8ccb3de8308ccb16cf8f5d157bc85ded5c3d8327b0dfb11818222b6f615 State.Running,True + } + +``` + +#### Sample Output + +``` +WARNING: Status check failed, reason: Value True for key State.Running did not match. +``` + +The plugin threw a warning because the Container ID I used on my system has the following State object: + +``` + u'State': {... + u'Running': False, + ... +``` + +If I change the command to have the parameter -q parameter `State.Running,False`, the output becomes: + +``` +OK: Status OK. ``` \ No newline at end of file diff --git a/check_http_json.py b/check_http_json.py index 763dfd3..2db2fd1 100755 --- a/check_http_json.py +++ b/check_http_json.py @@ -43,15 +43,24 @@ class JsonHelper: def __init__(self, json_data): self.data = json_data - def equals(self, key, value): return (key in self.data) and (str(self.data[key]) == value) - def lte(self, key, value): return (key in self.data) and (str(self.data[key]) <= value) - def gte(self, key, value): return (key in self.data) and (str(self.data[key]) >= value) - def exists(self, key): return key in self.data - def get(self, key): - if key in self.data: - return self.data[key] + def equals(self, key, value): return self.exists(key) and str(self.get(key)) == value + def lte(self, key, value): return self.exists(key) and str(self.get(key)) <= value + def gte(self, key, value): return self.exists(key) and str(self.get(key)) >= value + def exists(self, key): return (self.get(key) != (None, 'not_found')) + def get(self, key, temp_data=''): + """Can navigate nested json keys with a dot format (Element.Key.NestedKey). Returns (None, 'not_found') if not found""" + if temp_data: + data = temp_data else: - return '' + data = self.data + + if '.' in key: + return self.get(key[key.find('.') + 1:], data[key[:key.find('.')]]) + else: + if key in data: + return data[key] + else: + return (None, 'not_found') class JsonRuleProcessor: """Perform checks and gather values from a JSON dict given rules and metrics definitions""" @@ -73,7 +82,7 @@ class JsonRuleProcessor: for kv in self.rules.key_value_list: k, v = kv.split(',') if (helper.equals(k, v) == False): - reason += " Value %s for key %sdid not match." % (v, k) + reason += " Value %s for key %s did not match." % (v, k) if self.rules.key_lte_list != None: for kv in self.rules.key_lte_list: