Quantcast
Channel: unixcat – About monitoring

MK Livestatus. Accessing Nagios data with “unixcat” and LQL.

$
0
0

Introduction.

In recent posts we have installed check_mk in Centos / Redhat 6 or Centos / Redhat 7. Installing full check_mk integrates MK Livestatus component although it is also possible to install it separately to access a Nagios standalone data.

The most important thing is to know initially that data can be obtained and the format of these. We will use a utility included with MK Livestatus for Nagios data access, unixcat. Then in another post we will see how to access data through one of the APIs that includes MK Livestatus (Python).

Local access via socket.

 

LQL – The Livestatus Query Language

We can ask for Nagios data to MK Livestatus with its own language, LQL, created for this purpose. This language has a similar sintaxis to SQL by adapted to query Nagios object tables, There are numerous examples in the official documentation.

We will use LQL to access Nagios data using the utility unixcat.

 

Access to data by “unixcat” utility

Let’s use the “unixcat” utility provided by the installation of Livestatus. By this utility you can, very easily, perform queries to MK Livestatus by attaching the “LQL” file with the syntax of the data to search. Unixcat binary is normally installed with check_mk but maybe not in the user path.

A simple example. We create a file LQL “test.lql” to get Nagios services in critical state.

GET services
Columns: host_name description state
Filter: state = 2
Filter: in_notification_period = 1

Run unixcat passing LQL file to MK Livestatus socket and we get the columns and records that match the filter.

$ unixcat < test.lql /opt/omd/sites/jrm2/tmp/run/live
localhost;Interface 2;2
srv-debian;Interface 2;2
srv-ubuntu;Interface 2;2

 

With a simple query we can pass it directly on the command line. E.g. all hosts:

$ echo 'GET hosts' | unixcat /usr/local/nagios/var/rw/live

The syntax is very simple but … how do we know the available fields and values of tables for filtering?

Data tables.

To find fields that contains a table we must query to a special table “columns”. LQL query to know all fields in all tables coul be:

$ echo 'GET columns' | unixcat /opt/omd/sites/jrm2/tmp/run/live
The name of the column within the table;name;columns;string
The name of the table;table;columns;string
….

You can get at all the fields of all tables. In the the next to last column, the table name to which each field belongs to. To be more specific we can get the information for a table with the following filter query and LQL file “Hosts.lql

GET columns
Filter: table = hosts

Execute with unixcat and get all the fields of hosts table with description (with possible values where appropriate); field_name; table; value_type

$ unixcat < hosts.lql /opt/omd/sites/jrm2/tmp/run/live
description;name;table;type
Whether passive host checks are accepted (0/1);accept_passive_checks;hosts;int
Whether the current host problem has been acknowledged (0/1);acknowledged;hosts;int
Type of acknowledgement (0: none, 1: normal, 2: stick);acknowledgement_type;hosts;int

Default return is in CSV format. We can change this to get data in JSON or Python format with a descripción line about exit type in LQL query file:

OutputFormat: json
OutputFormat: python

 

A good starting point is to list and store in an appropriate format all information of each table, either created the LQL files or directly on the command line by specifying the table and save this info. E.g.

GET columns
Columns: description name type
Filter: table = hosts
unixcat < hosts.lql /opt/omd/sites/jrm2/tmp/run/live

With command line direcly (without use a LQL file)

printf 'GET columns \nFilter: table = hosts \n' | unixcat /opt/omd/sites/jrm2/tmp/run/live >> hosts.csv

In conclusion, having these tables by hand, it is possible we use them very often.
Unixcat is helpful to become familiar with the possibilities and with scripting with bash or any other language even from other computers with ssh. For more complex programs / scripts is better use the Python, Perl or C++ API designed for accessing data that include MK Livestatus. There is documentacion about this in sofware directory install.
We can access the socket file directly or through network providing access to the file with Xinet.

 

Configuring remote access to Livestatus socket.

With check_mk running configuration for access through a TCP socket to Livestatus is simple and well documented . There are two possibilities: configure an installation of OMD or in simple installation either MK Livestatus alone or integrated with full install Check_mk.

Configuring an installation of OMD (for a specific site)

To access network in Livestatus by OMD run the configuration for the “instance / user” desired. E.g. with an instance OMD “jrm2” previously created:

omd config jrm2

omd_config_jrm2_livestatus1

 

Select “Distributed Monitoring” and activate “LIVESTUS_TCP”

 

omd_config_jrm2_livestatus2

If the instance is running, it may be necessary to restart and ask us to do so. Basically it add a xinetd configuration file to access the file through this socket using unixcat utility. This menu utility create the configuration file in the etc/xinetd directory in OMD user instance site. Initially we were particularly interested in “only from” parameter to access from another computer to the socket.

{
 type = UNLISTED
 socket_type = stream
 protocol = tcp
 wait = no
 cps = 100 3
 instances = 500
 per_source = 250 
 flags = NODELAY
 only_from = 127.0.0.1 10.0.20.1 10.0.20.2
 disable = no
 port = 6557
 user = jrm2
 server = /omd/sites/jrm2/bin/unixcat
 server_args = /omd/sites/jrm2/tmp/run/live
}

You will need to reload the site in OMD: omd reload jrm2

 

Configure a standalone Installation of MK Livestatus (or integrated into check_mk)

For a standalone installation of MK Livestatus or integrated in check_mk full install we must make this part. We will make sure that xinetd is installed and create the file to be accessed from other systems. An example for a /etc/xinetd.d/livestatus file in the documentation cmk Livestatus. Basically it would be similar at OMD config file.

service livestatus
{
 type = UNLISTED
 port = 6557
 socket_type = stream
 protocol = tcp
 wait = no
# limit to 100 connections per second. Disable 3 secs if above.
 cps = 100 3
# set the number of maximum allowed parallel instances of unixcat.
# Please make sure that this values is at least as high as
# the number of threads defined with num_client_threads in
# etc/mk-livestatus/nagios.cfg
 instances = 500
# limit the maximum number of simultaneous connections from
# one source IP address
 per_source = 250
# Disable TCP delay, makes connection more responsive
 flags = NODELAY
 user = nagios
 server = /usr/bin/unixcat
 server_args = /var/lib/nagios/rw/live
# configure the IP address(es) of your Nagios server here:
 only_from = 127.0.0.1 10.0.20.1 10.0.20.2
 disable = no
}

Careful, you must enable both IP addresses of computers allowed (parameter only_from) and enable / filter access to the local Firewall tcp port 6557 from the outside.

Testing remote access to Livestatus.

We can use for example the Netcat utility to remotely access another computer Livestatus and get information:

echo 'GET hosts' | nc host_remoto 6557
echo 'GET status' | nc host_remoto 6557

Continue with post “MK Livestatus. Get Nagios data with Python API2.

Download this post.

 

The post MK Livestatus. Accessing Nagios data with “unixcat” and LQL. appeared first on About monitoring.


MK Livestatus. Get Nagios data with Python API.

$
0
0

Introduction.

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.

check_mk_livestatus_plugin

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 .

    import livestatus

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.

    socket_path = "tcp:" + "localhost:6557"

We must trying sample script to test how queries works.

Obtaining data.

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, …)

Querys examples:

  • 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
 

The post MK Livestatus. Get Nagios data with Python API. appeared first on About monitoring.