Escaping the Zabbix UI pain: How to create a combined graph for a number of hosts using the Zabbix API

How to display the same item, f.ex. Processor load, for a number of hosts on the same graph

How to avoid getting crazy from all the slow clicking in the Zabbix UI by using its API

I will indicate how it could be done with plain HTTP POST and then show a solution using the Python library for accessing the Zabix API.

The problem we want to solve is to create a graph that plots the same item for a number of hosts that all are from the same Host group but not all hosts in the group should be included.

Zabbix API

Zabbix API is a REST API introduced in 1.8 that enables the management of Zabbix resources such as items, triggers, and graphs. The resources are connected together via IDs so you usually need to get a resource by its name, extract its id, and use that to get related resources.

The API documentation in v1.8 is ... lacking so I usually read the v2.2 documentation then check the corresponding page and example in 1.8 and how it will work. The documentation occasionally contains mistakes so don't trust it. (F.ex. item.get's filter should be an array but in fact is an object.) It also isn't clear, for get, when fields are ORed and when ANDed and whether you can do anything about it.

There are multiple libraries for the Zabbix API, I've chosen Python because I like it and the zabbix_api.py because it seems to be maintained and developed. I had an issue in authorization with it but managed to work around it.

Using the API

Authentication & authorization

You usually first authenticate with Zabbix and use the auth token you get from it in all subsequent calls.

Catch: Zabbix API must be enabled for the user

The Zabbix user used for communication with the API must be authorized to use the API (there is a check box for that in Zabbix administration). In our configuration this is off by default and, in our case, users must be added to the Zabbix api group.

If you do not have access, you will be able to authenticate with the API but other requests will fail with "No API access".

Creating a graph with zabbix_api.py

Some notes:

I had troubles with authorization, I had to specify user & password both in the constructor (for http basic auth. headers) and call the login method to make it work; in theory, only one of these two shall be necessary. (I might have made a mistake somewhere.)

There are some advantages over curl such as not needing to specify unimportant attributes such as request id and having automatic mapping between Python lists/dicts and JSON.

try:
# I had to spec. user+psw here to use Basic http auth to be able
# to log in even though I supply them to login below;
# otherwise the call failed with 'Error: HTTP Error 401: Authorization Required'
self.zapi = ZabbixAPI(
server="https://zabbix.example.com",
path="/api_jsonrpc.php",
user=user, passwd=passwd,
log_level=log_level) # or DEBUG

## GET ITEMS to include in the graph
# See (Zabbix 2.0 so not 100% relevant but better doc)
# https://www.zabbix.com/documentation/2.0/manual/appendix/api/item/get
filters = {}
if item_descr: filters["description"] = item_descr
if item_key: filters["key_"] = item_key

Other ways

As my colleague Markus Krüger has noted:

You could also use auto registration or auto discovery to add hosts to groups, then extract aggregated data across all hosts in the host group. (Granted, that only works if you want data from all hosts in the group - but if you don't want the data, don't add the host to that group.) That way, no manual work is needed to add monitoring and graphing across multiple instances winking into and out of existence.

This makes it possible to get aggregate metrics such as avg, max, min, sum of a metric for the whole host group. Using auto iscovery and auto registration makes it possible to assign hosts to groups automatically.

Conclusion

Using the API is easy and quick, especially with Python. Working the the UI is so slow and painful that I really recommend using the API.