https://github.com/candlerb/netbox-prometheus
Generate prometheus scrape targets and metadata from netbox
https://github.com/candlerb/netbox-prometheus
netbox-api netbox-plugin
Last synced: 25 days ago
JSON representation
Generate prometheus scrape targets and metadata from netbox
- Host: GitHub
- URL: https://github.com/candlerb/netbox-prometheus
- Owner: candlerb
- Created: 2020-01-17T15:22:30.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2022-09-14T10:14:21.000Z (over 2 years ago)
- Last Synced: 2025-03-23T10:44:07.343Z (29 days ago)
- Topics: netbox-api, netbox-plugin
- Language: Python
- Homepage:
- Size: 20.5 KB
- Stars: 20
- Watchers: 3
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# This project is now obsolete
*Use [netbox-plugin-prometheus-sd](https://github.com/FlxPeters/netbox-plugin-prometheus-sd)
instead, together with Prometheus 2.28.0+ using HTTP SD and target
relabelling*# Netbox Prometheus configuration generator
This script generates targets files for prometheus from devices and VMs in
the Netbox database. Example:```
# Auto-generated from Netbox, do not edit as your changes will be overwritten!
- labels:
module: if_mib_secret
netbox_type: device
targets:
- sw1 192.168.1.2
- sw2 192.168.1.3
- labels:
module: mikrotik_secret
netbox_type: device
targets:
- gw 192.168.1.1
```It writes separate files for each type of target: `node_targets.yml`,
`snmp_targets.yml`, `windows_targets.yml`.It also generates synthetic metrics which can be used for
[machine role queries](https://www.robustperception.io/how-to-have-labels-for-machine-roles)
and to add extra labels to alerts:```
netbox_meta{instance="gw",netbox_type="device",rack="r1",site="dc",tags_prom_snmp="1",role="router"} 1
netbox_meta{instance="sw1",netbox_type="device",rack="r1",site="dc1",tags_prom_snmp="1",role="core-switch"} 1
netbox_meta{instance="sw2",netbox_type="device",rack="r2",site="dc1",tags_prom_snmp="1",role="core-switch"} 1
```# Installation
Normally you would install script this on your prometheus server, so that it
can write the targets files directly.Copy the python source file to your prometheus server, e.g. as
`/usr/local/bin/netbox_prometheus.py`## Dependencies
```
apt-get install python3-pip
pip3 install pynetbox
```## Netbox Configuration
### API token
In Netbox, create an API token with write disabled.
Inside the python source file, set API_URL and API_TOKEN to be able to
communicate with Netbox REST API.### Tags
In your Netbox instance:
* Add tag "prometheus" onto each of the site(s) where you have things to to poll (*)
* Add tag "prom_node" to each Linux device/VM that you want to poll
* Add tag "prom_windows" to each Windows device/VM that you want to poll
* Add tag "prom_snmp" to each network device that you want to poll
* Ensure that each device or VM that you want to poll has status "Active",
and either has a primary IP address assigned, or its name is resolvableNote: the script *requires* all those tags to exist, even if there are no
devices with them, because the Netbox API gives an error if you try to query
non-existent tags.Therefore if you don't need `prom_windows` or `prom_snmp`, you still need to
create an unused tag in Netbox (prior to v2.9.0 you had to add it to a
device then remove it again), or else comment out the relevant lines in the
script.(*) To scrape Virtual Machines, the *cluster* must be associated with a
site, and that site must have the label "prometheus". Site Groups are
currently not tested, but you can adjust the filter yourself if you wish.### SNMP configuration
If you have any SNMP devices to poll, then you need to create a new custom
field as follows:* Type: Selection (or Multiple Selection)
* Name: `snmp_module`
* Label: `SNMP Module`
* Content Types: `DCIM > device` and `Virtualization > virtual machine`
* Choices: list of SNMP modules as required, e.g. `if_mib,apcups,synology`
(these refer to modules in your snmp_exporter `snmp.yml`)Then select one or more of these choices on each device or VM that you wish
to poll, as well as setting the `prom_snmp` tag.(The tag is required to minimise the data returned in the API query; Netbox
does not yet have
[custom field filters](https://github.com/netbox-community/netbox/issues/6615)
such as `cf_snmp_module__empty=0`)## Script setup
### Create the output directories
```
mkdir -p /etc/prometheus/targets.d
mkdir -p /var/www/html/metrics
```If you want the output to go somewhere else, then modify the
relevant constants in the script.### Run the script
Run the script, check for no errors, and that it creates output files in the
given directories.### Add cronjob
Create `/etc/cron.d/netbox_prometheus` to keep the files up-to-date:
```
*/5 * * * * /usr/local/bin/netbox_prometheus.py
```Prometheus `file_sd` automatically detects files which change, and doesn't
need to be reloaded.## Prometheus scrape configuration
### Targets
This script can output targets of the following forms:
```
- foo # name only
- x.x.x.x # IPv4 address only
- foo x.x.x.x # name and IPv4 address
- [dead:beef::] # IPv6 address only
- foo [dead:beef::] # name and IPv6 address
```The IP addresses come from the "primary" IP address defined in Netbox, and
the name from the device/VM name. This approach allows you to have
[meaningful instance labels](https://www.robustperception.io/controlling-the-instance-label)
like `{instance="foo"}` whilst using IP addresses for targets, avoiding
the need for DNS resolution.To use these target files, you will need some relabelling configuration.
Node Exporter:
```
- job_name: node
scrape_interval: 1m
file_sd_configs:
- files:
- /etc/prometheus/targets.d/node_targets.yml
metrics_path: /metrics
relabel_configs:
# When __address__ consists of just a name or IP address,
# copy it to the "instance" label. Doing this explicitly
# keeps the port number out of the instance label.
- source_labels: [__address__]
regex: '([^ ]+)'
target_label: instance# When __address__ is of the form "name address", extract
# name to "instance" label and address to "__address__"
- source_labels: [__address__]
regex: '(.+) (.+)'
target_label: instance
replacement: '${1}'
- source_labels: [__address__]
regex: '(.+) (.+)'
target_label: __address__
replacement: '${2}'# Append port number to __address__ so that scrape gets
# sent to the right port
- source_labels: [__address__]
target_label: __address__
replacement: '${1}:9100'
```Windows exporter is similar (just change the job_name, the filename, and the
replacement port number to 9182).SNMP exporter is slightly trickier because the target parameter
cannot contain square brackets around IPv6 addresses.```
- job_name: snmp
scrape_interval: 1m
file_sd_configs:
- files:
- /etc/prometheus/targets.d/snmp_targets.yml
metrics_path: /snmp
relabel_configs:
# When __address__ consists of just a name or IP address,
# copy it to both the "instance" label (visible to user)
# and "__param_target" (where snmp_exporter sends SNMP)
- source_labels: [__address__]
regex: '([^ ]+)'
target_label: instance
- source_labels: [__address__]
regex: '([^ ]+)'
target_label: __param_target# When __address__ is of the form "name address", extract
# name to "instance" label and address to "__param_target"
- source_labels: [__address__]
regex: '(.+) (.+)'
target_label: instance
replacement: '${1}'
- source_labels: [__address__]
regex: '(.+) (.+)'
target_label: __param_target
replacement: '${2}'# If __param_target is enclosed by square brackets, remove them
- source_labels: [__param_target]
regex: '\[(.+)\]'
target_label: __param_target
replacement: '${1}'# Copy "module" label to "__param_module" so that snmp_exporter
# receives it as part of the scrape URL
- source_labels: [module]
target_label: __param_module# Send the actual scrape to SNMP exporter
- target_label: __address__
replacement: 127.0.0.1:9116
```Reload prometheus config and check there are no errors:
```
killall -HUP prometheus
journalctl -eu prometheus
```See also:
* https://www.robustperception.io/controlling-the-instance-label
* https://www.robustperception.io/target-labels-are-for-life-not-just-for-christmas/
* https://www.robustperception.io/reloading-prometheus-configuration### Metadata
In order to use the metadata metrics, you'll need to expose them using http
(`apt-get install apache2`) and add a scrape job:```
# Pick up netbox_meta metrics exported from netbox database
- job_name: netbox
metrics_path: /metrics/netbox
scrape_interval: 5m
honor_labels: true
static_configs:
- targets:
- 127.0.0.1:80
```You can then use queries and alerting rules with extra labels from Netbox, e.g.
```
# Filter based on Netbox attributes
(up == 1) * on (instance) group_left netbox_meta{role="core-switch"}# Add extra labels from Netbox
(up == 1) * on (instance) group_left(tenant,role,site,rack,cluster) netbox_meta
```You can modify the python code to add extra labels, e.g. "platform".
See also:
* [How to have labels for machine roles](https://www.robustperception.io/how-to-have-labels-for-machine-roles)
* [Exposing the software version to prometheus](https://www.robustperception.io/exposing-the-software-version-to-prometheus)
* [Many-to-one and one-to-one vector matches](https://prometheus.io/docs/prometheus/latest/querying/operators/#many-to-one-and-one-to-many-vector-matches)# Complex deployments
## Multiple prometheus instances
You might have multiple prometheus instances. Say prometheus1 should poll
sites A, B and C, while prometheus2 polls sites A (for redundancy), D and E.You can control this with the SITE_TAG setting. On the two prometheus
instances run the same script, but one configured with```
SITE_TAG = "prometheus1"
```and the other with
```
SITE_TAG = "prometheus2"
```Then in Netbox, tag sites A, B and C with "prometheus1", and sites A, D and
E with "prometheus2". The correct targets will be generated for each
prometheus instance.