In the Zabbix an item is created for each monitored value of a host.
The values represented by the items can be displayed in graphs in a simple way.
Both the items and the graphs can be created dynamically using discovery rules.
Typically, the items, the graphs and the discovery rules are coupled in a template. The template is then applied to multiple hosts.
The discovery rule determines what is to be detected on the host - e.g. CPU cores. If the discovery rule contains an item prototype then an item is created for each discovered object within the host - e.g. one item for each CPU core. In similar way, graph prototypes are used to create a graph within a host. The graph can display a value of discovered item.
Unfortunately, in the current version of Zabbix 5.0.0 (May 2020), it is not possible to create a graph using a graph prototype that displays all detected items. The graph prototype creates one graph for each detected item. E.g., for four cores there are four graphs created.
There is a great extension Graph LLD for Zabbix which allows to dynamically create graphs of agregated discovered items. It's quite user friendly, the control is integrated into the Zabbix web frontend. But it is difficult to keep the Zabbix up to date, because as the Zabbix web frontend is changed, compatibility with the Graph LLD is lost.
Therefore I created my own frontend-independent tool for dynamic graph creating that uses Zabbix API functions.
The script is executed by Node.js.
It does not use graph prototypes. Instead, you need to create a special separate template. Create "dummy items" in this template. It doesn't matter what a value of dummy item is, the name of it is important. The name of dummy item is a regular expression that determines which corresponding items in the host will be selected for a graph. Then create a graph in the template. Let the graph contains one or more dummy items. This graph will be used as a model to create an actual graph for a host.
Create a link between a host and the special template. Then, when you run the script, a graph is created for the host with items that match the regular expression in the model graph's dummy item name. All host items are compared to the regular expression, regardless of whether they were created manually, by using a template, or by a discovery rule.
To establish the link between a host and the special template you have to set a proper value of macro named {$DISCOVERY_GRAPH_TEMPLATES}
. This macro can be defined either within the host or within a regular template used by the host. The value of the macro is a JSON of array of strings, each the string is the exact name of the special template.
The script stores information about graphs created by it in a status file. The graphs which becomes obsolete are deleted. This can happen, for example, if the link to a special template with model graphs is removed.
It is a good idea to run the script by cron periodically so the graphs are created/updated/deleted automatically according to changes in the Zabbix configuration.
Suppose you have a Zabbix server and it works properly, and you also have at least one host with Zabbix agent installed. For our example, let the host is named myserver1. Suppose the host is already configured in host list in the Zabbix server as a member of group My Host Group.
In this scenario, we will run the script on the same computer where the Zabbix server is. But it can be run on any computer that can connect to the Zabbix web frontend, even on MS Windows with Node.js installed.
If you have not Node.js in your system then install it using your favored package manager or download it. For example in RHEL/CentOS:
[root@zabbix ~] yum install nodejs
Create some directory for the script. The /opt/zabbix-discoverygraphs
directory is used in this example. The script needs sync-request module to run. So install it using nmp in the prepared directory. This will create the necessary module subdirectories.
[root@zabbix ~]# mkdir /opt/zabbix-discoverygraphs
[root@zabbix ~]# cd /opt/zabbix-discoverygraphs
[root@zabbix zabbix-discoverygraphs]# npm install sync-request
Download the script into the created directory.
[root@zabbix zabbix-discoverygraphs]# wget https://tinyurl.com/manak-cz/web/zabbix-discoverygraphs/zabbix-discoverygraphs.js
Open the script using your favored editor and customize values of variables in the config section.
api_jsonrpc.php
.
// ******************************* CONFIG *************************************
// Definition of API connection
var APIADR='http://localhost/zabbix/api_jsonrpc.php';
var APIUSR='admin';
var APIPWD='zabbix';
// The status file contains a record of created graphs - it's needed to delete graphs that become obsolete
var STATUSFILE='/opt/zabbix-discoverygraphs/zabbix-discoverygraphs.status';
Now you can test if the configuration is correct. If you run the script now all you should get is a warning about missing status file.
[root@zabbix zabbix-discoverygraphs]# ./zabbix-discoverygraphs.js
!!! WARNING: Cannot read status file '/opt/zabbix-discoverygraphs/zabbix-discoverygraphs.status'
Error: ENOENT: no such file or directory, open '/opt/zabbix-discoverygraphs/zabbix-discoverygraphs.status'
The obsoleting discovery graphs will not be deleted
It's OK if the file is missing during the first run - the file will be created
The status file has been created. So if you run the script once again there should be none output. In case there is other error or warning you can run the script with parameter -d
to see detailed debug info.
Log into your Zabbix web frontend using administrative account. Go to Configuration→Templates and click Create template button.
Create template within group My Host Group, name it for example CPU Utilisation Template. Click Add.
Now add a new item into the template. Open the template you have just created. In Configuration→Templates click on the name of the template. Then click Items and then click Create item button. Set the item parameters like this:
Name: | CPU Utilisation Percentage |
Type: | Zabbix agent |
Key: | system.cpu.util[] |
Type of information: | Numeric (float) |
Units: | % |
Update interval: | 1m |
Now add a discovery rule to the template. Click Discovery rules and then Create discovery rule button. Set the discovery rule parameters like this:
Name: | CPU Discovery |
Type: | Zabbix agent |
Key: | system.cpu.discovery |
Update interval: | 1m |
Now add an item prototype to the discovery rule. In the list of discovery rules click on the name of the rule you have just created. Then click Item prototypes and then Create item prototype button. Set the item prototype parameters like this:
Name: | Core {#CPU.NUMBER} Utilisation Percentage |
Type: | Zabbix agent |
Key: | system.cpu.util[{#CPU.NUMBER}] |
Type of information: | Numeric (float) |
Units: | % |
Update interval: | 1m |
Finally assign the new template to your host. Go to Configuration→Hosts, click on the name of your host (myserver1 in our example) and then click Templates (the templates of the host, not the templates in main menu, obviously). In the Link new templates input box select the CPU Utilisation Template you have created. Then click Update.
Wait one or two minutes to propagate the discovery rule to your host. Then the host myserver1 should have these items:
Go to Configuration→Templates and click Create template button.
Create template within group My Host Group, name it for example CPU Graphs Template. Click Add.
Now add new dummy items into the template. The dummy items will be used as placeholders for actual items in a graph. Open the template CPU Graphs Template you have just created. In Configuration→Templates click on the name of the template. Then click Items and then click Create item button. The name of the first dummy item is a regular expression that matches the actual item name "CPU Utilisation Percentage". Set the item parameters like this:
Name: | ^CPU Utilisation Percentage$ |
Type: | Calculated |
Key: | dummy1 |
Formula: | 0 |
Type of information: | Numeric (float) |
Units: | % |
Update interval: | 1d |
Add the second dummy item the same way as the first. The name of the second dummy item is a regular expression that matches the names of actual items "Core x Utilisation percentage". Set the item parameters like this:
Name: | ^Core \d+ Utilisation Percentage$ |
Type: | Calculated |
Key: | dummy2 |
Formula: | 0 |
Type of information: | Numeric (float) |
Units: | % |
Update interval: | 1d |
Now create a model graph within the CPU Graphs Template. Click Graphs and then click Create graph. Customize these parameters of the graph:
Name: | CPU Utilisation |
Graph type: | Normal |
Y axis MIN value: | Fixed 0 |
Y axis MAX value: | Fixed 100 |
Item 1: | CPU Graphs Template: ^CPU Utilisation Percentage$ - avg, Gradient Line, Left, black |
Item 2: | CPU Graphs Template: ^Core \d+ Utilisation Percentage$ - avg, Line, Left, red |
The special template containing the model graph is ready. Now you have to assign it to a host. It can be done by creating a macro {$DISCOVERY_GRAPH_TEMPLATES}
within a host. But the macros propagate from templates to hosts. Therefore, it's more practical to set the macro within the CPU Utilisation Template created in the step 4.
Go to Configuration→Templates→CPU Utilisation Template→Macros and add the macro {$DISCOVERY_GRAPH_TEMPLATES}
. Let the value of the macro is ["CPU Graphs Template"]
. The value of the macro is a JSON of array of strings where each string is exact name of a template from which you want to provide model graphs. You can assign multiple templates containing model graphs because the macro value is the array. After you add the macro, click Update.
Run the script
[root@aim-monitor-01 zabbix-discoverygraphs]# ./zabbix-discoverygraphs.js
Creating graph 'CPU Utilisation' for host 'myserver1'
If everything goes well you should see a message about creating new graph CPU Utilisation for host myserver1. You can also run the script with parameter -d
to get detailed debug info:
[root@aim-monitor-01 zabbix-discoverygraphs]# ./zabbix-discoverygraphs.js -d
* API authentication ...
* Gathering hosts ...
* Gathering global macros ...
* Gathering templates ...
* Gathering graphs ...
* Loading status file ...
* Browsing hosts/templates topology ...
myserver1 -> CPU Utilisation Template ===> CPU Graphs Template
myserver1 will use template(s) CPU Graphs Template
* Handling graph 'CPU Utilisation' from template 'CPU Graphs Template' for host 'myserver1' ...
Discovery graph item '^CPU Utilisation Percentage$' - found these host items: 'CPU Utilisation Percentage'
Discovery graph item '^Core \d+ Utilisation Percentage$' - found these host items: 'Core 0 Utilisation Percentage', 'Core 1 Utilisation Percentage', 'Core 2 Utilisation Percentage', 'Core 3 Utilisation Percentage'
Graph not changed - no update needed
* Checking obsolete discovery graphs ...
* Saving status file ...
In the debug output you can check if the regular expression in dummy item name matches proper items of a host.
New graph within the host myserver1 is ready as you can check in Monitoring in the web frontend:
If the current utilisation of myserver1 is low and you want to see the graph of loaded server, create some CPU load at myserver1 temporarily:
[root@myserver1 ~]# cat /dev/random > /dev/null
Stop it later with Ctrl+C
You probably don't want to call the script every time you change the configuration of Zabbix. Therefore, set the script to run regularly with cron. Run command:
[root@zabbix zabbix-discoverygraphs]# crontab -e
and add this line into the crontab to run the script each 15 minutes
*/15 * * * * /opt/zabbix-discoverygraphs/zabbix-discoverygraphs.js
Script parameters:
-d0 | Only errors will be displayed. Warnings and other output suppressed. |
-d1 or none parameter | Errors, warnings, list of created/updated/deleted graphs will be displayed. |
-d2 or just -d | Detailed debug info will be displayed. |
When the script creates a graph and one dummy item matches more than one actual host item then the second and another items needs some color for graph line assigned automatically. You can customize the PALETTE
array variable in the script configuration part.
If for any reason the macro name {$DISCOVERY_GRAPH_TEMPLATES}
doesn't suit you then change the macro name in variable ZABBIXMACRO
in the script configuration part.
The script is designed for Zabbix version 5.0.0, perhaps it works with other versions.
The script is absolutely free for use, modification and sharing.