Lightweight dashboard for Zabbix network services monitoring based on Vue.js.
In order to provide at-a-glance network services health monitoring, I put together a front-end dashboard based roughly on Andrew Letson's zabbixweb Zabbix API library. The dashboard provides a cleaner, semi-customizable interface that Zabbix lacks, and provides near-realtime monitoring intended for use on a view-only kiosk (such as FullPageOS for Raspberry Pi).
The app is broken into the following components:
/js/zabbix.js
: A Zabbix API library (unmodified from Andrew), which handles basic authentication and API call duties to the Zabbix server/js/app.js
: This dashboard app, which primarily parses Zabbix API's (somewhat overcomplicated) JSON data into a simpler JSON object suitable for use with Vue.js/js/config.js
: A simple JSON object containing the host and item information to be displayed on the dashboard (see below)/index.html
: A static HTML page containing template and layout data and logic
Most of the work behind this dashboard app is put into maintaining a clean separation of concerns between the bulk raw API data (Zabbix API and /js/app.js
), host configuration (/js/config.js
), and display (index.html
).
Layout and styles from precompiled Bootstrap/Font Awesome.
- Zabbix installation with API and guest access enabled
- Basic HTTP service (Apache, nginx) that can serve
index.html
, can be the same service that serves Zabbix
Zabbix should be configured separately according to Zabbix documentation. As a guide, the process is roughly:
- Install a Zabbix agent on a host that you want to monitor
- Adjust firewall rules to allow Zabbix agent to communicate
- Add the host Zabbix
- Import an existing template or enable auto-discovery to populate host items, or manually define host items
From there, host item data will be included in the API request payload.
Ubiquiti UniFi AP shown in this example requires a separate proxy middleware to feed AP data into Zabbix, requiring separate installation and host item key definition. Refer to UniFi Proxy and Uniquiti UniFi + zabbix discussion for further information.
Support for printer status monitoring (toner level, printed page count, tray status) is provided by SNMP reporting. You will need to refer to your printer's SNMP documentation to identify the correct SNMP OIDs, then add them to a Zabbix host as a manually-defined item. As each printer manufacturer has different SNMP OID values/units/codes, some trial and error may be necessary. Additional SNMP authentication and corresponding firewall configuration may be necessary.
When fetching data from the Zabbix API, the returned JSON payload is extremely granular, generally unit-less, and not dashboard-friendly. In order to support a broad range of monitoring capabilities, Zabbix treats monitoring data as raw data, and does not distinguish between data types (such as booleans or decimals) or display formats (such as progress bars, percentages, or status icons). Zabbix provides rudimentary ways for data to be consumed, such as assigning human-readable labels to response/error codes on a per-item basis. But configuration is cumbersome, and Zabbix's built-in dashboards are still primarily text-based.
/js/app.js
takes care of parsing the dense Zabbix API JSON object and populating a local variable data
with the appropriate hosts and item data. The parseData
method extracts only the data specified in /js/config.js
to ensure low resource usage client-side, and formats each host's items (CPU, memory/disk usage, etc) into appropriate formats (decimals, percentages, booleans) for handling.
All parsed host data is stored in a client-side data
object.
Supported host item taxonomy (object "types"):
cpu
: CPU usage, percentageproc
: process count, integeruptime
: host uptime, secondsping
: host response time, millisecondsvm
: memory usage, object containingused
: memory usage, bytestotal
: total memory, bytes
vfs
: disk usage, array of objects, each object containingused
: disk used space, bytesfree
: disk free space, bytestotal
: total disk size, bytes
if
: network traffic, array of objects, each object containngin
: network traffic in, bitsout
: network traffic out, bits
services
: service status, array of strings, each string containing "OK" or "ERROR" as the boolean status of the servicetoner
: printer toner level, array of objects, each object containngcurrent
: current toner level, integertotal
: toner total level, integer
pagecount
: printer page count, array of integers, each integer containing the reported page count
Basic Ubiquiti UniFi AP monitoring is also supported with this taxonomy:
users
: number of users connected to AP, integerin
: network traffic in, bitsout
: network traffic out, bits
Since Zabbix has built-in graph rendering, the Ubiquiti UniFi AP traffic graphs shown above are handled by simply defining the URL that points to the corresponding Zabbix graph. An arbitrary query string (timestamp) is appended to the URL to ensure the browser does not use a cached image.
Unit conversion is done inside index.html
so that no additional logic is required inside /js/app.js
or /js/config.js
.
Dashboard configuration is kept separate in /js/config.js
and contains an object hosts
that tells the dashboard app what data to retrieve for each defined host.
'MONITOR': {
label: 'MONITOR',
icon: 'server',
cpu: 'system.cpu.load[percpu,avg1]',
proc: 'proc.num[]',
vm: {
used: 'vm.memory.size[used]',
total: 'vm.memory.size[total]'
},
vfs: {
'DISK': {
used: 'vfs.fs.size[/,used]',
free: 'vfs.fs.size[/,free]',
total: 'vfs.fs.size[/,total]'
}
},
uptime: 'system.uptime',
ping: 'agent.ping',
if: {
'ETH0': {
in: 'net.if.in[p6p1]',
out: 'net.if.out[p6p1]'
}
},
services: {
'SSH': { key: 'net.tcp.port[,22]', ok: '1' },
'APACHE': { key: 'net.tcp.port[,80]', ok: '1' },
'MYSQL': { key: 'net.tcp.port[,3306]', ok: '1' }
}
},
As you can see, the format follows the data
object taxonomy. The values for each key correspond to the host item key defined in Zabbix. Since Zabbix API will dump all of the raw data indexed for each host by this key, there is no consistency in how "Disk Usage" (for instance) is defined across different systems (Windows, Linux, etc). The key-values in /js/config.js
lets you manually identify the appropriate Zabbix item key that corresponds to the monitored item. This also allows you to arbitrarily define arrays of monitored items, such as multiple disks or services, which may vary between hosts with different hardware configurations.
In addition, the services
sub-object includes an ok
sub-key, which defines the expected value that corresponds with an "OK/No Error" status. This allows you to set the correct corresponding response code for each service (for example, ok: '1'
may mean "Running" for one service, while meaning "Error" for another service).
One-way data-binding is handled automatically with Vue and populated in templating code in index.html
. /js/app.js
polls the Zabbix API at a defined interval, parses the JSON response, and updates the client-side data
object. The data
object is passed into the Vue app initialization, so any updates to data
will cause Vue to update the dashboard.
Note: In this instance, /js/app.js
is set to fetch from the Zabbix API every 10 seconds. However, individual host items may be configured in Zabbix to update at slower intervals (30 seconds, 1 minute, etc) and therefore will not appear to update on the dashboard until the next Zabbix-defined interval.
As the app requires actual Zabbix API data to parse, no demo is available directly from this repo. However, assuming a working Zabbix instance meeting the requirements is accessible, /js/config.js
should be easy to modify to adapt to different Zabbix installations.