-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Prometheus / OpenMetrics instrumentation for Rex, with no external dependencies — the counter, gauge and histogram primitives are implemented in this module.
go get github.com/kryovyx/rextension-metricimport (
"github.com/kryovyx/rex"
metric "github.com/kryovyx/rextension-metric"
)
app := rex.New(metric.WithMetrics(nil))That exposes /metrics on a dedicated listener at :9090, instruments every
request, and samples process metrics every 5 seconds.
$ curl :9090/metrics
# HELP http_requests_total Total HTTP requests, by route pattern and response status
# TYPE http_requests_total counter
http_requests_total{router="default",method="GET",path="/users/{id}",status="200"} 1834
…
-
http_requests_total— by router, method, route pattern and status -
http_request_duration_seconds— a histogram, same labels minus status -
http_requests_in_flight— a gauge, maintained by middleware -
http_requests_unresolved_total— 404s and 405s -
rex_uptime_seconds,rex_memory_bytes,rex_goroutines -
rex_metric_series_dropped_total,rex_events_dropped_total,rex_routes_total
See Exported Metrics.
Labels use the route pattern, never the URL path.
http_request_duration_seconds{path="/users/{id}"} is one time series no matter
how many user identifiers exist. Labelling by Request.URL.Path made every
distinct URL its own retained series — unbounded, and controlled by the client.
See Cardinality.
The in-flight gauge is middleware, not an event subscriber. The increment
and the decrement are the same function call and its defer, so they cannot be
lost independently. As events they could: Emit is non-blocking, a full queue
drops events, and increments happen under precisely the load that fills the
queue. The gauge drifted one way and never recovered.
Both are examples of the same rule: anything that must be exact belongs in middleware, not in an event subscriber.
var reg metric.Registry
_ = app.Container().Resolve(®)
orders := metric.NewCounterVec([]string{"status"})
orders.SetHelp("Orders processed, by outcome")
if err := reg.Register("orders_processed_total", orders); err != nil {
return err // a duplicate name is refused, not appended
}
orders.With(map[string]string{"status": "settled"}).Inc()See Custom Metrics.
/metrics is on a dedicated router precisely so it can be firewalled. It
exposes request rates, error counts, latency distributions and every route
pattern in the application — a map of your API to anyone who can reach it.
metric.WithMetricsRouter(rx.RouterConfig{Addr: "127.0.0.1:9090"})WithAtDefaultAddr(true) puts it on the public listener. It is a deliberate
choice, not a default.
rextension-metric — Prometheus / OpenMetrics instrumentation for Rex · MIT · © 2026 Kryovyx
Ecosystem