commit 4161e4cd515e6edd8d43f605def7a3d0d9176e70 Author: Benjamin Renard Date: Tue Mar 1 19:50:28 2022 +0100 Initial version diff --git a/README.md b/README.md new file mode 100644 index 0000000..9a03842 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# Icinga/Nagios plugin to check status of a Livestatus socket + +This script could be used as Icinga/Nagios check plugin to check Livestatus socket status. + +## Installation + +``` +git clone https://gogs.zionetrix.net/bn8/check_livestatus.git /usr/local/src/check_livestatus +mkdir -p /usr/local/lib/nagios/plugins +ln -s /usr/local/src/check_livestatus/check_livestatus /usr/local/lib/nagios/plugins/ +``` + +## Usage + +``` +usage: check_livestatus [-h] [-d] [-v] [-l LOGFILE] [-C] [-U UNIX_SOCKET_PATH] + [-H HOST] [-p PORT] [-t TIMEOUT] + +Icinga/Nagios plugin to check status of a Livestatus socket + +optional arguments: + -h, --help show this help message and exit + -d, --debug Show debug messages + -v, --verbose Show verbose messages + -l LOGFILE, --log-file LOGFILE + Log file path + -C, --console Also log on console (even if log file is provided) + -U UNIX_SOCKET_PATH, --unix-socket-path UNIX_SOCKET_PATH + Livestatus UNIX socket path + -H HOST, --host HOST Livestatus host (default: 127.0.0.1) + -p PORT, --port PORT Livestatus port (default: 6557) + -t TIMEOUT, --timeout TIMEOUT + Livestatus timeout in second (default: 2) +``` + +## Copyright + +Copyright (c) 2022 Benjamin Renard + +## License + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + diff --git a/check_livestatus b/check_livestatus new file mode 100755 index 0000000..1a3390e --- /dev/null +++ b/check_livestatus @@ -0,0 +1,143 @@ +#!/usr/bin/python2.7 +""" +Icinga/Nagios plugin to check status of a Livestatus socket +""" +import argparse +import json +import logging +import os +import socket +import sys +import traceback + +DEFAULT_HOST = '127.0.0.1' +DEFAULT_PORT = 6557 +DEFAULT_TIMEOUT = 2 + +### MAIN #### +parser = argparse.ArgumentParser(description=__doc__) + +parser.add_argument( + '-d', '--debug', + action='store_true', + help='Show debug messages' +) + +parser.add_argument( + '-v', '--verbose', + action='store_true', + help='Show verbose messages' +) + +parser.add_argument( + '-l', + '--log-file', + action="store", + type=str, + dest="logfile", + help="Log file path" +) + +parser.add_argument( + '-C', '--console', + action='store_true', + help='Also log on console (even if log file is provided)' +) + +parser.add_argument( + '-U', '--unix-socket-path', + action='store', + type=str, + dest='unix_socket_path', + help='Livestatus UNIX socket path', +) + +parser.add_argument( + '-H', '--host', + action='store', + type=str, + dest='host', + help='Livestatus host (default: %s)' % DEFAULT_HOST, + default=DEFAULT_HOST +) + +parser.add_argument( + '-p', '--port', + action='store', + type=int, + dest='port', + help='Livestatus port (default: %d)' % DEFAULT_PORT, + default=DEFAULT_PORT +) + +parser.add_argument( + '-t', '--timeout', + action='store', + type=float, + dest='timeout', + help='Livestatus timeout in second (default: %s)' % DEFAULT_TIMEOUT, + default=DEFAULT_TIMEOUT +) +options = parser.parse_args() + +# Initialize log +log = logging.getLogger() +logformat = logging.Formatter("%(asctime)s - " + os.path.basename(sys.argv[0]) + " - %(levelname)s - %(message)s") + +if options.debug: + log.setLevel(logging.DEBUG) +elif options.verbose: + log.setLevel(logging.INFO) +else: + log.setLevel(logging.WARNING) + +if options.logfile: + logfile = logging.FileHandler(options.logfile) + logfile.setFormatter(logformat) + log.addHandler(logfile) + +if not options.logfile or options.console: + logconsole = logging.StreamHandler() + logconsole.setFormatter(logformat) + log.addHandler(logconsole) + +try: + if options.unix_socket_path: + peer = options.unix_socket_path + livestatus = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + livestatus.connect(options.unix_socket_path) + elif options.host and options.port: + peer = "%s:%d" % (options.host, options.port) + livestatus = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + livestatus.connect((options.host, options.port)) + else: + parser.error('You must provide Livestatus UNIX socket path or host & port') + sys.exit(3) + livestatus.settimeout(options.timeout) + + livestatus.send("GET status\nOutputFormat: json\nColumnHeaders: on\n\n") + livestatus.shutdown(socket.SHUT_WR) + rawdata = livestatus.makefile().read() + status = None + if rawdata: + data = json.loads(rawdata) + assert isinstance(data, list) and len(data) == 2, "Invalid Livestatus return:\n%s" % data + status = dict( + (data[0][idx], value) + for idx, value in enumerate(data[1]) + ) +except Exception: + print( + 'UNKNOWN - Fail to retreive status from Livestatus from %s\n\nException:\n%s' % + (peer, traceback.format_exc()) + ) + sys.exit(2) + +if isinstance(status, dict) and 'num_hosts' in status: + print('OK - %s host(s) found\n' % status['num_hosts']) + for key in sorted(status.keys()): + print('%s: %s' % (key, status[key])) + sys.exit(0) + +print('UNKNOWN - Invalid Livestatus return\n\n%s' % data) +sys.exit(3)