Skip to content

variablenix/cups-prometheus-exporter

Repository files navigation

cups-prometheus-exporter

A lightweight Prometheus exporter for CUPS print server metrics. Built out of necessity when I realized there was no simple way to monitor my homelab print server in Grafana — so I wrote one.

Exposes printer status, job queue depth, and scheduler health via a /metrics HTTP endpoint on port 9628. Runs as a Docker container alongside your CUPS server using the CUPS Unix socket directly, so no network config or credentials needed.

CUPS Print Server Status


Metrics

Metric Type Description
cups_up gauge CUPS scheduler is reachable (0/1)
cups_printer_status gauge Printer state: 0=idle, 1=printing, 2=stopped/error
cups_printer_accepting gauge Printer is accepting jobs (0/1)
cups_printer_enabled gauge Printer is enabled (0/1)
cups_jobs_active gauge Active/pending jobs per printer
cups_jobs_completed counter Completed jobs per printer since CUPS start

All per-printer metrics include a printer label with the printer name, e.g. cups_printer_status{printer="Brother-MFC-L3770CDW"}.


Requirements

  • Docker + Docker Compose
  • CUPS running on the same host with the Unix socket at /var/run/cups/cups.sock
  • Prometheus (to scrape the metrics)

Files

cups-prometheus-exporter/
├── cups_exporter.py       # The exporter itself
├── Dockerfile             # Builds the container image
├── docker-compose.yml     # Deploy with Docker Compose
└── README.md

Quickstart

1. Clone the repo

git clone https://github.com/variablenix/cups-prometheus-exporter.git
cd cups-prometheus-exporter

2. Pull the image from GHCR

The image is published to GitHub Container Registry and is the recommended way to deploy:

docker pull ghcr.io/variablenix/cups-prometheus-exporter:latest

3. Start the exporter

docker compose up -d cups-exporter

4. Verify it's working

curl http://localhost:9628/metrics

You should see Prometheus-formatted output like:

# HELP cups_up Whether the CUPS scheduler is running
# TYPE cups_up gauge
cups_up 1
# HELP cups_printer_status Printer state: 0=idle, 1=printing, 2=stopped
# TYPE cups_printer_status gauge
cups_printer_status{printer="Brother-MFC-L3770CDW"} 0

Docker Compose

Only the cups-exporter service is required. The full docker-compose.yml in this repo also includes node-exporter and cadvisor for host and container metrics — include or drop those based on your setup.

The default compose config pulls from GHCR:

cups-exporter:
  image: ghcr.io/variablenix/cups-prometheus-exporter:latest
  container_name: cups-exporter
  restart: unless-stopped
  environment:
    - CUPS_SERVER=/var/run/cups/cups.sock
  volumes:
    - /var/run/cups/cups.sock:/var/run/cups/cups.sock:ro
  network_mode: host
  healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:9628/metrics"]
    interval: 30s
    timeout: 5s
    retries: 3
    start_period: 10s

Note: network_mode: host is required so the container can reach the CUPS socket and expose metrics on the host network. The ports: directive has no effect in host network mode and can be omitted — Docker will warn you about this, which is expected.


Building Locally

If you want to build the image yourself instead of pulling from GHCR:

docker compose build cups-exporter
docker compose up -d cups-exporter

When building locally, update the image: line in docker-compose.yml to use a local tag instead of the GHCR reference:

cups-exporter:
  build:
    context: .
    dockerfile: Dockerfile
  image: cups-exporter:local
  ...

Dockerfile

FROM python:3.12-slim

RUN apt-get update -qq && \
    apt-get install -y -qq --no-install-recommends \
    cups-client \
    curl && \
    rm -rf /var/lib/apt/lists/*

COPY cups_exporter.py /app/cups_exporter.py

EXPOSE 9628
CMD ["python3", "/app/cups_exporter.py", "--port", "9628"]

curl is included for the Docker healthcheck. cups-client provides lpstat which is how the exporter talks to CUPS.


Publishing to GHCR

The image is published to ghcr.io/variablenix/cups-prometheus-exporter. To build and push a new version manually:

# Authenticate with GHCR using a personal access token
echo $GITHUB_TOKEN | docker login ghcr.io -u variablenix --password-stdin

# Build and tag
docker build -t ghcr.io/variablenix/cups-prometheus-exporter:latest .

# Push
docker push ghcr.io/variablenix/cups-prometheus-exporter:latest

To tag a versioned release alongside latest:

docker build \
  -t ghcr.io/variablenix/cups-prometheus-exporter:latest \
  -t ghcr.io/variablenix/cups-prometheus-exporter:1.0.0 \
  .

docker push ghcr.io/variablenix/cups-prometheus-exporter:latest
docker push ghcr.io/variablenix/cups-prometheus-exporter:1.0.0

The GITHUB_TOKEN needs write:packages scope. For CI/CD, a GitHub Actions workflow with packages: write permission can automate this on push to main.


Prometheus Configuration

Add this job to your prometheus.yml scrape config:

scrape_configs:
  - job_name: 'cups-exporter'
    scrape_interval: 30s
    metrics_path: /metrics
    static_configs:
      - targets: ['192.168.70.10:9628']
        labels:
          role: 'print-server'
          use: 'cups'
          hostname: 'cups-print'

Replace 192.168.70.10 with the IP of your CUPS host. If Prometheus is on the same machine, use localhost:9628.


Completed Job History

By default CUPS may not keep completed job history. To enable it add this to /etc/cups/cupsd.conf:

MaxJobs 500
PreserveJobHistory Yes
PreserveJobFiles No

Then restart CUPS:

sudo systemctl restart cups

Without this, cups_jobs_completed will always return 0.


Changing the Port

Default port is 9628. Override in docker-compose.yml if needed:

command: ["python3", "/app/cups_exporter.py", "--port", "9999"]

Updating

To pull the latest image from GHCR and restart:

docker compose pull cups-exporter
docker compose up -d cups-exporter

If you built locally and edited cups_exporter.py or the Dockerfile, rebuild instead:

docker rm -f cups-exporter
docker compose build cups-exporter
docker compose up -d cups-exporter

About

Prometheus exporter for CUPS print server: exposes printer status, job counts, and scheduler health as metrics. Docker-ready with Grafana dashboard support.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors