@@ -4,27 +4,192 @@ import (
44 "go.opentelemetry.io/otel/metric"
55)
66
7+ // MetricGroup represents a group of related metrics
8+ type MetricGroup string
9+
10+ const (
11+ // MetricGroupCommand includes command-level metrics
12+ MetricGroupCommand MetricGroup = "command"
13+ // MetricGroupConnectionBasic includes basic connection metrics
14+ MetricGroupConnectionBasic MetricGroup = "connection-basic"
15+ // MetricGroupResiliency includes resiliency metrics (errors, retries, etc.)
16+ MetricGroupResiliency MetricGroup = "resiliency"
17+ // MetricGroupConnectionAdvanced includes advanced connection metrics
18+ MetricGroupConnectionAdvanced MetricGroup = "connection-advanced"
19+ // MetricGroupStream includes stream-specific metrics
20+ MetricGroupStream MetricGroup = "stream"
21+ )
22+
23+ // HistogramAggregation represents the histogram aggregation mode
24+ type HistogramAggregation string
25+
26+ const (
27+ // HistogramAggregationExplicitBucket uses explicit bucket boundaries
28+ HistogramAggregationExplicitBucket HistogramAggregation = "explicit_bucket_histogram"
29+ // HistogramAggregationBase2Exponential uses base-2 exponential buckets
30+ HistogramAggregationBase2Exponential HistogramAggregation = "base2_exponential_bucket_histogram"
31+ )
32+
733// config holds the configuration for the instrumentation
834type config struct {
9- meterProvider metric.MeterProvider
10- histogramBuckets []float64
35+ // Core settings
36+ meterProvider metric.MeterProvider
37+ enabled bool
38+
39+ // Metric group settings
40+ enabledMetricGroups map [MetricGroup ]bool
41+
42+ // Command filtering
43+ includeCommands map [string ]bool // nil means include all
44+ excludeCommands map [string ]bool // nil means exclude none
45+
46+ // Cardinality reduction
47+ hidePubSubChannelNames bool
48+ hideStreamNames bool
49+
50+ // Histogram settings
51+ histAggregation HistogramAggregation
52+
53+ // Bucket configurations for different histogram metrics
54+ bucketsOperationDuration []float64
55+ bucketsStreamProcessingDuration []float64
56+ bucketsConnectionCreateTime []float64
57+ bucketsConnectionWaitTime []float64
58+ bucketsConnectionUseTime []float64
1159}
1260
1361// defaultConfig returns the default configuration
1462func defaultConfig () config {
1563 return config {
16- meterProvider : nil , // Will use global otel.GetMeterProvider() if nil
17- histogramBuckets : defaultHistogramBuckets (),
64+ meterProvider : nil , // Will use global otel.GetMeterProvider() if nil
65+ enabled : false ,
66+
67+ // Default metric groups: command, connection-basic, resiliency
68+ enabledMetricGroups : map [MetricGroup ]bool {
69+ MetricGroupCommand : true ,
70+ MetricGroupConnectionBasic : true ,
71+ MetricGroupResiliency : true ,
72+ },
73+
74+ // No command filtering by default
75+ includeCommands : nil ,
76+ excludeCommands : nil ,
77+
78+ // Don't hide labels by default
79+ hidePubSubChannelNames : false ,
80+ hideStreamNames : false ,
81+
82+ // Use explicit bucket histogram by default
83+ histAggregation : HistogramAggregationExplicitBucket ,
84+
85+ // Default buckets for different metrics
86+ bucketsOperationDuration : defaultOperationDurationBuckets (),
87+ bucketsStreamProcessingDuration : defaultStreamProcessingDurationBuckets (),
88+ bucketsConnectionCreateTime : defaultConnectionCreateTimeBuckets (),
89+ bucketsConnectionWaitTime : defaultConnectionWaitTimeBuckets (),
90+ bucketsConnectionUseTime : defaultConnectionUseTimeBuckets (),
1891 }
1992}
2093
21- // defaultHistogramBuckets returns the default histogram buckets for operation duration
94+ // isMetricGroupEnabled checks if a metric group is enabled
95+ func (c * config ) isMetricGroupEnabled (group MetricGroup ) bool {
96+ return c .enabledMetricGroups [group ]
97+ }
98+
99+ // isCommandIncluded checks if a command should be included in metrics
100+ func (c * config ) isCommandIncluded (command string ) bool {
101+ // If there's an exclude list and command is in it, exclude
102+ if c .excludeCommands != nil && c .excludeCommands [command ] {
103+ return false
104+ }
105+
106+ // If there's an include list, only include if command is in it
107+ if c .includeCommands != nil {
108+ return c .includeCommands [command ]
109+ }
110+
111+ // No filtering, include all
112+ return true
113+ }
114+
115+ // defaultOperationDurationBuckets returns the default histogram buckets for db.client.operation.duration
22116// These buckets are designed to capture typical Redis operation latencies:
23117// - Sub-millisecond: 0.0001s (0.1ms), 0.0005s (0.5ms)
24118// - Milliseconds: 0.001s (1ms), 0.005s (5ms), 0.01s (10ms), 0.05s (50ms), 0.1s (100ms)
25119// - Sub-second: 0.5s (500ms)
26- // - Seconds: 1s, 5s, 10s
27- func defaultHistogramBuckets () []float64 {
120+ // - Seconds: 1s, 2.5s
121+ func defaultOperationDurationBuckets () []float64 {
122+ return []float64 {
123+ 0.0001 , // 0.1ms
124+ 0.0005 , // 0.5ms
125+ 0.001 , // 1ms
126+ 0.005 , // 5ms
127+ 0.01 , // 10ms
128+ 0.05 , // 50ms
129+ 0.1 , // 100ms
130+ 0.5 , // 500ms
131+ 1.0 , // 1s
132+ 2.5 , // 2.5s
133+ }
134+ }
135+
136+ // defaultStreamProcessingDurationBuckets returns the default histogram buckets for redis.client.stream.processing_duration
137+ // Stream processing can take longer than regular operations
138+ func defaultStreamProcessingDurationBuckets () []float64 {
139+ return []float64 {
140+ 0.0001 , // 0.1ms
141+ 0.0005 , // 0.5ms
142+ 0.001 , // 1ms
143+ 0.005 , // 5ms
144+ 0.01 , // 10ms
145+ 0.05 , // 50ms
146+ 0.1 , // 100ms
147+ 0.5 , // 500ms
148+ 1.0 , // 1s
149+ 5.0 , // 5s
150+ 10.0 , // 10s
151+ }
152+ }
153+
154+ // defaultConnectionCreateTimeBuckets returns the default histogram buckets for db.client.connection.create_time
155+ // Connection creation can take longer than regular operations
156+ func defaultConnectionCreateTimeBuckets () []float64 {
157+ return []float64 {
158+ 0.0001 , // 0.1ms
159+ 0.0005 , // 0.5ms
160+ 0.001 , // 1ms
161+ 0.005 , // 5ms
162+ 0.01 , // 10ms
163+ 0.05 , // 50ms
164+ 0.1 , // 100ms
165+ 0.5 , // 500ms
166+ 1.0 , // 1s
167+ 5.0 , // 5s
168+ 10.0 , // 10s
169+ }
170+ }
171+
172+ // defaultConnectionWaitTimeBuckets returns the default histogram buckets for db.client.connection.wait_time
173+ // Time waiting for a connection from the pool
174+ func defaultConnectionWaitTimeBuckets () []float64 {
175+ return []float64 {
176+ 0.0001 , // 0.1ms
177+ 0.0005 , // 0.5ms
178+ 0.001 , // 1ms
179+ 0.005 , // 5ms
180+ 0.01 , // 10ms
181+ 0.05 , // 50ms
182+ 0.1 , // 100ms
183+ 0.5 , // 500ms
184+ 1.0 , // 1s
185+ 5.0 , // 5s
186+ 10.0 , // 10s
187+ }
188+ }
189+
190+ // defaultConnectionUseTimeBuckets returns the default histogram buckets for db.client.connection.use_time
191+ // Time a connection is in use (checked out from pool)
192+ func defaultConnectionUseTimeBuckets () []float64 {
28193 return []float64 {
29194 0.0001 , // 0.1ms
30195 0.0005 , // 0.5ms
@@ -60,10 +225,100 @@ func WithMeterProvider(provider metric.MeterProvider) Option {
60225 })
61226}
62227
63- // WithHistogramBuckets sets custom histogram buckets for operation duration
64- // Buckets should be in seconds and in ascending order
65- func WithHistogramBuckets (buckets []float64 ) Option {
228+ // WithEnabled enables or disables metrics emission
229+ func WithEnabled (enabled bool ) Option {
230+ return optionFunc (func (c * config ) {
231+ c .enabled = enabled
232+ })
233+ }
234+
235+ // WithEnabledMetricGroups sets which metric groups to register
236+ // Default: ["command", "connection-basic", "resiliency"]
237+ func WithEnabledMetricGroups (groups []MetricGroup ) Option {
238+ return optionFunc (func (c * config ) {
239+ c .enabledMetricGroups = make (map [MetricGroup ]bool )
240+ for _ , group := range groups {
241+ c .enabledMetricGroups [group ] = true
242+ }
243+ })
244+ }
245+
246+ // WithIncludeCommands sets a command allow-list for metrics
247+ // Only commands in this list will have metrics recorded
248+ // If not set, all commands are included (unless excluded)
249+ func WithIncludeCommands (commands []string ) Option {
250+ return optionFunc (func (c * config ) {
251+ c .includeCommands = make (map [string ]bool )
252+ for _ , cmd := range commands {
253+ c .includeCommands [cmd ] = true
254+ }
255+ })
256+ }
257+
258+ // WithExcludeCommands sets a command deny-list for metrics
259+ // Commands in this list will not have metrics recorded
260+ func WithExcludeCommands (commands []string ) Option {
261+ return optionFunc (func (c * config ) {
262+ c .excludeCommands = make (map [string ]bool )
263+ for _ , cmd := range commands {
264+ c .excludeCommands [cmd ] = true
265+ }
266+ })
267+ }
268+
269+ // WithHidePubSubChannelNames omits channel label from Pub/Sub metrics to reduce cardinality
270+ func WithHidePubSubChannelNames (hide bool ) Option {
271+ return optionFunc (func (c * config ) {
272+ c .hidePubSubChannelNames = hide
273+ })
274+ }
275+
276+ // WithHideStreamNames omits stream label from stream metrics to reduce cardinality
277+ func WithHideStreamNames (hide bool ) Option {
278+ return optionFunc (func (c * config ) {
279+ c .hideStreamNames = hide
280+ })
281+ }
282+
283+ // WithHistogramAggregation sets the histogram aggregation mode
284+ // Controls whether bucket overrides apply
285+ func WithHistogramAggregation (agg HistogramAggregation ) Option {
286+ return optionFunc (func (c * config ) {
287+ c .histAggregation = agg
288+ })
289+ }
290+
291+ // WithBucketsOperationDuration sets explicit buckets (seconds) for db.client.operation.duration
292+ func WithBucketsOperationDuration (buckets []float64 ) Option {
293+ return optionFunc (func (c * config ) {
294+ c .bucketsOperationDuration = buckets
295+ })
296+ }
297+
298+ // WithBucketsStreamProcessingDuration sets explicit buckets (seconds) for redis.client.stream.processing_duration
299+ func WithBucketsStreamProcessingDuration (buckets []float64 ) Option {
300+ return optionFunc (func (c * config ) {
301+ c .bucketsStreamProcessingDuration = buckets
302+ })
303+ }
304+
305+ // WithBucketsConnectionCreateTime sets buckets for db.client.connection.create_time
306+ func WithBucketsConnectionCreateTime (buckets []float64 ) Option {
307+ return optionFunc (func (c * config ) {
308+ c .bucketsConnectionCreateTime = buckets
309+ })
310+ }
311+
312+ // WithBucketsConnectionWaitTime sets buckets for db.client.connection.wait_time
313+ func WithBucketsConnectionWaitTime (buckets []float64 ) Option {
314+ return optionFunc (func (c * config ) {
315+ c .bucketsConnectionWaitTime = buckets
316+ })
317+ }
318+
319+ // WithBucketsConnectionUseTime sets buckets for db.client.connection.use_time
320+ func WithBucketsConnectionUseTime (buckets []float64 ) Option {
66321 return optionFunc (func (c * config ) {
67- c .histogramBuckets = buckets
322+ c .bucketsConnectionUseTime = buckets
68323 })
69324}
0 commit comments