Observability & Telemetry
distlimit features a pluggable telemetry architecture via the metrics.Observer interface. When disabled, the telemetry subsystem incurs 0 B/op memory overhead and zero latency impact.
📊 Prometheus Integration (metrics/prometheus)
Section titled “📊 Prometheus Integration (metrics/prometheus)”The Prometheus collector (distprom.Observer) exports metrics for total evaluation counts, execution latencies, and circuit breaker failover events.
Installation
Section titled “Installation”go get github.com/prometheus/client_golangComplete Code Setup
Section titled “Complete Code Setup”package main
import ( "net/http" "time"
"github.com/balramadan/distlimit" "github.com/balramadan/distlimit/algorithm/tokenbucket" "github.com/balramadan/distlimit/driver/memory" distprom "github.com/balramadan/distlimit/metrics/prometheus" distlimitnethttp "github.com/balramadan/distlimit/middleware/nethttp" "github.com/prometheus/client_golang/prometheus/promhttp")
func main() { memDriver := memory.New(5 * time.Minute)
// 1. Initialize Prometheus Observer promObserver := distprom.NewObserver( distprom.WithNamespace("api_gateway"), distprom.WithSubsystem("rate_limiter"), )
// 2. Attach Observer to Limiter limiter, _ := distlimit.New( memDriver, distlimit.WithLimit(100), distlimit.WithWindow(1*time.Minute), distlimit.WithAlgorithm(tokenbucket.New()), distlimit.WithMetricObserver(promObserver), )
mux := http.NewServeMux()
// 3. Enable Route Labeling on Middleware apiHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("ok")) }) mux.Handle("/api/v1/users", distlimitnethttp.New( limiter, distlimitnethttp.WithRouteLabeling(true), )(apiHandler))
// 4. Expose Metrics Endpoint for Prometheus Scraper mux.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8080", mux)}Exported Prometheus Metrics
Section titled “Exported Prometheus Metrics”| Metric Name | Type | Labels | Description |
|---|---|---|---|
distlimit_requests_total |
Counter | status, driver, algorithm, route |
Total number of rate limit evaluations. status values: allowed or blocked. |
distlimit_evaluation_duration_seconds |
Histogram | driver, algorithm, route |
Internal execution latency of rate limit evaluations in seconds. |
distlimit_hybrid_fallback_total |
Counter | driver |
Total number of times the Hybrid Driver fell back to memory due to Redis failure. |
🔭 OpenTelemetry Integration (metrics/otel)
Section titled “🔭 OpenTelemetry Integration (metrics/otel)”The OpenTelemetry observer (distotel.Observer) records metric counters and histograms using standard OTel Meter Providers.
Installation
Section titled “Installation”go get go.opentelemetry.io/otelComplete Code Setup
Section titled “Complete Code Setup”package main
import ( "time"
"github.com/balramadan/distlimit" "github.com/balramadan/distlimit/algorithm/tokenbucket" "github.com/balramadan/distlimit/driver/memory" distotel "github.com/balramadan/distlimit/metrics/otel" "go.opentelemetry.io/otel")
func main() { memDriver := memory.New(5 * time.Minute)
// Initialize OpenTelemetry Observer using global MeterProvider otelObserver := distotel.NewObserver( distotel.WithMeterProvider(otel.GetMeterProvider()), )
limiter, _ := distlimit.New( memDriver, distlimit.WithLimit(100), distlimit.WithWindow(1*time.Minute), distlimit.WithAlgorithm(tokenbucket.New()), distlimit.WithMetricObserver(otelObserver), )
_ = limiter}Zero-Allocation Guarantee
Section titled “Zero-Allocation Guarantee”When no observer is provided (or when using metrics.NewNoopObserver()), distlimit completely skips timestamping and string allocations.
Benchmark Output
Section titled “Benchmark Output”BenchmarkLimiter_NoObserver-2 322239 3223 ns/op 0 B/op 0 allocs/opKey Performance Takeaway: Enabling rate limiting with observability turned off incurs
0 B/opmemory allocations and introduces no Garbage Collection pressure under high concurrency.