wrapper/monitoring/prometheus/README.md
The prometheus wrapper package exposes standard request metrics (request
count, latency, errors) for go-micro services and clients, so they can be
scraped by a Prometheus server with zero extra boilerplate.
Resolves micro/go-micro#2893.
import prom "go-micro.dev/v5/wrapper/monitoring/prometheus"
All metrics are labelled with service, endpoint and status
("success" or "fail"). Labels are kept small on purpose to avoid
blowing up Prometheus memory.
| Metric | Type | Description |
|---|---|---|
micro_request_total | Counter | Total number of requests handled. |
micro_request_duration_seconds | Histogram | Request latency distribution (seconds). |
The micro prefix can be overridden with prom.ServiceName("myapp").
import (
"go-micro.dev/v5"
prom "go-micro.dev/v5/wrapper/monitoring/prometheus"
)
func main() {
service := micro.NewService(
micro.Name("example.service"),
micro.WrapHandler(prom.NewHandlerWrapper()),
micro.WrapClient(prom.NewClientWrapper()),
micro.WrapSubscriber(prom.NewSubscriberWrapper()),
)
service.Init()
if err := service.Run(); err != nil {
panic(err)
}
}
To expose the metrics to Prometheus, serve the default promhttp handler
on a side HTTP endpoint:
import (
"net/http"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
go func() {
http.Handle("/metrics", promhttp.Handler())
_ = http.ListenAndServe(":9100", nil)
}()
Then point Prometheus at it:
scrape_configs:
- job_name: 'example.service'
static_configs:
- targets: ['localhost:9100']
| Constructor | Wraps | Notes |
|---|---|---|
NewHandlerWrapper | server.HandlerWrapper | Incoming RPC handlers. |
NewSubscriberWrapper | server.SubscriberWrapper | Event subscribers (uses topic as endpoint). |
NewCallWrapper | client.CallWrapper | Outgoing unary RPC calls only. |
NewClientWrapper | client.Wrapper | Outgoing Call and Publish. |
NewClientWrapper is the right choice when you want metrics for both
Call and Publish; use NewCallWrapper if you only care about unary
calls and want lower overhead.
All constructors accept functional options:
prom.NewHandlerWrapper(
prom.ServiceName("myapp"), // metric name prefix
prom.Namespace("prod"), // Prometheus namespace
prom.Subsystem("api"), // Prometheus subsystem
prom.ConstLabels(prometheus.Labels{"dc": "eu-1"}), // labels on every metric
prom.Buckets([]float64{0.005, 0.05, 0.5, 1, 5}), // latency buckets
prom.Registerer(myRegistry), // custom registerer
)
Defaults:
ServiceName: "micro"Buckets: prometheus.DefBucketsRegisterer: prometheus.DefaultRegistererCreating multiple wrappers with the same options (e.g. NewHandlerWrapper
and NewClientWrapper together) is safe: the collectors are cached per
(name, namespace, subsystem) triple and AlreadyRegisteredError from
Prometheus is handled transparently, so the existing collector is reused.
The package ships with unit tests that use a fresh prometheus.Registry
per test to keep assertions isolated:
go test ./wrapper/monitoring/prometheus/...
Apache 2.0