Understanding Prometheus Exporters: Operation Modes, Data Format, and a Go Implementation Example
This article explains the purpose and operation modes of Prometheus exporters, details the text-based metric exposition format including HELP, TYPE, and sample lines for counters, gauges, summaries, and histograms, and provides a complete Go example showing how to build, run, and expose a custom exporter with Prometheus client libraries.
Prometheus monitors a wide variety of targets, but without a unified standard; exporters solve this by exposing metrics in a format that Prometheus can scrape. Exporters can be integrated directly into applications using client libraries or run as independent processes when the target cannot provide metrics itself.
Exporters expose metrics over HTTP as plain‑text lines. Each metric includes optional # HELP and # TYPE comments, followed by one or more sample lines. The format supports Counter, Gauge, Summary, Histogram, and Untyped types. Summaries require additional _sum and _count lines, while Histograms need bucket lines with an le="+Inf" bucket.
The article also discusses drawbacks of the text format, such as verbosity, lack of validation for HELP/TYPE fields, and higher parsing cost compared with protobuf.
Two widely used exporters are described:
MySQL Server Exporter : monitors MySQL 5.6+ status, variables, schema statistics, InnoDB metrics, replication, etc.
Node Exporter : monitors *NIX system and hardware metrics like CPU, load, memory, network, and filesystem statistics.
To illustrate exporter development, a complete Go program is provided. It registers a GaugeVec, Counter, Summary, and Histogram, simulates data collection, and serves the metrics at /metrics using promhttp.Handler() . The source code is:
package main
import (
"log"
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
// Gauge with a "device" label
speed = prometheus.NewGaugeVec(prometheus.GaugeOpts{Name: "disk_available_bytes", Help: "Disk space available in bytes"}, []string{"device"})
tasksTotal = prometheus.NewCounter(prometheus.CounterOpts{Name: "test_tasks_total", Help: "Total number of test tasks"})
taskDuration = prometheus.NewSummary(prometheus.SummaryOpts{Name: "task_duration_seconds", Help: "Duration of task in seconds", Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}})
cpuTemperature = prometheus.NewHistogram(prometheus.HistogramOpts{Name: "cpu_temperature", Help: "The temperature of cpu", Buckets: []float64{20, 50, 70, 80}})
)
func init() {
prometheus.MustRegister(speed, tasksTotal, taskDuration, cpuTemperature)
}
func main() {
fakeData()
http.Handle("/metrics", promhttp.Handler())
log.Fatal(http.ListenAndServe(":10000", nil))
}
func fakeData() {
tasksTotal.Inc()
speed.With(prometheus.Labels{"device": "/dev/sda"}).Set(82115880)
taskDuration.Observe(10)
taskDuration.Observe(20)
taskDuration.Observe(30)
taskDuration.Observe(45)
taskDuration.Observe(56)
taskDuration.Observe(80)
cpuTemperature.Observe(30)
cpuTemperature.Observe(43)
cpuTemperature.Observe(56)
cpuTemperature.Observe(58)
cpuTemperature.Observe(65)
cpuTemperature.Observe(70)
}After building and running the exporter, add its address to the Prometheus static_configs so the server can scrape the metrics. The article then shows example outputs for each metric type (Gauge, Counter, Summary, Histogram) as they appear on the /metrics endpoint.
Finally, the article compares two implementation strategies: a long‑running exporter that keeps metrics in memory versus a per‑request exporter that creates metrics on demand, discussing trade‑offs such as data freshness, resource consumption, and handling of stale targets.
Aikesheng Open Source Community
The Aikesheng Open Source Community provides stable, enterprise‑grade MySQL open‑source tools and services, releases a premium open‑source component each year (1024), and continuously operates and maintains them.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.