Documentation
¶
Overview ¶
Package prometrics provides simple, composable Prometheus instrumentation for HTTP servers and application-level metrics.
Overview ¶
This package offers ready-to-use middleware wrappers and helper utilities to expose standardized Prometheus metrics for HTTP handlers, application health, and business logic metrics (such as object counts or operation latency).
It is designed to reduce boilerplate while keeping flexibility for advanced users. The library wraps Prometheus client primitives such as CounterVec, GaugeVec, and HistogramVec, and integrates seamlessly with net/http or Gin.
Example usage:
import (
"net/http"
"github.com/peek8/prometric-go/prometrics"
)
func main() {
mux := http.NewServeMux()
mux.Handle("/person", prometrics.InstrumentHttpHandler("person_handler", http.HandlerFunc(PersonHandler)))
// Expose metrics endpoint
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8080", mux)
}
func PersonHandler(w http.ResponseWriter, r *http.Request) {
// your CRUD logic
}
Provided Metrics ¶
By default, all of the following HTTP metrics are exposed:
- http_requests_total{path,method,code}
- http_request_duration_seconds{path,method,code}
- http_in_flight_requests{path}
- http_request_size_bytes{path,method,code}
- http_response_size_bytes{path,method,code}
Additionally, application-level gauges or counters can be created dynamically using the MetricFactory API for business metrics.
Example (EndToEnd) ¶
ExampleEndToEnd demonstrates using prometrics in a small end-to-end HTTP server. This example won’t run indefinitely in tests, but illustrates a real-world setup.
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"time"
"github.com/peek8/prometric-go/prometrics"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func main() {
mux := http.NewServeMux()
mux.Handle("/person", prometrics.InstrumentHttpHandler("person_handler", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Person CRUD example")
})))
// Expose Prometheus metrics endpoint
mux.Handle("/metrics", promhttp.Handler())
srv := httptest.NewServer(mux)
defer srv.Close()
resp, _ := http.Get(srv.URL + "/person")
fmt.Println("Status:", resp.StatusCode)
// Simulate scraping metrics
metricsResp, err := http.Get(srv.URL + "/metrics")
if err != nil {
return
}
defer metricsResp.Body.Close()
fmt.Println("Metrics exposed:", metricsResp.StatusCode == 200)
time.Sleep(100 * time.Millisecond)
}
Output: Status: 200 Metrics exposed: true
Index ¶
- Variables
- func CollectSystemMetricsLoop(ctx context.Context, intervalSecs int)
- func CreateCounter(name, help string, labels []string) *prometheus.CounterVec
- func CreateGauge(name, help string, labels []string) *prometheus.GaugeVec
- func CreateHistogram(name, help string, labels []string, buckets []float64) *prometheus.HistogramVec
- func DecObjectCount(object string)
- func GinHealthMiddleware() gin.HandlerFunc
- func GinMiddleware() gin.HandlerFunc
- func HealthMiddleware(next http.Handler) http.Handler
- func HttpMiddleware(next http.Handler) http.Handler
- func IncObjectCount(object string)
- func InstrumentHttpHandler(handlerName string, next http.Handler) http.Handler
- func SetObjectCount(object string, count float64)
- func TrackCRUD(object, operation string) func(start time.Time)
- type HTTPMetricName
- type MetricFactory
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // AppUptime keep track of the Total duration of Application is being up // Metric type: GaugeVec AppUptime = CreateGauge("app_uptime_seconds", "App uptime in seconds", nil) // Mmory allocated by the app in bytes // Metric type: GaugeVec MemoryAlloc = CreateGauge("app_allocated_memory", "Memory allocated in bytes", nil) // CPU usage of the Go process CPUUsageGauge = CreateGauge("app_cpu_usage_percent", "CPU usage of the Go process (percent).", nil) // Number of Current goroutines // Metric type: GaugeVec Goroutines = CreateGauge("app_go_routines", "Number of Current goroutines", nil) // Number of Total garbage collections // Metric type: CounterVec GCCount = CreateCounter("app_garbage_collections_count", "Total garbage collections", nil) )
var ( // CrudOperationTotal counts the total number of CRUD operations, labeled by // object type and operation name (e.g. "person", "create"). // // Metric type: CounterVec CrudOperationTotal = CreateCounter("crud_operations_total", "Total CRUD operations", []string{"object", "operation"}) // CrudOperationDuration tracks the duration of CRUD operations in seconds, // labeled by object type and operation name. // // Metric type: HistogramVec CrudOperationDuration = CreateHistogram("object_operation_duration_seconds", "CRUD duration", []string{"object", "operation"}, nil) // CrudObjectCount reports the current number of objects of each type. // // Metric type: GaugeVec CrudObjectCount = CreateGauge("object_count", "Current number of objects", []string{"object"}) )
var ( // HttpRequestsTotal counts the total number of HTTP requests processed by the application. // It is labeled with the request path, HTTP method, and response status code. // // Typical usage: // // HttpRequestsTotal.WithLabelValues("/api/v1/person", "GET", "200").Inc() // // Metric type: CounterVec HttpRequestsTotal = promauto.NewCounterVec(prometheus.CounterOpts{ Name: string(HttpRequestsTotalMetric), Help: "Total number of HTTP requests processed, labeled by status code and method.", }, []string{"path", "method", "code"}) // HttpRequestDuration measures the duration of HTTP requests in seconds. // It is labeled by path, method, and status code, and uses the default Prometheus histogram buckets. // // Example usage: // // timer := prometheus.NewTimer(HttpRequestDuration.WithLabelValues("/api/v1/person", "GET", "200")) // defer timer.ObserveDuration() // // Metric type: HistogramVec HttpRequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ Name: string(HttpRequestDurationMetric), Help: "Histogram of HTTP request durations in seconds.", Buckets: prometheus.DefBuckets, }, []string{"path", "method", "code"}) // HttpRequestsInFlight reports the number of HTTP requests currently being served. // It is labeled by request path. // // Typical usage: // // HttpRequestsInFlight.WithLabelValues("/api/v1/person").Inc() // defer HttpRequestsInFlight.WithLabelValues("/api/v1/person").Dec() // // Metric type: GaugeVec HttpRequestsInFlight = promauto.NewGaugeVec(prometheus.GaugeOpts{ Name: string(HttpRequestsInFlightMetric), Help: "Number of HTTP requests currently being handled.", }, []string{"path"}) // HttpRequestSize records the size of incoming HTTP requests in bytes. // It is labeled by path, method, and response code, and uses exponential buckets // starting at 100 bytes, growing by a factor of 10 up to 10^5. // // Example usage: // // HttpRequestSize.WithLabelValues("/api/v1/person", "POST", "201").Observe(float64(req.ContentLength)) // // Metric type: HistogramVec HttpRequestSize = promauto.NewHistogramVec(prometheus.HistogramOpts{ Name: string(HttpRequestSizeMetric), Help: "Size of incoming HTTP requests in bytes.", Buckets: prometheus.ExponentialBuckets(100, 10, 5), }, []string{"path", "method", "code"}) // HttpResponseSize records the size of outgoing HTTP responses in bytes. // It is labeled by path, method, and status code, and uses exponential buckets // starting at 100 bytes, growing by a factor of 10 up to 10^5. // // Example usage: // // HttpResponseSize.WithLabelValues("/api/v1/person", "GET", "200").Observe(float64(respSize)) // // Metric type: HistogramVec HttpResponseSize = promauto.NewHistogramVec(prometheus.HistogramOpts{ Name: string(HttpResponseSizeMetric), Help: "Size of outgoing HTTP responses in bytes.", Buckets: prometheus.ExponentialBuckets(100, 10, 5), }, []string{"path", "method", "code"}) )
Functions ¶
func CollectSystemMetricsLoop ¶
CollectSystemMetricsLoop function collects system health information eg cpu, memory in some interval time ie intervalSecs. It should be called in a go routine
Example: if we want to collect metrics in 10 seconds interval, it should be called as follows:
ctx, cancel := context.WithCancel(context.Background(), 10) go collectSystemMetricsLoop(ctx)
It can be cancelled any time by calling `cancel()`
func CreateCounter ¶
func CreateCounter(name, help string, labels []string) *prometheus.CounterVec
CreateCounter registers a new Counter metric of type *prometheus.CounterVec and returns it.
Example:
counter := CreateCounter("crud_operations_total", "Total CRUD operations", []string{"object", "operation"})
CrudOperationTotal.WithLabelValues("person", "create").Inc()
func CreateGauge ¶
func CreateGauge(name, help string, labels []string) *prometheus.GaugeVec
CreateGauge registers a new Gauge metric of type *prometheus.GaugeVec and returns it.
Example:
g := CreateGauge("object_count", "Current number of objects", []string{"object"})
g.WithLabelValues("person").Set(55)
func CreateHistogram ¶
func CreateHistogram(name, help string, labels []string, buckets []float64) *prometheus.HistogramVec
CreateHistogram registers a new Histogram metric of type *prometheus.HistogramVec and returns it.
Example:
h := CreateCounter("crud_operations_total", "Total CRUD operations", []string{"object", "operation"})
h.WithLabelValues("person", "create").Observe(time.Since(start).Seconds())
func DecObjectCount ¶
func DecObjectCount(object string)
DecObjectCount decrements the gauge for the given object type by 1.
func GinHealthMiddleware ¶
func GinHealthMiddleware() gin.HandlerFunc
func GinMiddleware ¶
func GinMiddleware() gin.HandlerFunc
func HealthMiddleware ¶
HealthMiddleware instruments an http.Handler with Prometheus metrics. It records application health related metrics such as app uptim, memory allocated, current go routies and total garbage collectors.
Example:
http.Handle("/metrics",
prometrics.HealthMiddleware(promhttp.Handler()),
)
Example ¶
HealthMiddleware demonstrates how to register runtime metrics (goroutines, GC stats, memory usage, etc.) using HealthMiddleware.
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/peek8/prometric-go/prometrics"
)
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "OK")
})
// Wrap with Go runtime collector
instrumented := prometrics.HealthMiddleware(handler)
req := httptest.NewRequest("GET", "http://example.com/health", nil)
w := httptest.NewRecorder()
instrumented.ServeHTTP(w, req)
fmt.Println("Health endpoint responded:", w.Body.String())
}
Output: Health endpoint responded: OK
func HttpMiddleware ¶
HttpMiddleware is a generic version to wrap muxes or routers easily
func IncObjectCount ¶
func IncObjectCount(object string)
IncObjectCount increments the gauge for the given object type by 1.
func InstrumentHttpHandler ¶
InstrumentHttpHandler instruments an http.Handler with Prometheus metrics.
It records total requests, request duration, in-flight requests, request size and response size. The "handler" label is set from the given handlerName parameter. The returned handler can be used directly in an http.ServeMux.
Example:
http.Handle("/api",
prometrics.InstrumentHttpHandler("api", myHandler),
)
Example ¶
ExampleInstrumentHttpHandler demonstrates how to instrument a standard net/http handler with Prometheus metrics using InstrumentHttpHandler.
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/peek8/prometric-go/prometrics"
)
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, world!")
})
// Wrap with metrics middleware
instrumented := prometrics.InstrumentHttpHandler("hello_handler", handler)
// Simulate a request
req := httptest.NewRequest("GET", "http://example.com/hello", nil)
w := httptest.NewRecorder()
instrumented.ServeHTTP(w, req)
fmt.Println("Response Code:", w.Code)
}
Output: Response Code: 200
func SetObjectCount ¶
SetObjectCount sets the gauge for the given object type to a specific value.
Example ¶
ExampleSetObjectCount demonstrates how to Set and increment/decrement object count
package main
import (
"github.com/peek8/prometric-go/prometrics"
)
func main() {
// Set initial count of "person" objects.
prometrics.SetObjectCount("person", 42)
// Increment and decrement.
prometrics.IncObjectCount("person")
prometrics.DecObjectCount("person")
}
Output: (no output, metrics are exported to Prometheus)
func TrackCRUD ¶
TrackCRUD records metrics for a CRUD operation. It should be called immediately before and after performing an operation.
Usage pattern:
done := metrics.TrackCRUD("person", "create")
defer done(time.Now())
The returned function observes the operation duration and increments the total CRUD counter.
Example ¶
ExampleTrackCRUD desmonstrates how to use TrackCRUD function to track crud operation total and crud operation duration
package main
import (
"time"
"github.com/peek8/prometric-go/prometrics"
)
func main() {
// Simulate a "create" operation for "person" object.
done := prometrics.TrackCRUD("person", "create")
defer done(time.Now())
// Perform your operation here...
time.Sleep(120 * time.Millisecond)
}
Output: (no output, metrics are exported to Prometheus)
Types ¶
type HTTPMetricName ¶
type HTTPMetricName string
const ( HttpRequestsTotalMetric HTTPMetricName = "http_requests_total" HttpRequestDurationMetric HTTPMetricName = "http_request_duration_seconds" HttpRequestsInFlightMetric HTTPMetricName = "http_requests_in_flight" HttpRequestSizeMetric HTTPMetricName = "http_request_size_bytes" HttpResponseSizeMetric HTTPMetricName = "http_response_size_bytes" )
type MetricFactory ¶
type MetricFactory struct {
// contains filtered or unexported fields
}
MetricFactory provides a flexible API to create dynamic Prometheus metrics such as counters, gauges, and histograms at runtime. Useful for tracking domain-specific data (e.g., number of stored objects or queue size).