Exporters
Exporters bridge the gap between systems that don’t natively expose Prometheus metrics and Prometheus itself. An exporter runs alongside (or inside) a target, collects metrics, and exposes them on a /metrics endpoint.
Node Exporter (Host Metrics)
Section titled “Node Exporter (Host Metrics)”The most commonly used exporter — provides CPU, memory, disk, network, and filesystem metrics for Linux hosts.
Install and Run
Section titled “Install and Run”# Downloadwget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gztar xzf node_exporter-*.tar.gz./node_exporterOr as a systemd service:
[Unit]Description=Node ExporterAfter=network.target
[Service]ExecStart=/usr/local/bin/node_exporterRestart=always
[Install]WantedBy=multi-user.targetKey Metrics
Section titled “Key Metrics”| Metric | Type | What It Measures |
|---|---|---|
node_cpu_seconds_total | Counter | CPU time per mode (user, system, idle, iowait) |
node_memory_MemAvailable_bytes | Gauge | Available memory |
node_memory_MemTotal_bytes | Gauge | Total memory |
node_filesystem_avail_bytes | Gauge | Available disk space |
node_filesystem_size_bytes | Gauge | Total disk space |
node_network_receive_bytes_total | Counter | Network bytes received |
node_network_transmit_bytes_total | Counter | Network bytes sent |
node_load1 / node_load5 / node_load15 | Gauge | System load averages |
node_disk_io_time_seconds_total | Counter | Disk I/O time |
See Saturation and monitoring frameworks for how these series fit USE-style node saturation and how they compose with RED and Golden Signals at the service edge.
Useful Queries
Section titled “Useful Queries”These are PromQL queries you’d run in the Prometheus UI (http://prometheus:9090/graph) or use in Grafana dashboard panels to visualize Node exporter data:
# CPU usage percentage100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Memory usage percentage(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# Disk usage percentage(1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100
# Network throughput (bytes/sec)rate(node_network_receive_bytes_total{device="eth0"}[5m])Scrape Config
Section titled “Scrape Config”To tell Prometheus to scrape your Node exporters, add this to the Prometheus server’s prometheus.yml under scrape_configs. Each target is a host:port where Node exporter is running:
# prometheus.yml — on the Prometheus serverscrape_configs: - job_name: "node" static_configs: - targets: ["node1:9100", "node2:9100", "node3:9100"]Prometheus will scrape http://node1:9100/metrics, http://node2:9100/metrics, and http://node3:9100/metrics at the global scrape_interval.
Blackbox Exporter (Probing)
Section titled “Blackbox Exporter (Probing)”Probes endpoints from the outside — HTTP, TCP, DNS, ICMP. Tests what users experience:
Use Cases
Section titled “Use Cases”- Is my website returning 200?
- Is my API responding within 500ms?
- Is my DNS resolving correctly?
- Is port 5432 (PostgreSQL) open?
Configuration
Section titled “Configuration”modules: http_2xx: prober: http timeout: 5s http: valid_status_codes: [200, 201, 202] method: GET follow_redirects: true
http_post: prober: http http: method: POST headers: Content-Type: application/json body: '{"check": true}'
tcp_connect: prober: tcp timeout: 5s
dns_lookup: prober: dns dns: query_name: example.com query_type: A
icmp_ping: prober: icmp timeout: 5sScrape Config (Multi-Target)
Section titled “Scrape Config (Multi-Target)”scrape_configs: - job_name: "blackbox-http" metrics_path: /probe params: module: [http_2xx] static_configs: - targets: - https://example.com - https://api.example.com/health - https://staging.example.com relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: blackbox-exporter:9115Key Metrics
Section titled “Key Metrics”# Is the endpoint up? (1 = success, 0 = failure)probe_success{instance="https://example.com"}
# Response timeprobe_duration_seconds{instance="https://example.com"}
# SSL certificate expiry (days until expiration)(probe_ssl_earliest_cert_expiry - time()) / 86400Application Instrumentation (Client Libraries)
Section titled “Application Instrumentation (Client Libraries)”Instead of using an exporter, instrument your own application to expose metrics directly.
Python (prometheus_client)
Section titled “Python (prometheus_client)”from prometheus_client import Counter, Histogram, start_http_server
REQUEST_COUNT = Counter( 'http_requests_total', 'Total HTTP requests', ['method', 'status'])REQUEST_LATENCY = Histogram( 'http_request_duration_seconds', 'Request latency in seconds', ['method'])
@app.route('/api/data')def get_data(): with REQUEST_LATENCY.labels(method='GET').time(): # ... handle request ... REQUEST_COUNT.labels(method='GET', status='200').inc() return data
# Expose /metrics on port 8000start_http_server(8000)Go (prometheus/client_golang)
Section titled “Go (prometheus/client_golang)”import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp")
var requestCount = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Total HTTP requests", }, []string{"method", "status"},)
func init() { prometheus.MustRegister(requestCount)}
func main() { http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil)}Node.js (prom-client)
Section titled “Node.js (prom-client)”const client = require('prom-client');
const requestCount = new client.Counter({ name: 'http_requests_total', help: 'Total HTTP requests', labelNames: ['method', 'status'],});
app.get('/metrics', async (req, res) => { res.set('Content-Type', client.register.contentType); res.end(await client.register.metrics());});Naming Conventions
Section titled “Naming Conventions”| Pattern | Example | Rule |
|---|---|---|
<namespace>_<name>_<unit> | http_request_duration_seconds | Always include the unit |
| Counter suffix | _total | Counters should end in _total |
| Histogram suffix | _bucket, _sum, _count | Auto-generated |
| Unit suffixes | _bytes, _seconds, _total | Use base units (bytes not KB, seconds not ms) |
Other Common Exporters
Section titled “Other Common Exporters”| Exporter | Metrics From |
|---|---|
| mysqld_exporter | MySQL queries, connections, buffer pool |
| postgres_exporter | PostgreSQL queries, connections, replication |
| redis_exporter | Redis memory, keys, commands/sec |
| mongodb_exporter | MongoDB connections, operations, replication |
| nginx_exporter | Nginx connections, requests |
| cadvisor | Container CPU, memory, network (Docker/K8s) |
| kube-state-metrics | Kubernetes object states (pods, deployments, nodes) |
Custom Exporters
Section titled “Custom Exporters”When no existing exporter fits, write your own. The pattern:
- Collect data from your system (API, file, database).
- Map it to Prometheus metric types (Counter, Gauge, Histogram).
- Expose on
/metrics.
from prometheus_client import Gauge, start_http_serverimport requests, time
queue_depth = Gauge('queue_depth', 'Number of items in the job queue', ['queue_name'])
def collect(): while True: resp = requests.get('http://internal-api/queues') for queue in resp.json(): queue_depth.labels(queue_name=queue['name']).set(queue['depth']) time.sleep(15)
start_http_server(9200)collect()Key Takeaways
Section titled “Key Takeaways”- Node exporter for host metrics (CPU, memory, disk, network) — install on every machine.
- Blackbox exporter for probing endpoints from the outside (HTTP, TCP, DNS, ICMP).
- Instrument your apps with client libraries to expose request counts, latency histograms, and business metrics.
- Follow naming conventions:
_totalfor counters,_seconds/_bytesfor units. - Use existing exporters for databases, caches, and web servers before writing custom ones.