Simplifying Prometheus Metrics in Go with prometric-go



This content originally appeared on DEV Community and was authored by Md Asraful Haque (Sohel)

Effortless observability for your Go applications — without the boilerplate.

🧠 The Problem

As Go developers, we all want observability — to know how our APIs perform, how many requests we handle, and how our systems behave in production.

Prometheus is fantastic for that — but setting up metrics in Go can quickly turn verbose:

counter := prometheus.NewCounterVec(
    prometheus.CounterOpts{Name: "http_requests_total", Help: "Total HTTP requests"},
    []string{"path", "method", "status"},
)
prometheus.MustRegister(counter)

And soon your code fills with boilerplate.

That’s why I built prometric-go — a lightweight, idiomatic helper library that makes exposing Prometheus metrics in Go as simple as possible.

💡 What is prometric-go?

prometric-go is a minimal Go library that wraps Prometheus client_golang and provides ready-to-use metrics for:

  • 🌐 HTTP request tracking (latency, size, in-flight)
  • ⚙ CRUD operation metrics (total, duration, object count)
  • ❤ Application health metrics
  • 🧱 Helpers for creating and registering custom metrics easily

It’s designed to be plug-and-play for HTTP servers and microservices.

🏗 Installation

go get github.com/peek8/prometric-go/prometrics

Then import it in your Go app:

import "github.com/peek8/prometric-go/prometrics"

⚙ Getting Started

Start by exposing a /metrics endpoint on your existing HTTP server:

package main
import (
    "net/http"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)
func main() {
    mux := http.NewServeMux()
    mux.Handle("/metrics", promhttp.Handler())

    http.ListenAndServe(":7080", mux)
}

You now have a fully working Prometheus endpoint at http://localhost:7080/metrics.

🔍 Track HTTP Request Metrics Automatically

You can easily wrap your handlers with Prometheus middleware:

handler := prometrics.InstrumentHttpHandler("/person",http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello, Prometheus!"))
}))

http.Handle("/", handler)
http.ListenAndServe(":7080", nil)

The library automatically tracks:

  • http_requests_total: Total HTTP requests processed
  • http_request_duration_seconds: Request duration histogram
  • http_requests_in_flight: Current requests being handled
  • http_request_size_bytes: Request payload size
  • http_response_size_bytes: Response size

Example output:

http_requests_total{path="/",method="GET",code="200"} 42
http_request_duration_seconds_bucket{le="0.1",path="/",method="GET",code="200"} 12
http_requests_in_flight{path="/"} 1

📦 Tracking CRUD Operations

The library also provides metrics for tracking your CRUD operations:

// Example: create user in DB here
tracker := prometrics.TrackCRUD("user", "create")
defer tracker(time.Now())

This automatically records:

  • crud_operations_total: Total CRUD operations by object & operation
  • object_operation_duration_seconds: Histogram of CRUD operation durations
  • object_count: Current number of objects

⚡ Setting Object Counts

You can manually control the current count of entities in your system:

prometrics.SetObjectCount("user", 100)
prometrics.IncObjectCount("user")
prometrics.DecObjectCount("user")

All labeled and tracked automatically.

🧠 System Metrics (Optional)

You can also enable lightweight system metric collection in a background goroutine:

// collect health metrics in 10s interval
ctx, cancel := context.WithCancel(context.Background(), 10)
go prometrics.CollectSystemMetricsLoop(ctx)

This will report CPU and memory usage to Prometheus — useful for understanding resource trends.

Its also possible to collect these health metrics using Middleware:

mux := http.NewServeMux()

// Use HealthMiddleware at /metrics endpoint
mux.Handle("/metrics", prometrics.HealthMiddleware(promhttp.Handler()))

Using GIN Framework

If you are using Gin Web framework for your api, you can use the gin middlewares from prometrics.

r := gin.Default()
// For http metrics
r.Use(prometrics.GinMiddleware())
// For health metrics
r.Use(prometrics.GinHealthMiddleware())

r.GET("/ping", func(c *gin.Context) {
  c.JSON(200, gin.H{"msg": "pong"})
})

r.GET("/person", func(c *gin.Context) {
  defer prometrics.TrackCRUD("person", "Get")(time.Now())

  c.JSON(200, gin.H{"name": "asraf"})
})

📊 Visualizing in Grafana

Once your app exposes /metrics, you can scrape it using Prometheus:

scrape_configs:
  - job_name: 'prometric-go-demo'
    static_configs:
      - targets: ['localhost:7080']

Then build dashboards in Grafana with panels like:

  • Request duration heatmaps
  • Total requests per endpoint
  • In-flight request gauge

⚙ Behind the Scenes

When I started building small Go microservices, I kept rewriting the same few lines of Prometheus setup code — NewCounterVec, MustRegister, boilerplate handlers, and middleware wrappers.

I wanted:

  • quick start
  • clean, ready-to-use metrics,
  • label conventions that were consistent,
  • and no mental overhead every time I started a new project.

That’s where prometric-go was born.

Some internal design goals that shaped it:

  • Quick Start with Metrics: Which metrics are useful to expose for a microservice/http-api and how to expose those. I wanted to start up with something without thinking too much.
  • Self-registration: all metrics are registered automatically using promauto.
  • Safe concurrency: metric operations are goroutine-safe by design.
  • GoDoc first: all exported symbols are documented so the package looks clean on pkg.go.dev.
  • Composable structure: submodules like http.go, crudmetrics.go, and apphealth.go keep responsibilities separate.

The idea wasn’t to replace Prometheus — just to make it nicer and faster to use for everyday Go developers.

🚀 Roadmap

Planned future enhancements include:

  • Add more metrics and customization to choose/filter metrics.
  • Integration with OpenTelemetry
  • Customizable metric namespace/prefix
  • Built-in Chi(and probably others) middleware
  • Out-of-the-box Grafana dashboards

Conclusion

prometric-go makes Prometheus metrics in Go simple, standardized, and developer-friendly.

Whether you’re building an HTTP API, a CLI, or a microservice, it helps you focus on business logic — not boilerplate metrics wiring.

Give it a try 👇

📦 github.com/peek8/prometric-go

📚 Documentation
Full API reference available at:
pkg.go.dev/github.com/peek8/prometric-go/prometrics


This content originally appeared on DEV Community and was authored by Md Asraful Haque (Sohel)