Wiki / Integrations

Zabbix Integration

Last updated

Zabbix Integration

Pull CertTracker monitor status into Zabbix using its native HTTP agent items plus low-level discovery (LLD), so every monitor you have in CertTracker auto-creates as a Zabbix item without manual setup.

Community-validated recipe. CertTracker doesn't run a Zabbix install in-house — this guide is written from Zabbix documentation and may need adjustment for your version. Corrections welcome via the community forum.

Plan required. API access is a Business and Enterprise plan feature. See API access for token creation.

Architecture

+----------------+         +-----------------------+
|  Zabbix server |         |  CertTracker          |
|                |  HTTPS  |                       |
|  HTTP agent --------------->|  /api/v1/monitors  |
|  (master item) |         |                       |
|       |        |         +-----------------------+
|       v        |
|  LLD discovers |
|  per-monitor   |
|  items + trigs |
+----------------+

The pattern: one master HTTP agent item fetches the full JSON, dependent items extract per-monitor values via JSONPath preprocessing, and LLD auto-creates one item set per discovered monitor.

Step 1 — Mint a CertTracker API token

Standard flow from API access: Administration → API Tokens → Create. Name it zabbix-prod. Copy the ct_live_... value.

Step 2 — Create a host in Zabbix for CertTracker

Configuration → Hosts → Create host

Field Value
Host name certtracker
Visible name CertTracker (12Squared)
Groups Applications or whatever group you use
Interfaces None required (HTTP agent items don't use the host interface)

Add a host macro:

Macro Value
{$CERTTRACKER_TOKEN} ct_live_xxxxxxxxxxxxxxxxxxxxxxxx
{$CERTTRACKER_BASE} https://certtracker.12squared.com

Macros at the host level keep the token out of every item definition and make rotation a one-field change.

Step 3 — Master HTTP item

Items → Create item

Field Value
Name CertTracker raw services JSON
Type HTTP agent
Key certtracker.raw
URL {$CERTTRACKER_BASE}/api/v1/integrations/librenms/services
Request type GET
Headers Authorization: Bearer {$CERTTRACKER_TOKEN}
Update interval 5m
History storage 1d (raw JSON, doesn't need long retention)
Type of information Text

This single item holds the full payload; everything else pulls from it.

Step 4 — Low-level discovery rule

Discovery rules → Create discovery rule

Field Value
Name CertTracker monitors
Type Dependent item
Master item CertTracker raw services JSON
Key certtracker.discovery
Update interval 0 (triggers off the master)

Preprocessing tab — add one step:

Type Parameters
JSONPath $.services[*]

Then in the LLD macros tab:

LLD macro JSONPath
{#LABEL} $.label
{#MONITOR_ID} $.monitor_id
{#STATUS} $.status

Step 5 — Item prototypes

In the same discovery rule → Item prototypes tab → create:

Prototype A: per-monitor exit code

Field Value
Name CertTracker {#LABEL}: exit code
Type Dependent item
Master item CertTracker raw services JSON
Key certtracker.exit_code[{#LABEL}]
Type of information Numeric (unsigned)

Preprocessing — one step:

Type Parameters
JSONPath $.services[?(@.label == '{#LABEL}')].exit_code.first()

Prototype B: per-monitor message

Same shape, key certtracker.message[{#LABEL}], type Text, JSONPath ends in .message.first().

Prototype C: per-monitor days-to-expiry (optional, for graphs)

The perfdata string has days_to_expiry=N;30;7;; — easier to extract via a quick regex preprocessing step. Or hit /api/v1/monitors instead of /librenms/services for typed numeric fields:

URL: {$CERTTRACKER_BASE}/api/v1/monitors
JSONPath: $.monitors[?(@.fqdn + ':' + @.port == '{#LABEL}')].days_to_expiry.first()

Step 6 — Trigger prototypes

In the same discovery rule → Trigger prototypes:

Name Expression Severity
CertTracker {#LABEL}: WARNING last(/certtracker/certtracker.exit_code[{#LABEL}])=1 Warning
CertTracker {#LABEL}: CRITICAL last(/certtracker/certtracker.exit_code[{#LABEL}])=2 High or Disaster
CertTracker {#LABEL}: UNKNOWN last(/certtracker/certtracker.exit_code[{#LABEL}])=3 Information (optional)

For each trigger, the description / event name can pull the message field so alerts arrive with context:

Trigger description: {ITEM.LASTVALUE2}

Where ITEM.LASTVALUE2 refers to the message item on the same trigger.

Step 7 — Wait for discovery to fire

LLD runs on its own cadence (default once per hour). To kick it immediately:

  • Configuration → Hosts → certtracker → Discovery rules → CertTracker monitors → Execute now

Within 30 seconds you should see one set of items+triggers per monitor under the host. The exit_code item shows the current 0/1/2/3 value; the message item shows the human-readable nagios line from CertTracker.

Why this pattern

  • One HTTP call per polling cycle even if you have 500 monitors — Zabbix doesn't fan out per item; everything reads from the cached master JSON.
  • Auto-discovery means new monitors in CertTracker show up in Zabbix on the next LLD cycle with no admin action.
  • Standard Zabbix triggers — no scripts on the Zabbix host, no nagios-plugin shim, no env vars to manage. Everything is template config that exports cleanly to YAML/XML for reuse.

Troubleshooting

Symptom Likely cause
Master item returns "Cannot resolve macro" The host macro {$CERTTRACKER_TOKEN} isn't defined on the host.
All values come back NULL JSONPath syntax may differ between Zabbix versions. Test in Zabbix → Test item with the raw JSON pasted in.
Discovery returns 0 items Token is valid but plan isn't Business/Enterprise — check raw response, expect {"error":"plan_required"}.
401 errors Token revoked or wrong. Mint a new one in CertTracker and update {$CERTTRACKER_TOKEN}.

What's not in this recipe

  • Bulk export of the host template — once you've validated, export via Configuration → Templates so other Zabbix users can import directly.
  • Trigger dependencies so a CRITICAL on the umbrella suppresses spam from individual monitors — nice-to-have, version-specific UI.
  • Inventory linking between Zabbix devices and CertTracker labels — depends entirely on how your Zabbix devices are named.

Contributions to the community forum welcome — especially a template XML/YAML export.