MK Livestatus provides a standard API for accessing Nagios data in various programming languages: Python, Perl and C ++.
The API modules and sample documentation is available for use in these languages and is enough to start testing programs. We must have prior knowledge of Accessing Nagios data with “unixcat” and LQL.
The route to the documentation and the source / libraries normally is in a OMD setup in /omd/versions/default/share/doc/check_mk/livestatus/api/. If we do a direct install of check_mk or MK livestatus standalone the default path usually is the following: /usr/share/doc/check_mk/livestatus/api/.
MK Livestatus API python.
In python directory there are these files
- livestatus.py Python module to API livestatus acces.
- example.py Example API use to accesing one MK Livestatus instance.
- example_multisite.py Example API use to accesing several MK Livestatus instance.
- make_nagvis_map.py Map make Nagvis example program.
Let’s take a look at example.py file.
The necessary module to import in our development python environment is livestatus.py, in the usual way .
MK Livestatus connection.
Following “example.py” we will discuss how to connect using provided API. The proposal is for a OMD setup but is valid for a single product check_mk setup with Nagios as this related post “Nagios 4 (core) + Check_mk + pnp4Nagios + Nagvis”
omd_root = os.getenv("OMD_ROOT") socket_path = "unix:" + omd_root + "/tmp/run/live"
The example is for an installation of OMD and we must be in OMD session site (user created for the site) but we can also test it on a simple installation of ML Livestatus. If we take a look at the specific variables of a site OMD user there is a OMD_ROOT variable.
># env | grep -i omd .. OMD_ROOT=/omd/sites/jrm2 OMD_SITE=jrm2 …
Therefore if we are not in a OMD / OMDistro setup or want to run our Python scripts from other users just need to change the path to the socket file (being on the same server)
socket_path = "unix:" + "/opt/omd/sites/jrm2/tmp/run/live"
We can get an error to accesing data because the socket is created only with permissions for the user of OMD site. We must access with the same user or change directory group owner rights with the same group of users to access.
Even better, we are going to connect to a network socket at server with MK Livestatus in same server (localhost) or another server. It is simple and efficient. We must configure acces to MK Livesatus server socket with xinetd as explained in this post.
We must trying sample script to test how queries works.
In the previous post “MK Livestatus. Accessing Nagios data with “unixcat” and LQL” we saw how to obtain the necessary data from tables and fields for use in LQL queries.
We are going to review now the examples provided in the python file example.py and various options for accessing data with API.
In this example we see two types of connections. In first caseconnect is passing the “query” of data to look at and specifying the type of query (table, row_assoc,)
livestatus.SingleSiteConnection(socket_path).query_row_assoc("GET status").items(): hosts = livestatus.SingleSiteConnection(socket_path).query_table("GET hosts\nColumns: name alias address")
The other connection type first create the connection object and then use it for querys.
conn = livestatus.SingleSiteConnection(socket_path) num_up = conn.query_value("GET hosts\nStats: hard_state = 0")
There are different type of predefined used to specify what kind of data is obtained and the format of the data for output methods. All of them are defined in the API in the livestatus.py file. (Table, query_row_assoc, query_value, query_row, …)
- query_row_assoc returns a data line with a data dictionary, name → value
- query_table returns a list of lists representing each row of the table.
- query_value returns a single value (one line and column = one cell)
- query_row returns a data line with items as a list.
- query_column returns a column with all values as a list.
All examples are very simple and used functions are well detailed in the livestatus.py module. In another example file “example_multisite.py” we can see how to connect simultaneously with several Livestatus servers to run the same query in all of then and return added data.
Let’s see an example of using the python API.
Example. Plugin to verify an MK Livestatus connection from other server.
Let’s see a simple and practical example of using the API, a plugin for Nagios / CMK that we can use to ensure that other servers with MK Livestatus are responding appropriately. In a setup configuration with CMK Multisite is important to ensure that servers with MK Livestatus respond to querys or we can find a scenario in which we can’t see Hosts / services errors from other servers because Multisite server are not connect to MK Livestatus by any reason.
Although in setup definition of Remote Site with MK Multisite you can associate a proper host to validate the remote connection, it is associated with general host status not with MK socket connection responding. What better way than a clasical “plugin” to report problems connecting to the socket or by accessing host / service objects information.
To test the plugin download file from this link The plugin is very simple. We define MK Livestatus server and port to which we will connect plus a host object to search. We will ensure to connect with MK Livestatus and properly return a LQL search from a particular host object.
#!/usr/bin/python # -*- coding: iso-8859-15 -*- # Nagios plugin to check status of ML Livestatus socket # Connect to Livestatus socket from server and look for a object host definition import livestatus import sys cmk_livestatus_nagios_server = "localhost" cmk_livestatus_tcp_port = 6557 host_to_find = "srv0001a" try: # Make a socket #socket_path = "tcp:" + "localhost:6557" socket_path = "tcp:%s:%s" % (cmk_livestatus_nagios_server,cmk_livestatus_tcp_port) except: sys.exit(1) try: # make connection using socket conn = livestatus.SingleSiteConnection(socket_path) # ** LQL quey used to find a host ** # GET hosts # Columns: name # Filter: name = srv0001 host = conn.query_value("GET hosts\nColumns: name\nFilter: name = %s" % host_to_find) print "OK - Host '%s' found in livestatus connect to '%s:%s'" \ % (host_to_find, cmk_livestatus_nagios_server,cmk_livestatus_tcp_port) exit (0) except Exception, e: # livestatus.MKLivestatusException, e: #print "Livestatus error: %s" % str(e) print "CRITICAL - Host '%s' not found or livestatus connect to '%s:%s'" \ % (host_to_find, cmk_livestatus_nagios_server,cmk_livestatus_tcp_port) exit (2)
We are using a connection with MK Livestatus to run a query of type “value” (function / class “query_value”) to search for host only. If found it, it will continue to run and output successful string and return value 0 (OK). If not found, it will execute the exception and get an output error and a return value 2 (Critical for Nagios)
Testing the plugin and return value for Nagios (0 = OK, 2 = Critical)
$ python ./test_livestatus OK - Host 'srv0001' found in livestatus connect to 'localhost:6557' $ echo $? 0 # Cambiando nombre de host a uno inexistente $ python ./test_livestatus CRITICAL - Host 'srv0001a' not found or livestatus connect to 'localhost:6557' $ echo $? 2
Yes. There are not input parameters. All parameters are hardcoded. It is just one example. :)
Other possible uses.
The potential of the API is very interesting. It can be used for new plugins that use existing data, to extract data for the purpose of dealing with external programs (statistics, SLAs, …), to other online programs that show the state of our nagios objects such as do many programs (NagVis, nagstamon, …).
One very important use can be plugins to obtain data from other existing plugins. It may be convenient to perform checks that depend on values obtained from one or more existing checks or that operate with values obtained by other plugins.
In future articles we will try to deepen with other examples.
Download this post as PDF
Donwload python sample script