I ordered a second UPS because thanks to PeaNUT, I saw that my current UPS is only providing 20 minutes of uptime. Unfortunately, as of this post, PeaNUT will only read one UPS’ metrics from Network UPS Tools per PeaNUT instance, so I’m going to start scraping the metrics into Prometheus and displaying them with Grafana. Here’s how I did it.
Prerequisites
- A working Network UPS Tools (aka NUT) instance. I documented setting one up in Set up nut-upsd and peanut in your homelab
- A Linux server with docker-compose and docker, podman or containerd set up.
- Working Prometheus and Grafana servers. I documented setting them up with
docker-compose
here.
Setup
Configure the NUT exporter for Prometheus
I decided to use the hon95/prometheus-nut-exporter container to proxy metrics from NUT to Prometheus.
Here’s a docker-compose.yaml
file for starting nut-upsd and the prometheus nut exporter. For simplicity, I’m not including how to make it accessible via https. If you do want to secure the exporter with SSL, I documented how to use nginx-proxy-manager as an SSL reverse proxy here.
version: '3.9'
services:
# Details on nuts-upsd configuration are at https://unixorn.github.io/post/homelab/homelab-nut-upsd
nut-upsd:
image: instantlinux/nut-upsd
container_name: nut
environment:
- API_PASSWORD=${API_PASSWORD:-'aPasswordForAPIaccess'}
- TZ=${TZ:-America/Denver}
# Driver found with this tool https://networkupstools.org/stable-hcl.html
- DRIVER=usbhid-ups
# If you want to have the UPS show up in grafana named something other than 'ups' set name
# - NAME=cp800avr
devices:
# Device numbers are subject to change, so map in the whole bus so nuts-upsd can find your UPS
- /dev/bus/usb:/dev/bus/usb
ports:
- "3493:3493"
restart: unless-stopped
prometheus-nut-exporter:
image: hon95/prometheus-nut-exporter:stable
container_name: prometheus-nut-exporter
environment:
- HTTP_PATH=/nut
- TZ=${TZ:-America/Denver}
# Defaults
#- RUST_LOG=info
#- HTTP_PORT=9995
#- HTTP_PATH=/nut
#- LOG_REQUESTS_CONSOLE=false
#- PRINT_METRICS_AND_EXIT=false
ports:
- "9995:9995"
# Don't start until nut-upsd is running so we don't serve garbage data
# to prometheus when it scrapes us
depends_on:
- nut-upsd
restart: unless-stopped
Run docker-compose up -d
and you should be able to go to http://yourserver.example.com:9995/nut?target=nut-upsd:3493 and see output similar to this:
# TYPE nut_exporter_info info
# UNIT nut_exporter_info
# HELP nut_exporter_info Metadata about the exporter.
nut_exporter_info{version="1.2.1"} 1
# TYPE nut_server_info info
# UNIT nut_server_info
# HELP nut_server_info Metadata about the NUT server.
nut_server_info{version="2.8.1"} 1
# TYPE nut_ups_info info
# UNIT nut_ups_info
# HELP nut_ups_info Metadata about the UPS.
nut_ups_info{ups="ups",description="UPS",device_type="ups",manufacturer="CPS",model="CP800AVRa",battery_type="PbAcid",driver="usbhid-ups",driver_version="2.8.1",driver_version_internal="0.52",driver_version_data="CyberPower HID 0.8",usb_vendor_id="0764",usb_product_id="0501",type="ups",nut_version="2.8.1"} 1
# TYPE nut_info info
# A lot more information snipped for brevity
The example URL assumes you’re running nut-upsd
out of the same docker-compose.yaml
file you’re using to run the exporter. If not, replace nut-upsd
in the link with an ip or dns name so it looks like http://yourserver.example.com:9995/nut?target=nut-upsd.example.com:3493
Add NUT scrape configuration to Prometheus
Here’s the nut
scrape job I’m using, with my hostnames stripped. More detailed configuration instructions available at github.com/hon95/prometheus-nut-exporter site.
global:
scrape_interval: 15s
scrape_timeout: 10s
scrape_configs:
- job_name: "nut"
scrape_interval: 30s
static_configs:
# Insert NUT server address here
- targets: ["nut-upsd:3493"]
metrics_path: /nut
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
# Insert NUT exporter address here
replacement: your.exporter.server.example.com:9995
Add a nut dashboard to Grafana
Finally, add a dashboard to your grafana instance to display your nut metrics. I’m using the one here - the ID is 14371 if you want to directly import it to grafana.
Here’s what the resulting dashboard looks like in Grafana for one of my UPSes.