Documentation
¶
Overview ¶
Package metrics provides Prometheus-based monitoring and metrics collection functionality for Go applications.
The metrics package is designed to provide a standardized observability approach with dual HTTP endpoints for system-level and application-level metrics, full control over metric definitions, and integration with the Fx dependency injection framework for easy incorporation into Aleph Alpha services.
Architecture ¶
This package follows the "accept interfaces, return structs" design pattern:
- MetricsCollector interface: Defines the contract for metrics operations
- Metrics struct: Concrete implementation of the MetricsCollector interface
- NewMetrics constructor: Returns *Metrics (concrete type)
- FX module: Provides both *Metrics and MetricsCollector interface for dependency injection
Dual Endpoint Design ¶
The package provides two separate Prometheus endpoints:
1. System Metrics Endpoint (default: :9090)
- Go runtime metrics (goroutines, memory, GC stats)
- Process metrics (CPU, file descriptors, memory)
- Build info metrics
- Automatically registered, no user action required
2. Application Metrics Endpoint (default: :9091)
- User-defined custom metrics only
- Full control over metric names, types, and labels
- No default metrics - clean slate for application observability
This separation allows:
- Different scrape configurations (e.g., system metrics every 15s, app metrics every 5s)
- Different access controls (e.g., system metrics internal-only)
- Cleaner organization and cardinality management
Core Features ¶
- Two configurable /metrics endpoints for Prometheus scraping
- Integration with go.uber.org/fx for automatic lifecycle management
- Support for all Prometheus metric types (Counter, Gauge, Histogram, Summary)
- User-defined metrics with custom labels
- Automatic service label wrapping for multi-service observability
- Graceful startup and shutdown via Fx lifecycle hooks
Direct Usage (Without FX) ¶
For simple applications or tests, create metrics directly:
import "github.com/Aleph-Alpha/std/v1/metrics"
// Create metrics servers (returns concrete *Metrics)
cfg := metrics.Config{
SystemMetricsAddress: ":9090",
ApplicationMetricsAddress: ":9091",
ServiceName: "search-store",
}
m := metrics.NewMetrics(cfg)
// Start both servers
go m.SystemServer.ListenAndServe()
go m.ApplicationServer.ListenAndServe()
// Create custom application metrics
requestCounter := m.CreateCounter(
"http_requests_total",
"Total HTTP requests",
[]string{"method", "status"},
)
requestCounter.WithLabelValues("GET", "200").Inc()
// Access metrics:
// - System: http://localhost:9090/metrics
// - Application: http://localhost:9091/metrics
FX Module Integration ¶
For production applications using Uber's fx, use the FXModule which provides both the concrete type and interface:
import (
"go.uber.org/fx"
"github.com/Aleph-Alpha/std/v1/metrics"
"github.com/Aleph-Alpha/std/v1/logger"
)
app := fx.New(
logger.FXModule, // Optional: provides std logger
metrics.FXModule, // Provides *Metrics and MetricsCollector interface
fx.Provide(func() metrics.Config {
return metrics.Config{
SystemMetricsAddress: ":9090",
ApplicationMetricsAddress: ":9091",
ServiceName: "search-store",
}
}),
fx.Invoke(func(m metrics.MetricsCollector) {
// Define application metrics
counter := m.CreateCounter(
"requests_processed",
"Total processed requests",
[]string{"status"},
)
counter.WithLabelValues("success").Inc()
}),
)
app.Run()
Type Aliases in Consumer Code ¶
To simplify your code and make it metrics-agnostic, use type aliases:
package myapp
import stdMetrics "github.com/Aleph-Alpha/std/v1/metrics"
// Use type alias to reference std's interface
type MetricsCollector = stdMetrics.MetricsCollector
// Now use MetricsCollector throughout your codebase
func MyFunction(metrics MetricsCollector) {
counter := metrics.CreateCounter("my_counter", "My counter", []string{"label"})
counter.WithLabelValues("value").Inc()
}
This eliminates the need for adapters and allows you to switch implementations by only changing the alias definition.
Configuration ¶
The metrics servers can be configured via environment variables:
METRICS_SYSTEM_ADDRESS=:9090 # System metrics endpoint address METRICS_APPLICATION_ADDRESS=:9091 # Application metrics endpoint address METRICS_SERVICE_NAME=search-store # Adds service label to all metrics
Set an address to empty string ("") to disable that endpoint:
cfg := metrics.Config{
SystemMetricsAddress: "", // Disable system metrics
ApplicationMetricsAddress: ":9091", // Only application metrics
ServiceName: "search-store",
}
Metric Types and Usage Examples ¶
## 1. Counter - Cumulative metrics that only increase
Use counters for tracking totals (requests, errors, bytes processed):
requestCounter := m.CreateCounter(
"http_requests_total",
"Total number of HTTP requests",
[]string{"method", "status", "endpoint"},
)
// In your HTTP handler:
requestCounter.WithLabelValues("GET", "200", "/api/search").Inc()
requestCounter.WithLabelValues("POST", "500", "/api/index").Inc()
## 2. Gauge - Values that can go up or down
Use gauges for current state (active connections, queue depth, temperature):
activeConnections := m.CreateGauge(
"active_database_connections",
"Number of active database connections",
[]string{"pool"},
)
// Track connection pool size
activeConnections.WithLabelValues("postgres").Set(25)
activeConnections.WithLabelValues("postgres").Inc() // Add 1
activeConnections.WithLabelValues("postgres").Dec() // Subtract 1
activeConnections.WithLabelValues("postgres").Add(5) // Add 5
## 3. Histogram - Distribution tracking with quantiles
Use histograms for latency, request sizes, or any value distribution:
requestDuration := m.CreateHistogram(
"http_request_duration_seconds",
"HTTP request duration in seconds",
[]string{"method", "endpoint"},
[]float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}, // buckets
)
// In your HTTP handler:
start := time.Now()
// ... handle request ...
duration := time.Since(start).Seconds()
requestDuration.WithLabelValues("GET", "/api/search").Observe(duration)
Prometheus will automatically calculate:
- Quantiles (p50, p95, p99)
- Count of observations
- Sum of all observed values
## 4. Summary - Client-side streaming quantiles
Use summaries when you need precise quantile calculations on the client side:
apiLatency := m.CreateSummary(
"api_request_latency_seconds",
"API request latency in seconds",
[]string{"endpoint"},
map[float64]float64{
0.5: 0.05, // 50th percentile (median) with 5% error
0.9: 0.01, // 90th percentile with 1% error
0.99: 0.001, // 99th percentile with 0.1% error
},
)
// In your API handler:
start := time.Now()
// ... process request ...
apiLatency.WithLabelValues("/api/search").Observe(time.Since(start).Seconds())
Complete HTTP Middleware Example ¶
Here's a complete example of HTTP request instrumentation:
package main
import (
"net/http"
"time"
"go.uber.org/fx"
"github.com/Aleph-Alpha/std/v1/metrics"
"github.com/Aleph-Alpha/std/v1/logger"
)
type HTTPMetrics struct {
RequestsTotal metrics.Counter
RequestDuration metrics.Histogram
RequestSize metrics.Histogram
ResponseSize metrics.Histogram
ActiveRequests metrics.Gauge
}
func NewHTTPMetrics(m metrics.MetricsCollector) *HTTPMetrics {
return &HTTPMetrics{
RequestsTotal: m.CreateCounter(
"http_requests_total",
"Total number of HTTP requests",
[]string{"method", "endpoint", "status"},
),
RequestDuration: m.CreateHistogram(
"http_request_duration_seconds",
"HTTP request duration in seconds",
[]string{"method", "endpoint"},
[]float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10},
),
RequestSize: m.CreateHistogram(
"http_request_size_bytes",
"HTTP request size in bytes",
[]string{"method", "endpoint"},
exponentialBuckets(100, 10, 8), // 100, 1000, 10000, ...
),
ResponseSize: m.CreateHistogram(
"http_response_size_bytes",
"HTTP response size in bytes",
[]string{"method", "endpoint"},
exponentialBuckets(100, 10, 8),
),
ActiveRequests: m.CreateGauge(
"http_requests_active",
"Number of active HTTP requests",
[]string{"method", "endpoint"},
),
}
}
func (hm *HTTPMetrics) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
endpoint := r.URL.Path
method := r.Method
// Track active requests
hm.ActiveRequests.WithLabelValues(method, endpoint).Inc()
defer hm.ActiveRequests.WithLabelValues(method, endpoint).Dec()
// Track request size
if r.ContentLength > 0 {
hm.RequestSize.WithLabelValues(method, endpoint).Observe(float64(r.ContentLength))
}
// Capture response
wrw := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
next.ServeHTTP(wrw, r)
// Record metrics
duration := time.Since(start).Seconds()
status := fmt.Sprintf("%d", wrw.statusCode)
hm.RequestsTotal.WithLabelValues(method, endpoint, status).Inc()
hm.RequestDuration.WithLabelValues(method, endpoint).Observe(duration)
hm.ResponseSize.WithLabelValues(method, endpoint).Observe(float64(wrw.bytesWritten))
})
}
type responseWriter struct {
http.ResponseWriter
statusCode int
bytesWritten int
}
func (rw *responseWriter) WriteHeader(code int) {
rw.statusCode = code
rw.ResponseWriter.WriteHeader(code)
}
func (rw *responseWriter) Write(b []byte) (int, error) {
n, err := rw.ResponseWriter.Write(b)
rw.bytesWritten += n
return n, err
}
func main() {
app := fx.New(
logger.FXModule,
metrics.FXModule,
fx.Provide(
func() metrics.Config {
return metrics.Config{
SystemMetricsAddress: ":9090",
ApplicationMetricsAddress: ":9091",
ServiceName: "api-gateway",
}
},
NewHTTPMetrics,
),
fx.Invoke(func(hm *HTTPMetrics) {
// Your HTTP server setup with middleware
mux := http.NewServeMux()
mux.HandleFunc("/api/search", handleSearch)
server := &http.Server{
Addr: ":8080",
Handler: hm.Middleware(mux),
}
go server.ListenAndServe()
}),
)
app.Run()
}
Database Metrics Example ¶
Track database operations with detailed labels:
type DBMetrics struct {
QueriesTotal metrics.Counter
QueryDuration metrics.Histogram
ActiveConns metrics.Gauge
QueryErrors metrics.Counter
}
func NewDBMetrics(m metrics.MetricsCollector) *DBMetrics {
return &DBMetrics{
QueriesTotal: m.CreateCounter(
"db_queries_total",
"Total number of database queries",
[]string{"operation", "table"},
),
QueryDuration: m.CreateHistogram(
"db_query_duration_seconds",
"Database query duration in seconds",
[]string{"operation", "table"},
[]float64{.001, .005, .01, .025, .05, .1, .25, .5, 1, 2.5},
),
ActiveConns: m.CreateGauge(
"db_connections_active",
"Number of active database connections",
[]string{"pool"},
),
QueryErrors: m.CreateCounter(
"db_query_errors_total",
"Total number of database query errors",
[]string{"operation", "table", "error_type"},
),
}
}
// Usage in database layer:
func (db *Database) Query(ctx context.Context, query string) error {
start := time.Now()
defer func() {
duration := time.Since(start).Seconds()
db.metrics.QueryDuration.WithLabelValues("select", "documents").Observe(duration)
}()
db.metrics.QueriesTotal.WithLabelValues("select", "documents").Inc()
err := db.conn.QueryContext(ctx, query)
if err != nil {
db.metrics.QueryErrors.WithLabelValues("select", "documents", "timeout").Inc()
return err
}
return nil
}
Business Metrics Example ¶
Track application-specific business metrics:
type BusinessMetrics struct {
DocumentsIndexed metrics.Counter
SearchesPerformed metrics.Counter
ActiveUsers metrics.Gauge
DocumentProcessTime metrics.Histogram
CacheHits metrics.Counter
}
func NewBusinessMetrics(m metrics.MetricsCollector) *BusinessMetrics {
return &BusinessMetrics{
DocumentsIndexed: m.CreateCounter(
"documents_indexed_total",
"Total number of documents indexed",
[]string{"type", "status"},
),
SearchesPerformed: m.CreateCounter(
"searches_performed_total",
"Total number of search queries performed",
[]string{"type", "result_count_bucket"},
),
ActiveUsers: m.CreateGauge(
"active_users",
"Number of currently active users",
[]string{"tier"},
),
DocumentProcessTime: m.CreateHistogram(
"document_processing_seconds",
"Time to process a document",
[]string{"type", "stage"},
[]float64{.1, .5, 1, 2, 5, 10, 30, 60},
),
CacheHits: m.CreateCounter(
"cache_operations_total",
"Total cache operations",
[]string{"cache", "operation", "result"},
),
}
}
Performance Considerations ¶
1. Label Cardinality:
- Keep label values bounded (avoid user IDs, request IDs, timestamps)
- High cardinality can cause memory issues
- Good: []string{"method", "status"} with ~10 combinations
- Bad: []string{"user_id"} with millions of users
2. Metric Updates:
- All Prometheus metric operations are thread-safe
- Prefer gauges over counters when values can decrease
- Use histograms for latency tracking (more efficient than summaries)
3. Histogram vs Summary:
- Histograms: Server-side quantile calculation, aggregatable across instances
- Summaries: Client-side quantile calculation, NOT aggregatable
- Prefer histograms unless you need precise quantiles per instance
Thread Safety ¶
All methods on the Metrics struct and all Prometheus collectors are safe for concurrent use by multiple goroutines. No additional synchronization is needed.
Observability ¶
Exposed metrics can be scraped by Prometheus and visualized in Grafana or any compatible monitoring system. Example Prometheus scrape config:
scrape_configs:
- job_name: 'system-metrics'
static_configs:
- targets: ['localhost:9090']
scrape_interval: 15s
- job_name: 'application-metrics'
static_configs:
- targets: ['localhost:9091']
scrape_interval: 5s
Testing ¶
For unit tests, you can create a metrics instance without starting the servers:
func TestMyFunction(t *testing.T) {
cfg := metrics.Config{
SystemMetricsAddress: "", // Disable
ApplicationMetricsAddress: ":0", // Random port
ServiceName: "test",
}
m := metrics.NewMetrics(cfg)
counter := m.CreateCounter("test_counter", "Test counter", []string{"label"})
counter.WithLabelValues("test").Inc()
// Verify metrics using prometheus/testutil
// ...
}
Index ¶
- Constants
- Variables
- func Ptr(s string) *string
- func RegisterMetricsLifecycle(lc fx.Lifecycle, m *Metrics, log *logger.LoggerClient)
- type Config
- type Counter
- type Gauge
- type Histogram
- type Metrics
- func (m *Metrics) CreateCounter(name, help string, labels []string) Counter
- func (m *Metrics) CreateGauge(name, help string, labels []string) Gauge
- func (m *Metrics) CreateHistogram(name, help string, labels []string, buckets []float64) Histogram
- func (m *Metrics) CreateSummary(name, help string, labels []string, objectives map[float64]float64) Summary
- type MetricsCollector
- type Observer
- type Summary
Constants ¶
const ( DefaultSystemMetricsAddress = ":9090" DefaultApplicationMetricsAddress = ":9091" )
Default addresses for metrics servers if none is specified.
Variables ¶
var FXModule = fx.Module("metrics", fx.Provide( NewMetrics, fx.Annotate( func(m *Metrics) MetricsCollector { return m }, fx.As(new(MetricsCollector)), ), ), fx.Invoke(RegisterMetricsLifecycle), )
FXModule defines the Fx module for the metrics package. This module integrates two separate Prometheus metrics servers into an Fx-based application by providing the Metrics factory and registering lifecycle hooks for both servers.
The module provides: 1. *Metrics (concrete type) for direct use 2. MetricsCollector interface for dependency injection 3. Lifecycle management for both system and application metrics HTTP servers
System Metrics Endpoint (default: :9090):
- Go runtime metrics (goroutines, memory, GC)
- Process metrics (CPU, file descriptors)
- Build info metrics
Application Metrics Endpoint (default: :9091):
- User-defined custom metrics created via CreateCounter, CreateGauge, etc.
Usage:
app := fx.New(
metrics.FXModule,
fx.Provide(func() metrics.Config {
return metrics.Config{
SystemMetricsAddress: ":9090",
ApplicationMetricsAddress: ":9091",
ServiceName: "search-store",
}
}),
fx.Invoke(func(m metrics.MetricsCollector) {
// Create custom metrics
counter := m.CreateCounter("requests_total", "Total requests", []string{"endpoint"})
counter.WithLabelValues("/api/search").Inc()
}),
)
Dependencies required by this module: - A metrics.Config instance must be available in the dependency injection container - A logger.LoggerClient instance is optional but recommended for startup/shutdown logs
Functions ¶
func Ptr ¶ added in v0.12.0
Ptr returns a pointer to the given string value. Helper function for disabling endpoints in configuration.
Example:
cfg := metrics.Config{
SystemMetricsAddress: metrics.Ptr(""), // Explicitly disable
ApplicationMetricsAddress: nil, // Use default
ServiceName: "my-service",
}
func RegisterMetricsLifecycle ¶
func RegisterMetricsLifecycle(lc fx.Lifecycle, m *Metrics, log *logger.LoggerClient)
RegisterMetricsLifecycle manages the startup and shutdown lifecycle of both Prometheus metrics HTTP servers (system and application).
Parameters:
- lc: The Fx lifecycle controller
- m: The Metrics instance containing both HTTP servers
- log: The logger instance for structured lifecycle logging (optional)
The lifecycle hook:
- OnStart: Launches both metrics servers in background goroutines
- OnStop: Gracefully shuts down both servers
This ensures that both metrics endpoints are available for scraping during the application's lifetime and shut down cleanly when the application stops.
Note: This function is automatically invoked by the FXModule and does not need to be called directly in application code.
Types ¶
type Config ¶
type Config struct {
// SystemMetricsAddress determines the network address where the system
// metrics HTTP server listens. This endpoint exposes Go runtime,
// process, and build info metrics.
//
// Example values:
// - ":9090" → Listen on all interfaces, port 9090
// - "127.0.0.1:9090" → Listen only on localhost, port 9090
// - nil (or omitted) → Use default ":9090"
//
// To disable the system metrics endpoint, use an empty string pointer:
// SystemMetricsAddress: ptr(""),
//
// This setting can be configured via:
// - YAML configuration with the "system_metrics_address" key
// - Environment variable METRICS_SYSTEM_ADDRESS
//
// Default: ":9090"
SystemMetricsAddress *string `yaml:"system_metrics_address" envconfig:"METRICS_SYSTEM_ADDRESS"`
// ApplicationMetricsAddress determines the network address where the
// application metrics HTTP server listens. This endpoint exposes
// user-defined custom metrics created via CreateCounter, CreateGauge, etc.
//
// Example values:
// - ":9091" → Listen on all interfaces, port 9091
// - "127.0.0.1:9091" → Listen only on localhost, port 9091
// - nil (or omitted) → Use default ":9091"
//
// To disable the application metrics endpoint, use an empty string pointer:
// ApplicationMetricsAddress: ptr(""),
//
// This setting can be configured via:
// - YAML configuration with the "application_metrics_address" key
// - Environment variable METRICS_APPLICATION_ADDRESS
//
// Default: ":9091"
ApplicationMetricsAddress *string `yaml:"application_metrics_address" envconfig:"METRICS_APPLICATION_ADDRESS"`
// ServiceName identifies the service exposing metrics.
// This is used as a common label in all metrics to help
// distinguish metrics between services in multi-tenant deployments.
//
// Example:
// ServiceName: "document-index"
// → metrics include label service="document-index"
//
// This setting can be configured via:
// - YAML configuration with the "service_name" key
// - Environment variable METRICS_SERVICE_NAME
ServiceName string `yaml:"service_name" envconfig:"METRICS_SERVICE_NAME"`
}
Config defines the configuration structure for the Prometheus metrics servers. It contains settings that control how metrics are exposed and collected.
The package provides two separate metrics endpoints: 1. System Metrics Endpoint (default: :9090): Exposes Go runtime, process, and build info metrics 2. Application Metrics Endpoint (default: :9091): Exposes user-defined application-specific metrics
type Counter ¶ added in v0.12.0
type Counter interface {
// WithLabelValues returns the Counter for the given label values.
// The number of label values must match the number of labels defined
// when the counter was created.
WithLabelValues(lvs ...string) Counter
// Inc increments the counter by 1.
Inc()
// Add adds the given value to the counter. The value must be >= 0.
Add(val float64)
}
Counter represents a cumulative metric that only increases. It is used to track totals such as request counts, errors, or bytes processed.
This interface abstracts the underlying Prometheus CounterVec implementation.
type Gauge ¶ added in v0.12.0
type Gauge interface {
// WithLabelValues returns the Gauge for the given label values.
// The number of label values must match the number of labels defined
// when the gauge was created.
WithLabelValues(lvs ...string) Gauge
// Set sets the gauge to an arbitrary value.
Set(val float64)
// Inc increments the gauge by 1.
Inc()
// Dec decrements the gauge by 1.
Dec()
// Add adds the given value to the gauge. The value can be negative.
Add(val float64)
// Sub subtracts the given value from the gauge. The value can be negative.
Sub(val float64)
// SetToCurrentTime sets the gauge to the current Unix timestamp in seconds.
SetToCurrentTime()
}
Gauge represents a metric that can arbitrarily go up and down. It is used for values like active connections, temperature, or queue depth.
This interface abstracts the underlying Prometheus GaugeVec implementation.
type Histogram ¶ added in v0.12.0
type Histogram interface {
// WithLabelValues returns the Histogram (Observer) for the given label values.
// The number of label values must match the number of labels defined
// when the histogram was created.
WithLabelValues(lvs ...string) Observer
// Observe adds a single observation to the histogram.
Observe(val float64)
}
Histogram tracks the distribution of observations (e.g., request durations or response sizes). Histograms calculate quantiles, counts, and sums on the server side.
This interface abstracts the underlying Prometheus HistogramVec implementation.
type Metrics ¶
type Metrics struct {
// SystemServer defines the HTTP server for the /metrics endpoint exposing
// Go runtime, process, and build info metrics.
// Endpoint: SystemMetricsAddress (default: :9090)
SystemServer *http.Server
// ApplicationServer defines the HTTP server for the /metrics endpoint exposing
// user-defined application metrics.
// Endpoint: ApplicationMetricsAddress (default: :9091)
ApplicationServer *http.Server
// SystemRegistry is the Prometheus registry for system-level metrics
// (Go runtime, process collectors, build info).
SystemRegistry *prometheus.Registry
// ApplicationRegistry is the Prometheus registry for user-defined metrics.
// All metrics created via CreateCounter, CreateGauge, CreateHistogram, CreateSummary
// are registered here.
ApplicationRegistry *prometheus.Registry
// contains filtered or unexported fields
}
Metrics encapsulates two separate Prometheus registries and HTTP servers: 1. System metrics (Go runtime, process, build info) - exposed on SystemServer 2. Application metrics (user-defined custom metrics) - exposed on ApplicationServer
This separation allows different scrape configurations and access controls for system-level vs application-level observability.
func NewMetrics ¶
NewMetrics initializes and returns a new instance of the Metrics struct. It sets up two separate Prometheus registries and HTTP servers:
1. System Metrics Endpoint (default: :9090):
- Go runtime metrics (goroutines, GC stats, heap usage)
- Process metrics (CPU time, memory, file descriptors)
- Build info metrics
2. Application Metrics Endpoint (default: :9091):
- User-defined metrics created via CreateCounter, CreateGauge, etc.
- No default metrics - fully controlled by the application
Parameters:
- cfg: Configuration for the metrics servers, including addresses and service name
Returns:
- *Metrics: A configured Metrics instance ready for lifecycle management and Fx module integration
Both registries automatically wrap all metrics with a constant `service` label for easier aggregation and filtering in multi-service environments.
Example:
cfg := metrics.Config{
SystemMetricsAddress: ":9090",
ApplicationMetricsAddress: ":9091",
ServiceName: "document-index",
}
metricsInstance := metrics.NewMetrics(cfg)
go metricsInstance.SystemServer.ListenAndServe()
go metricsInstance.ApplicationServer.ListenAndServe()
Access metrics at:
- System metrics: http://localhost:9090/metrics
- Application metrics: http://localhost:9091/metrics
func (*Metrics) CreateCounter ¶
CreateCounter creates a new counter metric and registers it to the application metrics registry.
Counters are cumulative metrics that only increase (e.g., total requests, errors).
Example:
counter := m.CreateCounter("http_requests_total", "Total HTTP requests", []string{"method", "status"})
counter.WithLabelValues("GET", "200").Inc()
counter.WithLabelValues("POST", "500").Inc()
func (*Metrics) CreateGauge ¶
CreateGauge creates a new gauge metric and registers it to the application metrics registry.
Gauges represent values that can go up or down (e.g., active connections, temperature, queue depth).
Example:
gauge := m.CreateGauge("active_connections", "Number of active connections", []string{"pool"})
gauge.WithLabelValues("postgres").Set(42)
gauge.WithLabelValues("postgres").Inc()
gauge.WithLabelValues("postgres").Dec()
func (*Metrics) CreateHistogram ¶
CreateHistogram creates a new histogram metric and registers it to the application metrics registry.
Histograms track distributions of values (e.g., request latencies) and automatically calculate quantiles and counts.
Example:
hist := m.CreateHistogram(
"request_duration_seconds",
"Request duration in seconds",
[]string{"endpoint"},
[]float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10},
)
hist.WithLabelValues("/api/search").Observe(0.25)
func (*Metrics) CreateSummary ¶ added in v0.12.0
func (m *Metrics) CreateSummary(name, help string, labels []string, objectives map[float64]float64) Summary
CreateSummary creates a new summary metric and registers it to the application metrics registry.
Summaries calculate streaming quantiles on the client side. Objectives define the quantile ranks and their allowed error.
Example:
summary := m.CreateSummary(
"api_latency_seconds",
"API request latency in seconds",
[]string{"endpoint"},
map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
)
summary.WithLabelValues("/api/search").Observe(0.25)
type MetricsCollector ¶ added in v0.12.0
type MetricsCollector interface {
// CreateCounter creates a new counter metric and registers it to the
// application metrics registry.
//
// Counters are cumulative metrics that only increase over time (e.g., total requests).
// Use WithLabelValues to set specific label values before incrementing.
//
// Example:
// counter := m.CreateCounter("http_requests_total", "Total HTTP requests", []string{"method", "status"})
// counter.WithLabelValues("GET", "200").Inc()
CreateCounter(name, help string, labels []string) Counter
// CreateHistogram creates a new histogram metric and registers it to the
// application metrics registry.
//
// Histograms track distributions of values (e.g., request durations) and automatically
// calculate quantiles and counts across configurable buckets.
//
// Example:
// hist := m.CreateHistogram("request_duration_seconds", "Request duration", []string{"endpoint"}, []float64{.01, .05, .1, .5, 1, 5})
// hist.WithLabelValues("/api/search").Observe(0.25)
CreateHistogram(name, help string, labels []string, buckets []float64) Histogram
// CreateGauge creates a new gauge metric and registers it to the
// application metrics registry.
//
// Gauges represent values that can go up or down (e.g., active connections, temperature).
// Use Set, Inc, Dec, Add, or Sub to modify gauge values.
//
// Example:
// gauge := m.CreateGauge("active_connections", "Number of active connections", []string{"pool"})
// gauge.WithLabelValues("postgres").Set(42)
CreateGauge(name, help string, labels []string) Gauge
// CreateSummary creates a new summary metric and registers it to the
// application metrics registry.
//
// Summaries are similar to histograms but calculate streaming quantiles on the client side.
// Objectives define the quantile ranks (e.g., 0.5 for median, 0.99 for 99th percentile).
//
// Example:
// summary := m.CreateSummary("api_latency_seconds", "API latency", []string{"endpoint"}, map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001})
// summary.WithLabelValues("/api/search").Observe(0.25)
CreateSummary(name, help string, labels []string, objectives map[float64]float64) Summary
}
MetricsCollector provides an interface for collecting and exposing application metrics. It abstracts metric operations with support for counters, histograms, gauges, and summaries.
This interface is implemented by the concrete *Metrics type and does not expose any Prometheus-specific types, allowing for potential alternative implementations or testing mocks.
All metrics created through this interface are registered to the application metrics registry and exposed via the application metrics endpoint (default: :9091).
type Observer ¶ added in v0.12.0
type Observer interface {
// Observe adds a single observation to the metric.
Observe(val float64)
}
Observer is a common interface for metrics that observe values (Histogram and Summary).
type Summary ¶ added in v0.12.0
type Summary interface {
// WithLabelValues returns the Summary (Observer) for the given label values.
// The number of label values must match the number of labels defined
// when the summary was created.
WithLabelValues(lvs ...string) Observer
// Observe adds a single observation to the summary.
Observe(val float64)
}
Summary calculates streaming quantiles of observed values on the client side. Unlike histograms, summaries cannot be aggregated across multiple instances.
This interface abstracts the underlying Prometheus SummaryVec implementation.