Skip to main content

netbox-plugin-prometheus-sd

License: MIT CI PyPI

"Buy Me A Coffee"

Provide Prometheus http_sd compatible API Endpoint with data from Netbox.

HTTP SD is a feature since Prometheus 2.28.0 that allows hosts to be found via a URL instead of just files. This plugin implements API endpoints in Netbox to make devices, services, IPs and virtual machines available to Prometheus.

Compatibility

We aim to support the latest major versions of Netbox.

Plugin Netbox
2.x >= 4.0
1.x 3.x (no longer maintained)

Check the .github/workflows/ci.yml pipeline for the current tested builds. Other versions may work, but we do not test them explicitly. All relevant target versions are tested in CI.

Plugin 2.0 also fixed a set of N+1 queries that made the endpoints very slow on larger installations (#265). If service discovery is putting noticeable load on your Netbox database, upgrading is worthwhile.

Installation

The plugin is available as a Python package in pypi and can be installed with pip

pip install netbox-plugin-prometheus-sd

Enable the plugin in /opt/netbox/netbox/netbox/configuration.py:

    PLUGINS = ['netbox_prometheus_sd']

The plugin has not further plugin configuration.

Usage

The plugin only provides a new API endpoint on the Netbox API. There is no further action required after installation.

API

The plugin reuses Netbox API view sets with new serializers for Prometheus. This means that all filters that can be used on the Netbox API can also be used to filter Prometheus targets. Paging is disabled because Prometheus does not support paged results.

The plugin also reuses the Netbox authentication and permission model. Depending on the Netbox configuration, a token with valid object permissions must be passed to Netbox.

GET        /api/plugins/prometheus-sd/devices/              Get a list of devices in a prometheus compatible format
GET        /api/plugins/prometheus-sd/virtual-machines/     Get a list of vms in a prometheus compatible format
GET        /api/plugins/prometheus-sd/services/             Get a list of services in a prometheus compatible format
GET        /api/plugins/prometheus-sd/ip-addresses/         Get a list of ip in a prometheus compatible format

Extended services filters

Apart from standard Netbox filters, services endpoint also supports tenant=<slug> or tenant_id=<id>, and site=<slug> or site_id=<id> parameters. The lookup is only executed against the tenant/site attribute of the object associated with the service.

Filtering and response size

Because paging is disabled, one request serializes every object the token is allowed to see. Filtering with the standard Netbox query parameters is the supported way to keep responses small, and it is usually what you want anyway — Prometheus should not be told about decommissioned hardware:

/api/plugins/prometheus-sd/devices/?status=active&tag=monitoring&site=dc1

Labels

Every target carries __meta_netbox_* labels describing the Netbox object. Prometheus discards labels starting with __ after service discovery, so they have to be copied into real labels with relabel_configs (see below) if you want them on your metrics.

A label is only present when the underlying field is populated — a device with no tenant has no __meta_netbox_tenant.

Label Devices VMs Services IPs
id, name, status, model ✓ ✓ id/name only ✓ (no name)
primary_ip, primary_ip4, primary_ip6 ✓ ✓ from parent
oob_ip ✓ from parent
ip ✓
role, role_slug ✓ ✓ role only
platform, platform_slug ✓ ✓
device_type, device_type_slug ✓
site, site_slug ✓ ✓ from parent
scope, scope_slug ✓ ¹
location, location_slug ✓
rack, rack_u_position ✓
cluster, cluster_group, cluster_type ✓ ² ✓
tenant, tenant_slug ✓ ✓ from parent ✓
tenant_group, tenant_group_slug ✓ ✓ from parent ✓
tags, tag_slugs ✓ ✓ ✓ ✓
services ✓ ✓
contact_<priority>_{name,email,comments,role} ✓ ✓ from parent
custom_field_<name> ✓ ✓ ✓ ✓
description ✓
parent, display, ports, ipaddresses ✓

¹ Netbox 4.2 replaced the cluster's site with a generic scope. On 4.2+ a VM emits scope/scope_slug for the cluster, and site/site_slug for its own site; below 4.2 the cluster's site is reported as site. ² Only when the device is assigned to a cluster.

Config context can additionally set __metrics_path__ and __scheme__, which Prometheus consumes directly (see Config context).

Relabeling

The __meta_netbox_* labels are dropped unless you map them. A typical device job scraping node_exporter on the primary IP:

scrape_configs:
  - job_name: netbox-devices
    http_sd_configs:
      - url: http://netbox:8080/api/plugins/prometheus-sd/devices/?status=active&tag=monitoring
        refresh_interval: 60s
        authorization:
          type: Token
          credentials: "<your-netbox-api-token>"

    relabel_configs:
      # Skip anything without a primary IPv4, otherwise the address below is empty.
      - source_labels: [__meta_netbox_primary_ip4]
        regex: ^$
        action: drop

      # Scrape the primary IP instead of the device name, which may not resolve.
      - source_labels: [__meta_netbox_primary_ip4]
        target_label: __address__
        replacement: "$1:9100"

      # Keep the Netbox name as the instance label rather than the IP.
      - source_labels: [__meta_netbox_name]
        target_label: instance

      # Promote the dimensions worth alerting and grouping on.
      - source_labels: [__meta_netbox_site_slug]
        target_label: site
      - source_labels: [__meta_netbox_role_slug]
        target_label: role
      - source_labels: [__meta_netbox_tenant_slug]
        target_label: tenant

Two things worth knowing:

  • tags and tag_slugs are comma-joined, so match them with .*,?value,?.* rather than =.
  • Devices and VMs use the same label names, so one set of relabel_configs can be reused across both jobs.

Config context

The plugin can also discover extra config to inject in the HTTP SD JSON from the config context of the devices/virtual machines. If you have a prometheus-plugin-prometheus-sd entry in your config context with the following schema it will be automatically picked up:

prometheus-plugin-prometheus-sd:
  - metrics_path: /not/metrics
    port: 4242
    scheme: https
  - port: 4243

This allow you to configure those values directly into netbox instead of doing that inside the Prometheus config and filtering each scenario by a specific tag for instance.

If there is only one entry you can also use this form:

prometheus-plugin-prometheus-sd:
  metrics_path: /not/metrics
  port: 4242
  scheme: https

Example

example/prometheus.yml is a complete Prometheus configuration covering all four endpoints, with relabel_configs mapping the __meta_netbox_* labels onto real ones.

It is not a snippet that happens to be in the repository: the test suite runs Prometheus against this exact file and asserts that the expected targets and labels are discovered, so it cannot quietly stop working.

To see it running, with a Netbox that has demo data already loaded:

poetry run invoke build-dev
  • Netbox: http://localhost:8000 (admin / admin)
  • Prometheus: http://localhost:9090 — discovered targets are under Status → Target health, and expanding one shows the raw __meta_netbox_* labels before relabeling.

The demo data is the unit-test fixtures, so it also exercises config context (the VMs get two targets each, on different ports), services, contacts and tags.

Development

We use Poetry for dependency management and invoke as task runner. To test the plugin in an isolated environment, we use testcontainers which creates "throwaway, lightweight" Netbox Docker containers.

Install the dependencies with poetry install, then run the tasks through poetry run (this works on every Poetry version, whereas poetry shell was moved into a separate plugin in Poetry 2.0):

# Unit tests plus the Prometheus end-to-end check
poetry run invoke test

# Test against a specific Netbox release (default: latest)
NETBOX_VER=v4.6.5 poetry run invoke test

# Either half on its own
poetry run invoke unittest
poetry run invoke test-prometheus

The Netbox image is built from the Dockerfile in the repository root.

Testing has two layers:

  • Unit tests — plain Django tests under netbox_prometheus_sd/tests/, executed inside the Netbox container. These cover the serializers and the label output.
  • Prometheus end-to-end — Netbox serving real HTTP with seeded data, and a real Prometheus configured from example/prometheus.yml. It asserts that the expected jobs discover targets and that relabeling produced the expected labels.

The second layer exists because "valid JSON with targets and labels" is not the same as "Prometheus accepts this as an http_sd source". A response that Prometheus rejects would pass every unit test in this repository. It also keeps the documented example honest, since it is the file under test.

Features should be covered by a test, but sometimes it is easier to develop against a running system:

# Netbox + Prometheus with demo data, left running until Ctrl+C
poetry run invoke build-dev

Netbox is on http://localhost:8000 (admin / admin) and Prometheus on http://localhost:9090, already scraping it.

API endpoints for testing can be found at http://localhost:8000/api/plugins/prometheus-sd/

Conventional Commits

This repository follows the Conventional Commits specification for versioning and changelog generation. Conventional Commits provide a standardized way of writing commit messages to convey semantic meaning about the changes made. Each commit message follows a defined format that includes a type, an optional scope, and a message. The types typically include features, fixes, documentation, and more. By adhering to this convention, we ensure clear and automated versioning, release notes, and changelog generation.

Metadata

Release files for netbox-plugin-prometheus-sd 2.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for netbox-plugin-prometheus-sd 2.2.0
File Size Uploaded
netbox_plugin_prometheus_sd-2.2.0.tar.gz 21.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for netbox-plugin-prometheus-sd 2.2.0
File Interpreter ABI Platform
netbox_plugin_prometheus_sd-2.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 44.0 kB

Release files / netbox_plugin_prometheus_sd-2.2.0.tar.gz

Download URL netbox_plugin_prometheus_sd-2.2.0.tar.gz
Size 21.7 kB
Tags Source
SHA-256 checksum
How to use checksums
605bda37405dc9c2897cbedc3383e7bf759a7bea488534ced1f5eca147416e7b
BLAKE2b-256 checksum
How to use checksums
47154cddc0b1aaad00e3d725ca8baf1c9e0684e79fd5d78c55f70f013e14bb66
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / netbox_plugin_prometheus_sd-2.2.0-py3-none-any.whl

Download URL netbox_plugin_prometheus_sd-2.2.0-py3-none-any.whl
Size 22.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
14e7b8f64a499b5cb3c5e86db459f85c4a1ce3f8b1e26589f15826194a39bb1c
BLAKE2b-256 checksum
How to use checksums
ce3ebbc7da54d010acdf828c7c440d4c696fe7dde897ca27f235d8f62c194565
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page