Problem
go-metrics has no native way to export metrics to OpenTelemetry-compatible backends. Users who adopt OTEL must write their own adapter or maintain a separate metrics pipeline.
Requirements
Implement MetricSink, PrecisionGaugeMetricSink, and ShutdownSink interfaces
Drop-in compatibility with existing go-metrics usage. No changes needed at call sites — users just swap the sink.
Support multiple configuration modes: OTLP endpoint, custom exporter, custom reader, and bring-your-own MeterProvider
Different teams have different infrastructure. Some just want to point at a collector endpoint. Others need to plug in a custom exporter (e.g., for a proprietary backend), control the reader (e.g., pull-based collection), or share a MeterProvider across libraries. A single rigid mode would force workarounds.
Map Gauge, Counter, and Sample to OTEL equivalents; handle EmitKey gracefully
These are the four go-metrics operations. Gauge, Counter, and Sample have natural OTEL counterparts. EmitKey has no equivalent — it should be dropped without breaking callers, with a warning so users know to migrate.
Default to exponential histograms with opt-in explicit buckets
Exponential histograms adapt automatically to any value distribution without requiring users to pre-define bucket boundaries. Explicit buckets should remain available for teams that need deterministic boundaries or compatibility with existing dashboards.
Allow resource configuration (service name, hostname, custom attributes)
OTEL backends use resource attributes to identify and group metrics by service. The common case (service name + hostname) should be simple. Full resource override should be available for advanced setups.
Graceful shutdown with flush
Metrics sinks often buffer data. Without an explicit shutdown path, in-flight metrics are lost on process exit. The sink should flush pending data and respect a configurable timeout.
Concurrent-safe for hot-path usage
go-metrics sinks are called from arbitrary goroutines on every operation. The sink must handle concurrent writes without locks on the hot path to avoid becoming a bottleneck.
Problem
go-metrics has no native way to export metrics to OpenTelemetry-compatible backends. Users who adopt OTEL must write their own adapter or maintain a separate metrics pipeline.
Requirements
Implement
MetricSink,PrecisionGaugeMetricSink, andShutdownSinkinterfacesDrop-in compatibility with existing go-metrics usage. No changes needed at call sites — users just swap the sink.
Support multiple configuration modes: OTLP endpoint, custom exporter, custom reader, and bring-your-own MeterProvider
Different teams have different infrastructure. Some just want to point at a collector endpoint. Others need to plug in a custom exporter (e.g., for a proprietary backend), control the reader (e.g., pull-based collection), or share a MeterProvider across libraries. A single rigid mode would force workarounds.
Map Gauge, Counter, and Sample to OTEL equivalents; handle EmitKey gracefully
These are the four go-metrics operations. Gauge, Counter, and Sample have natural OTEL counterparts. EmitKey has no equivalent — it should be dropped without breaking callers, with a warning so users know to migrate.
Default to exponential histograms with opt-in explicit buckets
Exponential histograms adapt automatically to any value distribution without requiring users to pre-define bucket boundaries. Explicit buckets should remain available for teams that need deterministic boundaries or compatibility with existing dashboards.
Allow resource configuration (service name, hostname, custom attributes)
OTEL backends use resource attributes to identify and group metrics by service. The common case (service name + hostname) should be simple. Full resource override should be available for advanced setups.
Graceful shutdown with flush
Metrics sinks often buffer data. Without an explicit shutdown path, in-flight metrics are lost on process exit. The sink should flush pending data and respect a configurable timeout.
Concurrent-safe for hot-path usage
go-metrics sinks are called from arbitrary goroutines on every operation. The sink must handle concurrent writes without locks on the hot path to avoid becoming a bottleneck.