metrics

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Jun 9, 2025 License: MIT Imports: 12 Imported by: 2

README

metrics

Go package for metrics collection in OpenMetrics format.

Go Reference Go Report Card MIT License

Features

  • 🚀 High Performance: Built on top of Prometheus Go client with minimal overhead.
  • 🌐 HTTP Middleware: Real-time monitoring of incoming requests.
  • 🔄 HTTP Transport: Client instrumentation for outgoing requests.
  • 🎯 Compatibility: Compatible with OpenMetrics 1.0 collectors, e.g. Prometheus.
  • 🔒 Type Safety: Compile-time type-safe metric labels with struct tags validation.
  • 🏷️ Data Cardinality: The API helps you keep the metric label cardinality low.
  • 📊 Complete Metrics: Counter, Gauge, and Histogram metrics with customizable buckets.

Usage

go get github.com/go-chi/metrics@latest

package main

import (
	"github.com/go-chi/metrics"
)

func main() {
	r := chi.NewRouter()

	// Collect metrics for incoming HTTP requests automatically.
	r.Use(metrics.Collector(metrics.CollectorOpts{
		Host:  false,
		Proto: true,
		Skip: func(r *http.Request) bool {
			return r.Method != "OPTIONS"
		},
	}))

	r.Handle("/metrics", metrics.Handler())
	r.Post("/do-work", doWork)

	// Collect metrics for outgoing HTTP requests automatically.
	transport := metrics.Transport(metrics.TransportOpts{
		Host: true,
	})
	http.DefaultClient.Transport = transport(http.DefaultTransport)

	go simulateTraffic()

	log.Println("Server starting on :8022")
	if err := http.ListenAndServe(":8022", r); err != nil {
		log.Fatal(err)
	}
}

// Strongly typed metric labels help maintain low data cardinality
// by enforcing consistent label names across the codebase.
type jobLabels struct {
	Name   string `label:"name"`
	Status string `label:"status"`
}

var jobCounter = metrics.CounterWith[jobLabels]("jobs_processed_total", "Number of jobs processed")

func doWork(w http.ResponseWriter, r *http.Request) {
	time.Sleep(time.Second) // simulate work

	if rand.Intn(100) > 90 { // simulate error
		jobCounter.Inc(jobLabels{Name: "job", Status: "error"})
		w.Write([]byte("Job failed.\n"))
		return
	}

	jobCounter.Inc(jobLabels{Name: "job", Status: "success"})
	w.Write([]byte("Job finished successfully.\n"))
}

func simulateTraffic() {
	for {
		_, _ = client.Get("http://example.com")
		time.Sleep(500 * time.Millisecond)
	}
}

Example

See _example/main.go and try it locally:

$ cd _example

$ go run .

TODO: Run Prometheus + Grafana locally.

License

MIT license

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Collector

func Collector(opts CollectorOpts) func(next http.Handler) http.Handler

Collector returns HTTP middleware for tracking Prometheus metrics for incoming HTTP requests.

func Handler

func Handler() http.Handler

Handler returns an HTTP handler that serves OpenMetrics (Prometheus metrics) from the default Prometheus registry in the standard exposition format.

This handler should typically be mounted at the "/metrics" path and protected from public access, e.g. via github.com/go-chi/chi/middleware.BasicAuth middleware.

func Transport

func Transport(opts TransportOpts) func(http.RoundTripper) http.RoundTripper

Transport returns a new http.RoundTripper to be used in http.Client to track metrics for outgoing HTTP requests. It records request duration and counts for each unique combination of HTTP method, path and status code. The metrics are tagged with the endpoint (method + path) and status code for detailed monitoring.

Types

type CollectorOpts

type CollectorOpts struct {
	// Host enables tracking of request "host" label.
	Host bool

	// Proto enables tracking of request "proto" label, e.g. "HTTP/2", "HTTP/1.1 WebSocket".
	Proto bool

	// Skip is an optional predicate function that determines whether to skip recording metrics for a given request.
	// If nil, all requests are recorded. If provided, requests where Skip returns true will not be recorded.
	Skip func(r *http.Request) bool
}

type CounterMetric

type CounterMetric struct {
	// contains filtered or unexported fields
}

func Counter

func Counter(name string, help string) CounterMetric

Counter creates a counter metric

func (*CounterMetric) Add

func (c *CounterMetric) Add(value float64)

func (*CounterMetric) Inc

func (c *CounterMetric) Inc()

type CounterMetricLabeled

type CounterMetricLabeled[T any] struct {
	// contains filtered or unexported fields
}

func CounterWith

func CounterWith[T any](name string, help string) CounterMetricLabeled[T]

CounterWith creates a counter metric with typed labels

func (*CounterMetricLabeled[T]) Add

func (c *CounterMetricLabeled[T]) Add(value float64, labels T)

func (*CounterMetricLabeled[T]) Inc

func (c *CounterMetricLabeled[T]) Inc(labels T)

type GaugeMetric

type GaugeMetric struct {
	// contains filtered or unexported fields
}

func Gauge

func Gauge(name, help string) GaugeMetric

Gauge creates a gauge metric

func (*GaugeMetric) Add

func (g *GaugeMetric) Add(value float64)

func (*GaugeMetric) Dec

func (g *GaugeMetric) Dec()

func (*GaugeMetric) Inc

func (g *GaugeMetric) Inc()

func (*GaugeMetric) Set

func (g *GaugeMetric) Set(value float64)

type GaugeMetricLabeled

type GaugeMetricLabeled[T any] struct {
	// contains filtered or unexported fields
}

func GaugeWith

func GaugeWith[T any](name, help string) GaugeMetricLabeled[T]

GaugeWith creates a gauge metric with typed labels

func (*GaugeMetricLabeled[T]) Add

func (g *GaugeMetricLabeled[T]) Add(value float64, labels T)

func (*GaugeMetricLabeled[T]) Dec

func (g *GaugeMetricLabeled[T]) Dec(labels T)

func (*GaugeMetricLabeled[T]) Inc

func (g *GaugeMetricLabeled[T]) Inc(labels T)

func (*GaugeMetricLabeled[T]) Set

func (g *GaugeMetricLabeled[T]) Set(value float64, labels T)

type HistogramMetric

type HistogramMetric struct {
	// contains filtered or unexported fields
}

func Histogram

func Histogram(name, help string, buckets []float64) HistogramMetric

Histogram creates a histogram metric

func (*HistogramMetric) Observe

func (h *HistogramMetric) Observe(value float64)

type HistogramMetricLabeled

type HistogramMetricLabeled[T any] struct {
	// contains filtered or unexported fields
}

HistogramMetric represents a histogram metric with typed labels

func HistogramWith

func HistogramWith[T any](name, help string, buckets []float64) HistogramMetricLabeled[T]

HistogramWith creates a histogram metric with typed labels

func (*HistogramMetricLabeled[T]) Observe

func (h *HistogramMetricLabeled[T]) Observe(value float64, labels T)

type TransportOpts

type TransportOpts struct {
	// Host adds the request host as a "host" label to metrics.
	// WARNING: High cardinality risk - only enable for limited, known hosts.
	// Do not enable for user-input URLs, crawlers, or dynamically generated hosts.
	Host bool
}

Jump to

Keyboard shortcuts

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