{"id":18035903,"url":"https://github.com/candlerb/netbox-prometheus","last_synced_at":"2025-06-29T11:32:35.073Z","repository":{"id":66668218,"uuid":"234575688","full_name":"candlerb/netbox-prometheus","owner":"candlerb","description":"Generate prometheus scrape targets and metadata from netbox","archived":false,"fork":false,"pushed_at":"2022-09-14T10:14:21.000Z","size":21,"stargazers_count":21,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-29T03:44:08.966Z","etag":null,"topics":["netbox-api","netbox-plugin"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/candlerb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-17T15:22:30.000Z","updated_at":"2025-03-25T10:46:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"fb493407-c292-45aa-8f05-3d725006892d","html_url":"https://github.com/candlerb/netbox-prometheus","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/candlerb/netbox-prometheus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/candlerb%2Fnetbox-prometheus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/candlerb%2Fnetbox-prometheus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/candlerb%2Fnetbox-prometheus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/candlerb%2Fnetbox-prometheus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/candlerb","download_url":"https://codeload.github.com/candlerb/netbox-prometheus/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/candlerb%2Fnetbox-prometheus/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262586036,"owners_count":23332770,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["netbox-api","netbox-plugin"],"created_at":"2024-10-30T12:10:43.201Z","updated_at":"2025-06-29T11:32:35.033Z","avatar_url":"https://github.com/candlerb.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# This project is now obsolete\n\n*Use [netbox-plugin-prometheus-sd](https://github.com/FlxPeters/netbox-plugin-prometheus-sd)\ninstead, together with Prometheus 2.28.0+ using HTTP SD and target\nrelabelling*\n\n# Netbox Prometheus configuration generator\n\nThis script generates targets files for prometheus from devices and VMs in\nthe Netbox database.  Example:\n\n```\n# Auto-generated from Netbox, do not edit as your changes will be overwritten!\n- labels:\n    module: if_mib_secret\n    netbox_type: device\n  targets:\n  - sw1 192.168.1.2\n  - sw2 192.168.1.3\n- labels:\n    module: mikrotik_secret\n    netbox_type: device\n  targets:\n  - gw 192.168.1.1\n```\n\nIt writes separate files for each type of target: `node_targets.yml`,\n`snmp_targets.yml`, `windows_targets.yml`.\n\nIt also generates synthetic metrics which can be used for\n[machine role queries](https://www.robustperception.io/how-to-have-labels-for-machine-roles)\nand to add extra labels to alerts:\n\n```\nnetbox_meta{instance=\"gw\",netbox_type=\"device\",rack=\"r1\",site=\"dc\",tags_prom_snmp=\"1\",role=\"router\"} 1\nnetbox_meta{instance=\"sw1\",netbox_type=\"device\",rack=\"r1\",site=\"dc1\",tags_prom_snmp=\"1\",role=\"core-switch\"} 1\nnetbox_meta{instance=\"sw2\",netbox_type=\"device\",rack=\"r2\",site=\"dc1\",tags_prom_snmp=\"1\",role=\"core-switch\"} 1\n```\n\n# Installation\n\nNormally you would install script this on your prometheus server, so that it\ncan write the targets files directly.\n\nCopy the python source file to your prometheus server, e.g. as\n`/usr/local/bin/netbox_prometheus.py`\n\n## Dependencies\n\n```\napt-get install python3-pip\npip3 install pynetbox\n```\n\n## Netbox Configuration\n\n### API token\n\nIn Netbox, create an API token with write disabled.\n\nInside the python source file, set API_URL and API_TOKEN to be able to\ncommunicate with Netbox REST API.\n\n### Tags\n\nIn your Netbox instance:\n\n* Add tag \"prometheus\" onto each of the site(s) where you have things to to poll (*)\n* Add tag \"prom_node\" to each Linux device/VM that you want to poll\n* Add tag \"prom_windows\" to each Windows device/VM that you want to poll\n* Add tag \"prom_snmp\" to each network device that you want to poll\n* Ensure that each device or VM that you want to poll has status \"Active\",\n  and either has a primary IP address assigned, or its name is resolvable\n\nNote: the script *requires* all those tags to exist, even if there are no\ndevices with them, because the Netbox API gives an error if you try to query\nnon-existent tags.\n\nTherefore if you don't need `prom_windows` or `prom_snmp`, you still need to\ncreate an unused tag in Netbox (prior to v2.9.0 you had to add it to a\ndevice then remove it again), or else comment out the relevant lines in the\nscript.\n\n(*) To scrape Virtual Machines, the *cluster* must be associated with a\nsite, and that site must have the label \"prometheus\".  Site Groups are\ncurrently not tested, but you can adjust the filter yourself if you wish.\n\n### SNMP configuration\n\nIf you have any SNMP devices to poll, then you need to create a new custom\nfield as follows:\n\n* Type: Selection (or Multiple Selection)\n* Name: `snmp_module`\n* Label: `SNMP Module`\n* Content Types: `DCIM \u003e device` and `Virtualization \u003e virtual machine`\n* Choices: list of SNMP modules as required, e.g. `if_mib,apcups,synology`\n  (these refer to modules in your snmp_exporter `snmp.yml`)\n\nThen select one or more of these choices on each device or VM that you wish\nto poll, as well as setting the `prom_snmp` tag.\n\n(The tag is required to minimise the data returned in the API query; Netbox\ndoes not yet have\n[custom field filters](https://github.com/netbox-community/netbox/issues/6615)\nsuch as `cf_snmp_module__empty=0`)\n\n## Script setup\n\n### Create the output directories\n\n```\nmkdir -p /etc/prometheus/targets.d\nmkdir -p /var/www/html/metrics\n```\n\nIf you want the output to go somewhere else, then modify the\nrelevant constants in the script.\n\n### Run the script\n\nRun the script, check for no errors, and that it creates output files in the\ngiven directories.\n\n### Add cronjob\n\nCreate `/etc/cron.d/netbox_prometheus` to keep the files up-to-date:\n\n```\n*/5 * * * * /usr/local/bin/netbox_prometheus.py\n```\n\nPrometheus `file_sd` automatically detects files which change, and doesn't\nneed to be reloaded.\n\n## Prometheus scrape configuration\n\n### Targets\n\nThis script can output targets of the following forms:\n\n```\n- foo               # name only\n- x.x.x.x           # IPv4 address only\n- foo x.x.x.x       # name and IPv4 address\n- [dead:beef::]     # IPv6 address only\n- foo [dead:beef::] # name and IPv6 address\n```\n\nThe IP addresses come from the \"primary\" IP address defined in Netbox, and\nthe name from the device/VM name.  This approach allows you to have\n[meaningful instance labels](https://www.robustperception.io/controlling-the-instance-label)\nlike `{instance=\"foo\"}` whilst using IP addresses for targets, avoiding\nthe need for DNS resolution.\n\nTo use these target files, you will need some relabelling configuration.\n\nNode Exporter:\n\n```\n  - job_name: node\n    scrape_interval: 1m\n    file_sd_configs:\n      - files:\n        - /etc/prometheus/targets.d/node_targets.yml\n    metrics_path: /metrics\n    relabel_configs:\n      # When __address__ consists of just a name or IP address,\n      # copy it to the \"instance\" label.  Doing this explicitly\n      # keeps the port number out of the instance label.\n      - source_labels: [__address__]\n        regex: '([^ ]+)'\n        target_label: instance\n\n      # When __address__ is of the form \"name address\", extract\n      # name to \"instance\" label and address to \"__address__\"\n      - source_labels: [__address__]\n        regex: '(.+) (.+)'\n        target_label: instance\n        replacement: '${1}'\n      - source_labels: [__address__]\n        regex: '(.+) (.+)'\n        target_label: __address__\n        replacement: '${2}'\n\n      # Append port number to __address__ so that scrape gets\n      # sent to the right port\n      - source_labels: [__address__]\n        target_label: __address__\n        replacement: '${1}:9100'\n```\n\nWindows exporter is similar (just change the job_name, the filename, and the\nreplacement port number to 9182).\n\nSNMP exporter is slightly trickier because the target parameter\ncannot contain square brackets around IPv6 addresses.\n\n```\n  - job_name: snmp\n    scrape_interval: 1m\n    file_sd_configs:\n      - files:\n        - /etc/prometheus/targets.d/snmp_targets.yml\n    metrics_path: /snmp\n    relabel_configs:\n      # When __address__ consists of just a name or IP address,\n      # copy it to both the \"instance\" label (visible to user)\n      # and \"__param_target\" (where snmp_exporter sends SNMP)\n      - source_labels: [__address__]\n        regex: '([^ ]+)'\n        target_label: instance\n      - source_labels: [__address__]\n        regex: '([^ ]+)'\n        target_label: __param_target\n\n      # When __address__ is of the form \"name address\", extract\n      # name to \"instance\" label and address to \"__param_target\"\n      - source_labels: [__address__]\n        regex: '(.+) (.+)'\n        target_label: instance\n        replacement: '${1}'\n      - source_labels: [__address__]\n        regex: '(.+) (.+)'\n        target_label: __param_target\n        replacement: '${2}'\n\n      # If __param_target is enclosed by square brackets, remove them\n      - source_labels: [__param_target]\n        regex: '\\[(.+)\\]'\n        target_label: __param_target\n        replacement: '${1}'\n\n      # Copy \"module\" label to \"__param_module\" so that snmp_exporter\n      # receives it as part of the scrape URL\n      - source_labels: [module]\n        target_label: __param_module\n\n      # Send the actual scrape to SNMP exporter\n      - target_label: __address__\n        replacement: 127.0.0.1:9116\n```\n\nReload prometheus config and check there are no errors:\n\n```\nkillall -HUP prometheus\njournalctl -eu prometheus\n```\n\nSee also:\n\n* https://www.robustperception.io/controlling-the-instance-label\n* https://www.robustperception.io/target-labels-are-for-life-not-just-for-christmas/\n* https://www.robustperception.io/reloading-prometheus-configuration\n\n### Metadata\n\nIn order to use the metadata metrics, you'll need to expose them using http\n(`apt-get install apache2`) and add a scrape job:\n\n```\n  # Pick up netbox_meta metrics exported from netbox database\n  - job_name: netbox\n    metrics_path: /metrics/netbox\n    scrape_interval: 5m\n    honor_labels: true\n    static_configs:\n      - targets:\n        - 127.0.0.1:80\n```\n\nYou can then use queries and alerting rules with extra labels from Netbox, e.g.\n\n```\n# Filter based on Netbox attributes\n(up == 1) * on (instance) group_left netbox_meta{role=\"core-switch\"}\n\n# Add extra labels from Netbox\n(up == 1) * on (instance) group_left(tenant,role,site,rack,cluster) netbox_meta\n```\n\nYou can modify the python code to add extra labels, e.g. \"platform\".\n\nSee also:\n\n* [How to have labels for machine roles](https://www.robustperception.io/how-to-have-labels-for-machine-roles)\n* [Exposing the software version to prometheus](https://www.robustperception.io/exposing-the-software-version-to-prometheus)\n* [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)\n\n# Complex deployments\n\n## Multiple prometheus instances\n\nYou might have multiple prometheus instances.  Say prometheus1 should poll\nsites A, B and C, while prometheus2 polls sites A (for redundancy), D and E.\n\nYou can control this with the SITE_TAG setting.  On the two prometheus\ninstances run the same script, but one configured with\n\n```\nSITE_TAG = \"prometheus1\"\n```\n\nand the other with\n\n```\nSITE_TAG = \"prometheus2\"\n```\n\nThen in Netbox, tag sites A, B and C with \"prometheus1\", and sites A, D and\nE with \"prometheus2\".  The correct targets will be generated for each\nprometheus instance.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcandlerb%2Fnetbox-prometheus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcandlerb%2Fnetbox-prometheus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcandlerb%2Fnetbox-prometheus/lists"}