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@latest

Full 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

  1. Define metrics types for totals, current values, and distributions.
  2. Register metrics and expose a scrape endpoint.
  3. Update metrics in business flow.
  4. Validate with manual requests and Prometheus scrape.
  5. Tune labels to avoid high-cardinality cardinality issues.

Code Anatomy

  • Metric definitions at startup.
  • Request/probe path updates counters, gauges, or histograms.
  • /metrics endpoint exposes state for observability stack.

Learning Goals

  • Design practical service metrics.
  • Connect application behavior to SLO monitoring.
  • Build observability by default.