Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8e0e223
Add cardinality limit option to MeterProvider configuration(Default 2…
ysolomchenko Jul 11, 2025
c5c4e84
unit tests for `Cardinality Limit`
ysolomchenko Jul 11, 2025
f666cfc
refactor test
ysolomchenko Jul 11, 2025
c9edcf9
fix format
ysolomchenko Jul 11, 2025
e76e74f
fix format
ysolomchenko Jul 11, 2025
c555a1f
Changelog
ysolomchenko Jul 11, 2025
7900958
fix Pr number
ysolomchenko Jul 11, 2025
e07b0be
Merge branch 'main' into define-cardinality-limit-configuration-options
ysolomchenko Jul 11, 2025
ad08fcd
extract default CardinalityLimit to const
ysolomchenko Jul 11, 2025
5c9c26f
update description
ysolomchenko Jul 11, 2025
ff93247
fix changelog
ysolomchenko Jul 11, 2025
5dc6e22
Merge branch 'define-cardinality-limit-configuration-options' of http…
ysolomchenko Jul 11, 2025
0132081
support the `OTEL_GO_X_CARDINALITY_LIMIT` env var
ysolomchenko Jul 11, 2025
a583ea9
fix test
ysolomchenko Jul 11, 2025
0ae2f4e
fix test
ysolomchenko Jul 11, 2025
c3ac6c4
Update CHANGELOG.md
ysolomchenko Jul 11, 2025
0650c70
remove comment
ysolomchenko Jul 11, 2025
3f33729
inline envvar in test
ysolomchenko Jul 11, 2025
df87b1a
Merge branch 'define-cardinality-limit-configuration-options' of http…
ysolomchenko Jul 11, 2025
eaa667c
update docs
ysolomchenko Jul 11, 2025
6d26786
Handle error
ysolomchenko Jul 11, 2025
338964e
update WithCardinalityLimit docs
ysolomchenko Jul 14, 2025
f3178f2
Merge branch 'main' into define-cardinality-limit-configuration-options
ysolomchenko Jul 15, 2025
37ce2a9
change default to no limit
ysolomchenko Jul 16, 2025
9e21043
Update sdk/metric/config.go
ysolomchenko Jul 16, 2025
ecfe5b8
Merge branch 'main' into define-cardinality-limit-configuration-options
pellared Jul 16, 2025
304b6d4
Update sdk/metric/config.go
ysolomchenko Jul 17, 2025
54bd471
Merge branch 'main' into define-cardinality-limit-configuration-options
ysolomchenko Jul 17, 2025
65281aa
Merge branch 'main' into define-cardinality-limit-configuration-options
MrAlias Jul 17, 2025
d34be5b
Merge branch 'main' into define-cardinality-limit-configuration-options
pellared Jul 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- `RPCGRPCResponseMetadata`
- Add `ErrorType` attribute helper function to the `go.opentelmetry.io/otel/semconv/v1.34.0` package. (#6962)
- Add `WithAllowKeyDuplication` in `go.opentelemetry.io/otel/sdk/log` which can be used to disable deduplication for log records. (#6968)
- Add `WithCardinalityLimit` option to configure the cardinality limit in `go.opentelemetry.io/otel/sdk/metric`. (#6996)
- Add `Clone` method to `Record` in `go.opentelemetry.io/otel/log` that returns a copy of the record with no shared state. (#7001)
- The `go.opentelemetry.io/otel/semconv/v1.36.0` package.
The package contains semantic conventions from the `v1.36.0` version of the OpenTelemetry Semantic Conventions.
Expand Down
48 changes: 42 additions & 6 deletions sdk/metric/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"errors"
"os"
"strconv"
"strings"
"sync"

Expand All @@ -17,12 +18,15 @@ import (

// config contains configuration options for a MeterProvider.
type config struct {
res *resource.Resource
readers []Reader
views []View
exemplarFilter exemplar.Filter
res *resource.Resource
readers []Reader
views []View
exemplarFilter exemplar.Filter
cardinalityLimit int
}

const defaultCardinalityLimit = 0

// readerSignals returns a force-flush and shutdown function for a
// MeterProvider to call in their respective options. All Readers c contains
// will have their force-flush and shutdown methods unified into returned
Expand Down Expand Up @@ -69,8 +73,9 @@ func unifyShutdown(funcs []func(context.Context) error) func(context.Context) er
// newConfig returns a config configured with options.
func newConfig(options []Option) config {
conf := config{
res: resource.Default(),
exemplarFilter: exemplar.TraceBasedFilter,
res: resource.Default(),
exemplarFilter: exemplar.TraceBasedFilter,
cardinalityLimit: cardinalityLimitFromEnv(),
}
for _, o := range meterProviderOptionsFromEnv() {
conf = o.apply(conf)
Expand Down Expand Up @@ -155,6 +160,23 @@ func WithExemplarFilter(filter exemplar.Filter) Option {
})
}

// WithCardinalityLimit sets the cardinality limit for the MeterProvider.
//
// The cardinality limit is the hard limit on the number of metric datapoints
// that can be collected for a single instrument in a single collect cycle.
//
// By default, there is no limit applied.
//
// Setting this to a zero or negative value means no limit is applied.
func WithCardinalityLimit(limit int) Option {
Comment thread
pellared marked this conversation as resolved.
// For backward compatibility, the environment variable `OTEL_GO_X_CARDINALITY_LIMIT`
// can also be used to set this value.
return optionFunc(func(cfg config) config {
Comment thread
MrAlias marked this conversation as resolved.
cfg.cardinalityLimit = limit
return cfg
})
}

func meterProviderOptionsFromEnv() []Option {
var opts []Option
// https://github.com/open-telemetry/opentelemetry-specification/blob/d4b241f451674e8f611bb589477680341006ad2b/specification/configuration/sdk-environment-variables.md#exemplar
Expand All @@ -170,3 +192,17 @@ func meterProviderOptionsFromEnv() []Option {
}
return opts
}

func cardinalityLimitFromEnv() int {
const cardinalityLimitKey = "OTEL_GO_X_CARDINALITY_LIMIT"
v := strings.TrimSpace(os.Getenv(cardinalityLimitKey))
if v == "" {
return defaultCardinalityLimit
}
n, err := strconv.Atoi(v)
Comment thread
dmathieu marked this conversation as resolved.
if err != nil {
otel.Handle(err)
return defaultCardinalityLimit
}
return n
}
48 changes: 48 additions & 0 deletions sdk/metric/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,54 @@ func TestWithExemplarFilterOff(t *testing.T) {
}
}

func TestWithCardinalityLimit(t *testing.T) {
cases := []struct {
name string
envValue string
options []Option
expectedLimit int
}{
{
name: "only cardinality limit from option",
envValue: "",
options: []Option{WithCardinalityLimit(1000)},
expectedLimit: 1000,
},
{
name: "cardinality limit from option overrides env",
envValue: "500",
options: []Option{WithCardinalityLimit(1000)},
expectedLimit: 1000,
},
{
name: "cardinality limit from env",
envValue: "1234",
options: []Option{},
expectedLimit: 1234,
},
{
name: "invalid env value uses default",
envValue: "not-a-number",
options: []Option{},
expectedLimit: defaultCardinalityLimit,
},
{
name: "empty env and no option uses default",
envValue: "",
options: []Option{},
expectedLimit: defaultCardinalityLimit,
},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
t.Setenv("OTEL_GO_X_CARDINALITY_LIMIT", tc.envValue)
c := newConfig(tc.options)
assert.Equal(t, tc.expectedLimit, c.cardinalityLimit)
})
}
}

func sample(parent context.Context) context.Context {
sc := trace.NewSpanContext(trace.SpanContextConfig{
TraceID: trace.TraceID{0x01},
Expand Down
Loading