032 Project 32: Prometheus Probe Service
032 Build a Prometheus Probe Service
Probe a target URL and export health/latency metrics.
Full main.go
package main
import (
"log"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func main() {
up := prometheus.NewGaugeVec(prometheus.GaugeOpts{Name: "probe_up", Help: "target up"}, []string{"target"})
dur := prometheus.NewGaugeVec(prometheus.GaugeOpts{Name: "probe_duration_seconds", Help: "probe duration"}, []string{"target"})
prometheus.MustRegister(up, dur)
client := &http.Client{Timeout: 2 * time.Second}
http.HandleFunc("/probe", func(w http.ResponseWriter, r *http.Request) {
target := r.URL.Query().Get("target")
if target == "" {
http.Error(w, "missing target", http.StatusBadRequest)
return
}
start := time.Now()
resp, err := client.Get(target)
d := time.Since(start).Seconds()
dur.WithLabelValues(target).Set(d)
if err != nil || resp.StatusCode >= 400 {
up.WithLabelValues(target).Set(0)
w.WriteHeader(http.StatusServiceUnavailable)
w.Write([]byte("down\n"))
return
}
up.WithLabelValues(target).Set(1)
w.Write([]byte("up\n"))
})
http.Handle("/metrics", promhttp.Handler())
log.Println("probe service on :9115")
log.Fatal(http.ListenAndServe(":9115", 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.