Querying livestatus with python3. Simple code snipped wanted, please

I am trying to port some bash scripts to python3 code
I am using lql with unixcat ~/tmp/run/live.

This documentation gives a code example how to use livestatus with python:

But when I copy an paste this code on my 2.0 checkmk server and run it I get:

OMD[prod]:~$ python3  livestatus-test.py 
Traceback (most recent call last):
  File "livestatus-test.py", line 17, in <module>
    sock.sendall("GET status\nOutputFormat: json\n")
TypeError: a bytes-like object is required, not 'str'

Therefore I then tried to use a byte-like object by using b"GET …" instead of just “GET …”

But then the livestatus-test-bytes.py script never retruns.

I am looking for a simple python3 code snippet to talk to ~/tmp/run/live please.

The root Problem is, that I need to get the value of check_command
to use it in a Notes URL for Services.

We also want to include documentation for the check_command not only for the $SERVICEDESC$

In the Checkmk Raw Edition the Standard Nagios Macros seem to work so I can use $SERVICECHECKCOMMAND$ in Notes URL for Services but we use the Enterprise Edition where only a few Macros like $HOSTNAME$ and $SERVICEDESC$ seem to work but not $SERVICECHECKCOMMAND$ (which I do not understand why).

However, my workaround is now to use this as Notes URL for Services

/app/docs?host=$HOSTNAME$&service=$SERVICEDESC_URL_ENCODED$

and the /app/docs (which is a python wsgi ) looks up the check_command using lql
with host name and service name as filter.

This is the Code that is working, but it it is limited to 1024 bytes for the received data,
which is sufficient in this case, but If you do lql queries that return more than 1024 bytes it is truncated. I do not know yet how to read data out of the socket util it is “empty”.
But this is some progress I wanted to share.

#!/usr/bin/env python3

import socket

host = 'san1.mycompany.tld'
service = 'Eventlog' 

s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect('/omd/sites/prod/tmp/run/live')
s.sendall(f'GET services\nFilter: host_display_name = {host}\nFilter: display_name = {service}\nColumns: check_command\n\n'.encode())
data = s.recv(1024)
print(data.decode())
s.close()

The reason for this error is that in Python 3, strings are Unicode, but when transmitting on the network, the data needs to be bytes instead. We can convert bytes to string using bytes class decode() instance method, So you need to decode the bytes object to produce a string. In Python 3 , the default encoding is “utf-8” , so you can use directly:

b"python byte to string".decode("utf-8")

Python makes a clear distinction between bytes and strings . Bytes objects contain raw data — a sequence of octets — whereas strings are Unicode sequences . Conversion between these two types is explicit: you encode a string to get bytes, specifying an encoding (which defaults to UTF-8); and you decode bytes to get a string. Clients of these functions should be aware that such conversions may fail, and should consider how failures are handled.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed. Contact an admin if you think this should be re-opened.