prometrics

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 17, 2025 License: Apache-2.0 Imports: 14 Imported by: 0

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

Examples

Constants

This section is empty.

Variables

View Source
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)
)
View Source
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"})
)
View Source
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

func CollectSystemMetricsLoop(ctx context.Context, intervalSecs int)

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

func HealthMiddleware(next http.Handler) http.Handler

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

func HttpMiddleware(next http.Handler) http.Handler

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

func InstrumentHttpHandler(handlerName string, next http.Handler) http.Handler

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

func SetObjectCount(object string, count float64)

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

func TrackCRUD(object, operation string) func(start time.Time)

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).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL