@@ -26,7 +26,7 @@ type Config struct {
2626 EmitterMaxQueueSize int
2727 // EmitterBatchProcessor controls custom-message export mode:
2828 // true = batched async export; false = immediate per-record export.
29- EmitterBatchProcessor bool
29+ EmitterBatchProcessor bool
3030
3131 // OTel Trace
3232 TraceSampleRatio float64
@@ -39,7 +39,10 @@ type Config struct {
3939 // OTel Metric
4040 MetricReaderInterval time.Duration
4141 MetricRetryConfig * RetryConfig
42- MetricViews []metric.View
42+ MetricViews []metric.View
43+ // MetricCardinalityLimit sets the SDK per-instrument attribute-set limit (0 = disabled).
44+ // DefaultConfig uses DefaultMetricCardinalityLimit as a production safety valve for high-cardinality workloads.
45+ MetricCardinalityLimit int
4346 // MetricCompressor sets the gRPC compressor for metrics. Valid values: "gzip" (default), "none".
4447 MetricCompressor string
4548 MetricProducers []metric.Producer // For example, a prometheus bridge
@@ -108,6 +111,9 @@ var defaultRetryConfig = RetryConfig{
108111const (
109112 defaultPackageName = "beholder"
110113 defaultMaxConcurrentSends = 10
114+
115+ // DefaultMetricCardinalityLimit is the production safety valve for high-cardinality workloads.
116+ DefaultMetricCardinalityLimit = 100000
111117)
112118
113119var defaultOtelAttributes = []attribute.KeyValue {
@@ -127,7 +133,7 @@ func DefaultConfig() Config {
127133 EmitterExportInterval : 1 * time .Second ,
128134 EmitterMaxQueueSize : 2048 ,
129135 // Keep batched export enabled by default for throughput.
130- EmitterBatchProcessor : true ,
136+ EmitterBatchProcessor : true ,
131137 // OTel message log exporter retry config
132138 LogRetryConfig : defaultRetryConfig .Copy (),
133139 // Trace
@@ -137,8 +143,9 @@ func DefaultConfig() Config {
137143 // OTel trace exporter retry config
138144 TraceRetryConfig : defaultRetryConfig .Copy (),
139145 // Metric
140- MetricReaderInterval : 1 * time .Second ,
141- MetricCompressor : "gzip" ,
146+ MetricReaderInterval : 1 * time .Second ,
147+ MetricCompressor : "gzip" ,
148+ MetricCardinalityLimit : DefaultMetricCardinalityLimit ,
142149 // OTel metric exporter retry config
143150 MetricRetryConfig : defaultRetryConfig .Copy (),
144151 // Log
@@ -148,8 +155,8 @@ func DefaultConfig() Config {
148155 LogMaxQueueSize : 2048 ,
149156 LogBatchProcessor : true ,
150157 LogStreamingEnabled : true , // Enable logs streaming by default
151- LogLevel : zapcore .InfoLevel ,
152- LogCompressor : "gzip" ,
158+ LogLevel : zapcore .InfoLevel ,
159+ LogCompressor : "gzip" ,
153160 // Chip Ingress Batch Emitter
154161 ChipIngressBatchEmitterEnabled : false ,
155162 ChipIngressBufferSize : 1000 ,
@@ -173,6 +180,7 @@ func TestDefaultConfig() Config {
173180 config .LogRetryConfig .MaxElapsedTime = 0 // Retry is disabled
174181 config .TraceRetryConfig .MaxElapsedTime = 0 // Retry is disabled
175182 config .MetricRetryConfig .MaxElapsedTime = 0 // Retry is disabled
183+ config .MetricCardinalityLimit = 0 // Disable overflow aggregation in unit tests
176184 // Auth disabled for testing (TTL=0 means static auth mode)
177185 config .AuthHeadersTTL = 0
178186 return config
@@ -186,6 +194,7 @@ func TestDefaultConfigHTTPClient() Config {
186194 config .LogBatchProcessor = false
187195 config .OtelExporterGRPCEndpoint = ""
188196 config .OtelExporterHTTPEndpoint = "localhost:4318"
197+ config .MetricCardinalityLimit = 0
189198 // Auth disabled for testing (TTL=0 means static auth mode)
190199 config .AuthHeadersTTL = 0
191200 return config
0 commit comments