Skip to content

Zabbix low-level discovery using Puppet

Zabbix low-level discovery automatically detects host entities to monitor and creates the associated Zabbix items, triggers and graphs. Mounted file systems and network interfaces are two popular types of items that are supported by a vanilla installation of Zabbix on a Linux host. Zabbix can be extended to discover other things by adding so-called user parameters to the agent configuration. Normally these are scripts that output a JSON formatted data structure describing the discovered entities. In this article I present a different solution to create the relevant data by using Puppet.

Most of the blog entries on Zabbix low-level discovery talk about scripts (Bash, Perl, Python, ...) to generate the necessary input for Zabbix. These scripts either look at kernel data in the /proc and /sys pseudo filesystems or run other tools to extract the data. The scripts are often poorly written and needlessly fork processes by the dozen to get the desired data. This causes an additional load on the monitored system.

There is another option if you run Puppet on your hosts. With Facter - Puppet's system information library - you already have a powerful tool that probably includes the data you need to discover. This opens the door to the following implementation:

  1. Puppet already uses Facter to detect discoverable entities
  2. Puppet creates a small file in the proper JSON format for Zabbix
  3. Zabbix low-level discovery only needs to read the file to find the entities
  4. Puppet updates the file whenever the discovered entities change

Let's look at an example. The Zabbix items and require a Linux disk name as first argument. Zabbix currently does not provide a builtin discovery of available disk devices, so we need to roll our own. The following Puppet class is a simple implementation to manage the two files we need for Zabbix.

class zabbix::discovery::disks {

  # The output file for Zabbix
  $jsonfile = '/etc/zabbix/diskdevs.json'

  # Fetch all devices into a sorted array
  $alldisks = sort(keys($::disks))

  # Filter unwanted devices
  $diskdevs = filter($alldisks) |$dev| {
    $dev ? {
      /^cd/   => false,
      /^sr/   => false,
      default => true,

  file { '/etc/zabbix/zabbix_agentd.d/diskdev-discovery.conf':
    ensure  => file,
    owner   => 'root',
    group   => 'root',
    mode    => '0644',
    content => template('zabbix/diskdev-discovery.conf.erb'),
    notify  => Service['zabbix-agent'],

  file { $jsonfile:
    ensure  => file,
    owner   => 'root',
    group   => 'root',
    mode    => '0644',
    content => template('zabbix/diskdevs.json.erb'),
    notify  => Service['zabbix-agent'],

The first file is a configuration file that tells Zabbix about the new key we want to use for discovering our disk devices. From this file Zabbix learns the command it should run to fetch the data. Unfortunately Zabbix currently can't read a file directly so we have to use the cat command to do that. Obviously this is much better than creating a pipeline of multiple perl, awk or grep processes.

The file is created from the following template.,/bin/cat <%= @jsonfile %>

The second file is the JSON representation of an array of disk devices. It is also created by Puppet using this template.

    <%- last_index = @diskdevs.size - 1 -%>
    <%- @diskdevs.each_index do |i| -%>
    { "{#DISK}":"<%= @diskdevs[i] -%>" }<% if (i < last_index) %>,<% end %>
    <%- end -%>

This implements Zabbix low-level discovery for Linux disk devices where Puppet does all the heavy lifting. As you can see it is only a matter of creating the file in the correct format as long as Puppet/Facter has the data available.

Note that I used two Puppet features that are only available in recent releases of Puppet and Facter. First of all the structured fact $::disks which was not available in Facter 1. Then the filter() function which was introduced with the Future Parser (used by default in Puppet 4).


No Trackbacks


Display comments as Linear | Threaded

No comments

Add Comment

Standard emoticons like :-) and ;-) are converted to images.
Textile-formatting allowed
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.

Form options

Submitted comments will be subject to moderation before being displayed.