031 Project 31: Prometheus Exporter
031 Build a Prometheus Exporter
Expose custom app metrics at /metrics.
Setup
go mod init example.com/exporter
go get github.com/prometheus/client_golang/prometheus@latest
go get github.com/prometheus/client_golang/prometheus/promhttp@latestFull main.go
package main
import (
"log"
"math/rand"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func main() {
reqTotal := prometheus.NewCounter(prometheus.CounterOpts{Name: "demo_requests_total", Help: "total requests"})
latency := prometheus.NewHistogram(prometheus.HistogramOpts{Name: "demo_latency_seconds", Help: "request latency", Buckets: prometheus.DefBuckets})
inflight := prometheus.NewGauge(prometheus.GaugeOpts{Name: "demo_inflight", Help: "inflight requests"})
prometheus.MustRegister(reqTotal, latency, inflight)
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/work", func(w http.ResponseWriter, r *http.Request) {
inflight.Inc()
defer inflight.Dec()
start := time.Now()
time.Sleep(time.Duration(50+rand.Intn(200)) * time.Millisecond)
reqTotal.Inc()
latency.Observe(time.Since(start).Seconds())
w.Write([]byte("ok\n"))
})
log.Println("metrics on :9100/metrics")
log.Fatal(http.ListenAndServe(":9100", nil))
}Step-by-Step Explanation
- Define metrics types for totals, current values, and distributions.
- Register metrics and expose a scrape endpoint.
- Update metrics in business flow.
- Validate with manual requests and Prometheus scrape.
- Tune labels to avoid high-cardinality cardinality issues.
Code Anatomy
- Metric definitions at startup.
- Request/probe path updates counters, gauges, or histograms.
/metricsendpoint exposes state for observability stack.
Learning Goals
- Design practical service metrics.
- Connect application behavior to SLO monitoring.
- Build observability by default.