1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2026-06-19 21:45:50 +02:00

1264 Commits

Author SHA1 Message Date
Robert Pająk 4ef740f17f sdk: deduplicate MAP attribute keys (#8471)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/7957.

- Remove duplicate keys from `attribute.MAP` values by default across
SDK resource, log, trace, and metric export paths, including top-level
MAP-valued attributes and MAP values nested inside MAP or SLICE values.
- Update `log.WithAllowKeyDuplication()` behavior and docs.
- Always deduplicate MAP values in resources;
`go.opentelemetry.io/otel/sdk/resource` does not provide an opt-out.
Resources are typically evaluated once at startup or occasionally
updated. The ~12.90% overhead shown in benchmarks will have low impact
on an application's runtime latency, and having a strictly normalized
Resource map prevents downstream exporter issues.
- Preserve top-level `attribute.Set` behavior for resources, scopes, and
metric datapoint attributes; this change normalizes MAP-valued attribute
values, not the outer attribute collection semantics.
- Use last-value-wins semantics and do not increment dropped-attribute
counts for MAP duplicate removal.
- Keep internal helper code scoped per module: shared source lives in
`internal/shared/attrdedup`, then `gotmpl` renders module-local copies
under `sdk/internal`, `sdk/log/internal`, and `sdk/metric/internal`.

## Benchmarks

Baseline benchmarks were run from a local `main` worktree at
`/tmp/opentelemetry-go-main`; branch benchmarks were run from this
branch. All comparisons use `-benchmem -count=10`.

New helper benchmarks:

```console
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/sdk/internal/attrdedup
cpu: 13th Gen Intel(R) Core(TM) i7-13800H
                          │   this.txt   │
                          │    sec/op    │
Value/FastPath-20           186.4n ± 19%
Value/DuplicateMap-20       363.4n ± 82%
Value/NestedMapInSlice-20   607.4n ± 20%
geomean                     345.2n

                          │   this.txt   │
                          │     B/op     │
Value/FastPath-20           0.000 ± 0%
Value/DuplicateMap-20       320.0 ± 0%
Value/NestedMapInSlice-20   416.0 ± 0%
geomean                                ¹
¹ summaries must be >0 to compute geomean

                          │   this.txt   │
                          │  allocs/op   │
Value/FastPath-20           0.000 ± 0%
Value/DuplicateMap-20       2.000 ± 0%
Value/NestedMapInSlice-20   4.000 ± 0%
geomean                                ¹
¹ summaries must be >0 to compute geomean
```

```console
pkg: go.opentelemetry.io/otel/sdk/resource
                    │ main │ branch │
                    │ sec/op │ sec/op vs base │
MergeResource_1-20    587.9n ± 28%   677.7n ± 17%  +15.28% (p=0.043 n=10)
MergeResource_2-20    938.5n ± 11%  1011.8n ± 18%        ~ (p=0.393 n=10)
MergeResource_3-20    1.301µ ±  8%   1.522µ ± 21%  +16.95% (p=0.023 n=10)
MergeResource_4-20    1.487µ ± 31%   2.006µ ± 12%  +34.90% (p=0.000 n=10)
MergeResource_6-20    2.409µ ± 12%   2.962µ ± 15%  +22.96% (p=0.001 n=10)
MergeResource_8-20    3.336µ ± 10%   3.104µ ± 16%        ~ (p=0.247 n=10)
MergeResource_16-20   7.750µ ±  6%   8.076µ ±  9%        ~ (p=0.190 n=10)
geomean               1.821µ         2.056µ        +12.90%

pkg: go.opentelemetry.io/otel/sdk/trace
                                              │ main │ branch │
                                              │ sec/op │ sec/op vs base │
RecordingSpanSetAttributes/WithLimit/false-20  7.907µ ±  6%  11.311µ ±  6%  +43.06% (p=0.000 n=10)
RecordingSpanSetAttributes/WithLimit/true-20   13.29µ ± 15%   17.13µ ±  6%  +28.97% (p=0.002 n=10)
TraceStart/with_a_simple_span-20               402.1n ±  2%   406.4n ±  2%        ~ (p=0.218 n=10)
TraceStart/with_several_links-20               521.8n ±  1%   532.4n ±  2%  +2.03% (p=0.000 n=10)
TraceStart/with_attributes-20                  570.5n ±  2%   594.1n ±  2%  +4.12% (p=0.000 n=10)
TraceStart/ObservabilityEnabled-20             463.5n ±  1%   469.9n ±  1%  +1.38% (p=0.003 n=10)
SpanSetAttributesOverCapacity-20               2.539µ ±  8%   2.501µ ±  8%       ~ (p=0.684 n=10)
SpanWithAttributes_4/AlwaysSample-20           1.650µ ± 23%   1.867µ ± 12%       ~ (p=0.063 n=10)
SpanWithAttributes_4/NeverSample-20            634.5n ± 11%   683.4n ± 19%       ~ (p=0.315 n=10)
geomean                                        1.356µ         1.495µ       +10.27%
```

Resource and trace allocation counts were unchanged in the same
benchstat run.

```console
pkg: go.opentelemetry.io/otel/sdk/log
                                              │ main │ branch │
                                              │ sec/op │ sec/op vs base │
LoggerProviderLogger-20                        505.1n ± 8%  473.9n ± 15%       ~ (p=0.123 n=10)
SetAttributes/Unique/NoLimits-20               230.9n ± 9%  238.1n ±  7%       ~ (p=0.343 n=10)
SetAttributes/NestedDeduplication/Enabled-20   836.0n ± 6%  758.1n ±  8%  -9.32% (p=0.011 n=10)
SetAttributes/NestedDeduplication/Disabled-20  119.7n ± 1%  127.7n ±  8%       ~ (p=0.157 n=10)
geomean                                        328.7n       323.3n        -1.65%
```

Log allocation counts were unchanged in the same benchstat run.

```console
pkg: go.opentelemetry.io/otel/sdk/metric
                                                         │ main │ branch │
                                                         │ sec/op │ sec/op vs base │
MeasureNewAttributeSet/AlwaysOn/Int64Counter-20           725.7n ± 114%  1504.5n ± 15%  +107.32% (p=0.043 n=10)
MeasureNewAttributeSet/AlwaysOn/Float64Counter-20         1.106µ ±  14%   1.480µ ± 15%   +33.82% (p=0.000 n=10)
MeasureNewAttributeSet/AlwaysOn/Int64UpDownCounter-20     1.354µ ±   9%   1.334µ ± 13%         ~ (p=0.529 n=10)
MeasureNewAttributeSet/AlwaysOn/Float64UpDownCounter-20   1.445µ ±  29%   1.439µ ± 14%         ~ (p=0.542 n=10)
MeasureNewAttributeSet/AlwaysOn/Int64Histogram-20         1.423µ ±  31%   1.453µ ± 29%         ~ (p=0.631 n=10)
MeasureNewAttributeSet/AlwaysOn/Float64Histogram-20       1.383µ ±  41%   1.416µ ± 20%         ~ (p=0.796 n=10)
MeasureNewAttributeSet/AlwaysOn/Int64Gauge-20             1.105µ ±  42%   1.527µ ±  8%   +38.21% (p=0.023 n=10)
MeasureNewAttributeSet/AlwaysOn/Float64Gauge-20           1.598µ ±  10%   1.355µ ± 37%         ~ (p=0.247 n=10)
MeasureNewAttributeSet/AlwaysOff/Int64Counter-20          739.1n ±  16%   830.0n ± 17%         ~ (p=0.280 n=10)
MeasureNewAttributeSet/AlwaysOff/Float64Counter-20        299.2n ±  24%   766.7n ± 29%  +156.19% (p=0.000 n=10)
MeasureNewAttributeSet/AlwaysOff/Int64UpDownCounter-20    322.2n ± 104%   873.2n ±  7%  +171.01% (p=0.000 n=10)
MeasureNewAttributeSet/AlwaysOff/Float64UpDownCounter-20  740.5n ±  49%   713.8n ± 21%         ~ (p=0.481 n=10)
MeasureNewAttributeSet/AlwaysOff/Int64Histogram-20        901.1n ±  33%   988.8n ± 12%         ~ (p=0.481 n=10)
MeasureNewAttributeSet/AlwaysOff/Float64Histogram-20      1.059µ ±  23%   1.009µ ± 21%         ~ (p=0.393 n=10)
MeasureNewAttributeSet/AlwaysOff/Int64Gauge-20            408.9n ±  50%   788.0n ± 23%   +92.71% (p=0.000 n=10)
MeasureNewAttributeSet/AlwaysOff/Float64Gauge-20          544.5n ±  37%   662.1n ± 39%         ~ (p=0.725 n=10)
AsyncMeasureNewAttributeSet/AlwaysOn-20                   6.199µ ±  20%   5.766µ ± 26%         ~ (p=0.247 n=10)
AsyncMeasureNewAttributeSet/TraceBased-20                 1.811µ ±  10%   1.806µ ± 11%         ~ (p=0.912 n=10)
Instrument/instrumentImpl/aggregate-20                    2.577µ ±  10%   2.378µ ± 14%         ~ (p=0.247 n=10)
Instrument/observable/observe-20                          1.863µ ±  17%   1.762µ ±  8%         ~ (p=0.255 n=10)
InstrumentCreation-20                                     2.346µ ±  17%   2.215µ ±  8%         ~ (p=0.315 n=10)
geomean                                                   1.102µ          1.324µ         +20.12%
```

Metric B/op geomean was +0.10% and allocs/op geomean was unchanged in
the same benchstat run.

## Rejected implementations

### Seen-Pool

I tested an alternative `deduplicateMapValue` implementation using a
pooled `map[string]struct{}` for duplicate detection, modeled after
`sdk/log.Record`'s `seenPool`. The candidate was not kept because it
regressed all non-opt-out helper benchmark paths.

```console
pkg: go.opentelemetry.io/otel/sdk/internal/attrdedup
                             │ baseline │ seenpool │
                             │ sec/op │ sec/op vs base │
Value/FastPath-20              143.8n ± 0%   201.6n ±  0%  +40.15% (p=0.000 n=20)
Value/DuplicateMap-20          669.8n ± 9%   862.9n ± 12%  +28.83% (p=0.000 n=20)
Value/NestedMapInSlice-20      918.2n ± 9%  1115.0n ±  5%  +21.43% (p=0.000 n=20)
Value/AllowKeyDuplication-20   1.324n ± 0%   1.324n ±  0%        ~ (p=0.389 n=20)
geomean                        104.0n        126.6n        +21.68%
```

The candidate did not change allocation counts, but the `sync.Pool` and
map operations added measurable CPU overhead.

### Needs-Style Preflight

I tested an alternative implementation modeled after
`sdk/log.Record.needsValueLimitsOrDedup`: first scan attribute values to
determine whether normalization is needed, then normalize only when the
scan says a value would change.

The refined candidate preserved the opt-out fast path and avoided an
extra slice preflight pass, but was not kept because package-level
benchmark results were mixed: resource improved, but trace and metric
regressed.

```console
pkg: go.opentelemetry.io/otel/sdk/internal/attrdedup
                             │ baseline │ candidate │
                             │ sec/op │ sec/op vs base │
Value/FastPath-20              144.10n ± 0%   92.52n ± 0%  -35.79% (p=0.000 n=10)
Value/DuplicateMap-20           682.8n ± 19%  677.1n ± 34%       ~ (p=0.796 n=10)
Value/NestedMapInSlice-20       900.5n ±  7%  975.5n ±  8%  +8.33% (p=0.019 n=10)
Value/AllowKeyDuplication-20    1.325n ±  0%  1.325n ±  1%       ~ (p=0.860 n=10)
geomean                         104.1n        94.85n       -8.88%
```

```console
pkg: go.opentelemetry.io/otel/sdk/resource
MergeResource geomean: 2.209µ -> 1.896µ (-14.17%)

pkg: go.opentelemetry.io/otel/sdk/trace
Trace benchmark geomean: 1.474µ -> 1.576µ (+6.90%)
```

```console
pkg: go.opentelemetry.io/otel/sdk/log
Log benchmark geomean: 330.0n -> 330.6n (+0.18%)
```

```console
pkg: go.opentelemetry.io/otel/sdk/metric
Metric benchmark geomean: 1.355µ -> 1.455µ (+7.38%)
```

All candidate allocation geomeans were unchanged. Because the candidate
did not improve performance consistently across affected export paths,
this PR keeps the original lazy allocation-free no-op implementation.
2026-06-18 06:25:50 +02:00
Robert Pająk e7087816b8 sdk/trace: apply AttributeValueLengthLimit to attribute.MAP (#8454)
Fixes #7956

Per the OTel spec, attribute value limits must be applied recursively to
map values. Previously `truncateAttr` handled `STRING`, `STRINGSLICE`,
`BYTESLICE`, and `SLICE`, but not `MAP`.

Add `MAP` handling to the trace SDK attribute limiter:
- `truncateAttr`: truncates `attribute.MAP` values when needed.
- `truncateValue`: recursively truncates `MAP`, `SLICE`, `STRINGSLICE`,
`STRING`, and `BYTESLICE` values.
- `needsTruncation`: pre-scan guard for `MAP` values to avoid rebuilding
when no nested value changes.


`benchstat` for `BenchmarkSpanLimits/AttributeValueLengthLimit`
(`count=10`):

```
SpanLimits/AttributeValueLengthLimit-20   14.88µ ± 16%   15.56µ ± 53%       ~ (p=0.739 n=10)
SpanLimits/AttributeValueLengthLimit-20   12.71Ki ± 0%   13.66Ki ± 0%   +7.52% (p=0.000 n=10)
SpanLimits/AttributeValueLengthLimit-20    47.00 ± 0%     56.00 ± 0%   +19.15% (p=0.000 n=10)
```

The extra allocations are expected in the truncation path because
truncated `MAP` values are rebuilt recursively.

`benchstat` for `BenchmarkSpanLimits/AttributeValueLengthLimit`
(`count=10`):

```
SpanLimits/None-20   14.18µ ± 7%   12.86µ ± 18%   -9.31% (p=0.043 n=10)
SpanLimits/None-20   12.16Ki ± 0%  12.16Ki ± 0%       ~ (p=1.000 n=10)
SpanLimits/None-20   38.00 ± 0%    38.00 ± 0%          ~ (p=1.000 n
```

No extra allocations where nothing needs to be rebuild.
2026-06-16 21:07:49 +02:00
Robert Pająk 51b03667ac attribute: add MAP type support (#8445)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/7935

```
$ go test -run=^$ -bench=BenchmarkMap
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/attribute
cpu: 13th Gen Intel(R) Core(TM) i7-13800H
BenchmarkMap/Len3/Value-20      12423774               143.1 ns/op           192 B/op          1 allocs/op
BenchmarkMap/Len3/KeyValue-20            8123966               170.4 ns/op           192 B/op          1 allocs/op
BenchmarkMap/Len3/AsMap-20              12685639               111.0 ns/op           192 B/op          1 allocs/op
BenchmarkMap/Len3/String-20              4482690               250.1 ns/op           128 B/op          1 allocs/op
BenchmarkMap/Len3/Emit-20                5927258               205.5 ns/op           128 B/op          1 allocs/op
BenchmarkMap/Len5Nested/Value-20         2773639               387.1 ns/op           320 B/op          1 allocs/op
BenchmarkMap/Len5Nested/KeyValue-20      3093283               404.7 ns/op           320 B/op          1 allocs/op
BenchmarkMap/Len5Nested/AsMap-20         8646662               161.1 ns/op           320 B/op          1 allocs/op
BenchmarkMap/Len5Nested/String-20        2785362               499.1 ns/op           208 B/op          1 allocs/op
BenchmarkMap/Len5Nested/Emit-20          2882395               375.2 ns/op           208 B/op          1 allocs/op
```

```
$ go test -run=^$ -bench=BenchmarkHashValueMap
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/attribute
cpu: 13th Gen Intel(R) Core(TM) i7-13800H
BenchmarkHashValueMap/Len2-20            7589696               133.0 ns/op            80 B/op          1 allocs/op
BenchmarkHashValueMap/Len5-20            6254871               205.7 ns/op            80 B/op          1 allocs/op
BenchmarkHashValueMap/Len8Nested-20      2726431               424.1 ns/op            80 B/op          1 allocs/op
```
2026-06-12 10:07:11 +02:00
David Ashpole 6e3d3448fc Add WithUnsafeAttributes to support no-copy dynamic metric API calls (#8251)
Split from https://github.com/open-telemetry/opentelemetry-go/pull/8179

Part of https://github.com/open-telemetry/opentelemetry-go/issues/7743

This just defines the new WithUnsafeAttributes option, but converts it
to a set, and leaves the optimization of that path for a follow-up.

Benchmarks

```
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/sdk/metric
cpu: Intel(R) Xeon(R) CPU @ 2.20GHz
                                                                              │   out.txt    │
                                                                              │    sec/op    │
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributeSet-24        65.18n ± 25%
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributes-24          61.96n ± 19%
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithUnsafeAttributes-24    199.9n ± 22%
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-24            231.6n ±  9%
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributes-24              288.0n ± 14%
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithUnsafeAttributes-24        271.9n ±  6%
EndToEndCounterAdd/NoFilter/Attributes/1/Naive/WithAttributes-24                352.7n ± 14%
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributeSet-24        68.73n ± 22%
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributes-24          61.04n ± 22%
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithUnsafeAttributes-24    754.0n ± 25%
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributeSet-24            637.3n ± 21%
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributes-24              908.2n ± 28%
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithUnsafeAttributes-24        901.7n ± 14%
EndToEndCounterAdd/NoFilter/Attributes/5/Naive/WithAttributes-24                1.062µ ± 15%
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributeSet-24       53.82n ± 28%
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributes-24         65.82n ±  5%
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithUnsafeAttributes-24   1.717µ ± 14%
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributeSet-24           1.183µ ± 13%
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributes-24             1.803µ ± 20%
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithUnsafeAttributes-24       2.050µ ± 15%
EndToEndCounterAdd/NoFilter/Attributes/10/Naive/WithAttributes-24               2.082µ ± 33%
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributeSet-24        204.1n ± 14%
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributes-24          214.5n ± 28%
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithUnsafeAttributes-24    433.9n ± 18%
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributeSet-24            412.6n ± 10%
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributes-24              464.1n ± 18%
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithUnsafeAttributes-24        471.4n ± 13%
EndToEndCounterAdd/Filtered/Attributes/1/Naive/WithAttributes-24                558.5n ± 19%
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributeSet-24        772.4n ± 14%
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributes-24          748.7n ±  9%
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithUnsafeAttributes-24    1.453µ ± 17%
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributeSet-24            1.501µ ± 19%
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributes-24              1.489µ ±  9%
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithUnsafeAttributes-24        1.608µ ± 24%
EndToEndCounterAdd/Filtered/Attributes/5/Naive/WithAttributes-24                1.671µ ± 14%
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributeSet-24       1.324µ ± 18%
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributes-24         1.463µ ± 17%
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithUnsafeAttributes-24   2.833µ ± 33%
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributeSet-24           2.635µ ±  9%
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributes-24             3.125µ ± 14%
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithUnsafeAttributes-24       2.685µ ± 24%
EndToEndCounterAdd/Filtered/Attributes/10/Naive/WithAttributes-24               3.404µ ±  8%
geomean                                                                         610.5n

                                                                              │    out.txt     │
                                                                              │      B/op      │
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributeSet-24          0.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributes-24            0.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithUnsafeAttributes-24      128.0 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-24              88.00 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributes-24                152.0 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithUnsafeAttributes-24          128.0 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/1/Naive/WithAttributes-24                  232.0 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributeSet-24          0.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributes-24            0.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithUnsafeAttributes-24      640.0 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributeSet-24              344.0 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributes-24                664.0 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithUnsafeAttributes-24          640.0 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Naive/WithAttributes-24                 1000.0 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributeSet-24         0.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributes-24           0.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithUnsafeAttributes-24   1.375Ki ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributeSet-24             729.0 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributes-24             1.399Ki ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithUnsafeAttributes-24       1.376Ki ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Naive/WithAttributes-24               2.102Ki ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributeSet-24          64.00 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributes-24            64.00 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithUnsafeAttributes-24      192.0 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributeSet-24              152.0 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributes-24                216.0 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithUnsafeAttributes-24          192.0 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Naive/WithAttributes-24                  296.0 ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributeSet-24          576.0 ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributes-24            576.0 ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithUnsafeAttributes-24    1.188Ki ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributeSet-24              921.0 ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributes-24              1.212Ki ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithUnsafeAttributes-24        1.188Ki ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Naive/WithAttributes-24                1.539Ki ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributeSet-24       1.312Ki ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributes-24         1.312Ki ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithUnsafeAttributes-24   2.688Ki ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributeSet-24           2.025Ki ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributes-24             2.713Ki ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithUnsafeAttributes-24       2.689Ki ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Naive/WithAttributes-24               3.414Ki ± 0%
geomean                                                                                      ¹
¹ summaries must be >0 to compute geomean

                                                                              │   out.txt    │
                                                                              │  allocs/op   │
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributeSet-24        0.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributes-24          0.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithUnsafeAttributes-24    2.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-24            2.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributes-24              3.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithUnsafeAttributes-24        2.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/1/Naive/WithAttributes-24                5.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributeSet-24        0.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributes-24          0.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithUnsafeAttributes-24    2.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributeSet-24            2.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributes-24              3.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithUnsafeAttributes-24        2.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/5/Naive/WithAttributes-24                5.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributeSet-24       0.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributes-24         0.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithUnsafeAttributes-24   2.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributeSet-24           2.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributes-24             3.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithUnsafeAttributes-24       2.000 ± 0%
EndToEndCounterAdd/NoFilter/Attributes/10/Naive/WithAttributes-24               5.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributeSet-24        1.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributes-24          1.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithUnsafeAttributes-24    3.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributeSet-24            3.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributes-24              4.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithUnsafeAttributes-24        3.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/1/Naive/WithAttributes-24                6.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributeSet-24        2.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributes-24          2.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithUnsafeAttributes-24    4.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributeSet-24            4.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributes-24              5.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithUnsafeAttributes-24        4.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/5/Naive/WithAttributes-24                7.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributeSet-24       2.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributes-24         2.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithUnsafeAttributes-24   4.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributeSet-24           4.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributes-24             5.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithUnsafeAttributes-24       4.000 ± 0%
EndToEndCounterAdd/Filtered/Attributes/10/Naive/WithAttributes-24               7.000 ± 0%
geomean                                                                                    ¹
¹ summaries must be >0 to compute geomean
```
2026-06-11 14:33:54 -04:00
David Ashpole 35e8690c4b Document that WithExemplarFilter(nil) is not supported (#8392)
Fixes #8240
2026-06-10 11:13:58 -04:00
David Ashpole 0a1d12fb66 fix: clear stale histogram fields on datapoint reuse (#8403)
Fixes #8399

---------

Co-authored-by: Robert Pająk <pellared@hotmail.com>
2026-06-10 09:57:18 -04:00
David Ashpole 0eb89a5210 Fix memory leak in exemplar reservoir by storing SpanContext instead of Context (#8389)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/8337

Co-authored-by: Robert Pająk <pellared@hotmail.com>
2026-06-10 09:37:37 -04:00
Kevin Gao 4714a4fbd5 sdk/metric: reuse cumulative-histogram Collect buffers to reduce heap usage (#8428)
`cumulativeHistogram.collect()` was allocating a fresh `[]uint64` for
every series' `BucketCounts` (and a fresh `Exemplars` slice) on every
cycle. The delta path already reused these buffers; the cumulative path
now follows the same pattern: pre-size `h.DataPoints`, write in place so
`loadCountsInto` and `collectExemplars` reuse the existing slot's
capacity, and explicitly clear `Sum`/`Min`/`Max` since `sync.Map`
iteration order isn't stable across cycles.

Steady-state allocation at high cardinality drops by ~98% (187 MiB ->
3.8 MiB per cycle at 100k series).

Fixes #8427

---------

Signed-off-by: Kevin Gao <kevin@sierra.ai>
Co-authored-by: David Ashpole <dashpole@google.com>
Co-authored-by: Robert Pająk <pellared@hotmail.com>
2026-06-09 16:27:16 -04:00
David Ashpole 8bc4068efe fix: off-by-one bug for FixedSizeReservoir (#8309)
While working on
https://github.com/open-telemetry/opentelemetry-go/pull/8306, I found an
off-by-one error.

Reset was setting `r.next` to `k`, and then calling advance(), which
meant `r.next` was always at least `k+1`.

The first `k` exemplars are unconditionally stored during the "fill"
phase. Count is incremented at the end of the Offer call, so the `k+1`th
exemplar was **never** stored because `r.next` is `k` when that Offer
call is being evaluated.

---------

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
2026-06-09 15:53:20 -04:00
David Ashpole 41d99e7eb1 Cleanup limitedSyncMap, and add tests (#8302)
Making some cleanups to the existing limitedSyncMap before
https://github.com/open-telemetry/opentelemetry-go/pull/8276.

### Changes

limitedSyncMap uses generics to eliminate the need to use type
assertions in the aggregators themselves, and moves all type assertions
to be internal to the limitedSyncMap implementation

Testing

* Added two new tests for limitedSyncMap: a ConcurrentSafe test, and a
test that ensures the overflow limit is correctly enforced after it is
Cleared.

Co-authored-by: Robert Pająk <pellared@hotmail.com>
Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
2026-06-09 14:03:38 -04:00
Robert Pająk 3a1412d2b3 sdk/trace: avoid logging exporter endpoint configuration (#8438)
Prevent internal trace exporter logging from including endpoint
configuration.

`MarshalLog` now keeps the existing log shape where practical, but logs
exporter/client type strings instead of recursively serializing exporter
and client internals. OTLP trace HTTP/gRPC and Zipkin exporter log
payloads no longer include endpoint URLs, embedded credentials, query
tokens, internal hostnames, or insecure transport configuration.

## Changes

- Stop recursive logging of trace exporter/client config from
`sdk/trace` span processors and `otlptrace.Exporter`.
- Remove endpoint/URL fields from OTLP trace HTTP/gRPC and Zipkin
`MarshalLog` output.
- Add regression coverage for credential-bearing endpoints not appearing
in internal log output.
2026-06-09 19:09:30 +02:00
renovate[bot] 58f767a448 fix(deps): update golang.org/x (#8437) 2026-06-08 16:25:23 +02:00
Ilya Kiselev c221f3e856 sdk/metric/internal/x: generate x package from x component template (#8397)
Closes #7381

Signed-off-by: Ilya Kiselev <Kis-Ilya-A@yandex.ru>
2026-06-03 15:05:06 +02:00
Robert Pająk b62d92831b Release 1.44.0 (#8376)
### Added

- Add `ByteSlice` and `ByteSliceValue` functions for new `BYTESLICE`
attribute type in `go.opentelemetry.io/otel/attribute`. (#7948)
- Apply attribute value limit to the `KindBytes` attribute type in
`go.opentelemetry.io/otel/sdk/log`. (#7990)
- Apply attribute value limit to the `BYTESLICE` attribute type in
`go.opentelemetry.io/otel/sdk/trace`. (#7990)
- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/trace`.
(#8153)
- Support `BYTESLICE` attributes in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace`. (#8153)
- Support `BYTESLICE` attributes in
`go.opentelemetry.io/otel/exporters/otlp/otlplog`. (#8153)
- Support `BYTESLICE` attributes in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#8153)
- Support `BYTESLICE` attributes in
`go.opentelemetry.io/otel/exporters/zipkin`. (#8153)
- Add `String` method for `Value` type in
`go.opentelemetry.io/otel/attribute`. (#8142)
- Add `Slice` and `SliceValue` functions for new `SLICE` attribute type
in `go.opentelemetry.io/otel/attribute`. (#8166)
- Support `SLICE` attributes in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace`. (#8216)
- Support `SLICE` attributes in
`go.opentelemetry.io/otel/exporters/otlp/otlplog`. (#8216)
- Support `SLICE` attributes in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#8216)
- Support `SLICE` attributes in
`go.opentelemetry.io/otel/exporters/zipkin`. (#8216)
- Apply `AttributeValueLengthLimit` to `attribute.SLICE` type attribute
values in `go.opentelemetry.io/otel/sdk/trace`, recursively truncating
contained string values. (#8217)
- Add `Error` field on `Record` type in
`go.opentelemetry.io/otel/log/logtest`. (#8148)
- Add `WithMaxRequestSize` option in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`.
(#8157)
- Add `WithMaxRequestSize` option in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`.
(#8157)
- Add `WithMaxRequestSize` option in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`.
(#8157)
- Add `WithMaxRequestSize` option in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
(#8157)
- Add `WithMaxRequestSize` option in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#8157)
- Add `WithMaxRequestSize` option in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8157)
- Add `Settable` to `go.opentelemetry.io/otel/metric/x` to allow reusing
attribute options. (#8178)
- Add experimental support for splitting metric data across multiple
batches in `go.opentelemetry.io/otel/sdk/metric`.
Set `OTEL_GO_X_METRIC_EXPORT_BATCH_SIZE=<max_size>` to enable for all
periodic readers.
See `go.opentelemetry.io/otel/sdk/metric/internal/x` for feature
documentation. (#8071)
- Add experimental self-observability metrics in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`.
  Enable with `OTEL_GO_X_SELF_OBSERVABILITY=true` environment variable.
See
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x`
for feature documentation. (#8192)
- Add experimental self-observability metrics in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
  Enable with `OTEL_GO_X_SELF_OBSERVABILITY=true` environment variable.
See
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x`
for feature documentation. (#8194)
- Add experimental self-observability metrics in
`go.opentelemetry.io/otel/exporters/stdout/stdoutlog`.
  Enable with `OTEL_GO_X_SELF_OBSERVABILITY=true` environment variable.
See `go.opentelemetry.io/otel/stdout/stdoutlog/internal/x` for feature
documentation. (#8263)
- Add `WithDefaultAttributes` to `go.opentelemetry.io/otel/metric/x` to
support setting default attributes on instruments. (#8135)
- Add `go.opentelemetry.io/otel/semconv/v1.41.0` package.
The package contains semantic conventions from the `v1.41.0` version of
the OpenTelemetry Semantic Conventions.
See the [migration documentation](./semconv/v1.41.0/MIGRATION.md) for
information on how to upgrade from
`go.opentelemetry.io/otel/semconv/v1.40.0`. (#8324)
- Add Observable variants of instruments to
`go.opentelemetry.io/otel/semconv/v1.41.0` package. (#8350)
- Generate explicit histogram bucket boundaries from weaver
configuration for HTTP and RPC duration instruments in
`go.opentelemetry.io/otel/semconv/v1.41.0`. (#8002)

### Changed

- ⚠️ **Breaking Change:** `go.opentelemetry.io/otel/sdk/metric` now
applies a default cardinality limit of 2000 to comply with the Metrics
SDK specification recommendation.
New attribute sets are dropped when the cardinality limit is reached.
The measurement of these sets are aggregated into a special attribute
set containing `attribute.Bool("otel.metric.overflow", true)`.
  This can break users who relied on the previous unlimited default.
Set `WithCardinalityLimit(0)` or the deprecated
`OTEL_GO_X_CARDINALITY_LIMIT=0` environment variable to preserve
unlimited cardinality.
Note that support for `OTEL_GO_X_CARDINALITY_LIMIT` may be removed in a
future release. (#8247)
- `ErrorType` in `go.opentelemetry.io/otel/semconv` now unwraps errors
created with `fmt.Errorf` when deriving the `error.type` attribute.
(#8133)
- `go.opentelemetry.io/otel/sdk/log` now unwraps error chains created
with `fmt.Errorf` when deriving the `error.type` attribute from errors
on log records. (#8133)
- `Set.MarshalLog` method in `go.opentelemetry.io/otel/attribute` now
uses `Value.String` formatting following the [OpenTelemetry AnyValue
representation for non-OTLP
protocols](https://opentelemetry.io/docs/specs/otel/common/#anyvalue).
(#8169)
- Optimize `go.opentelemetry.io/otel/sdk/metric` to return a drop
reservoir and short-circuit `Offer` calls to the exemplar reservoir when
`exemplar.AlwaysOffFilter` is configured. (#8211) (#8267)
- Optimize `go.opentelemetry.io/otel/sdk/metric` to return a drop
reservoir for asynchronous instruments when `exemplar.TraceBasedFilter`
is configured. (#8286)

### Deprecated

- Deprecate `Value.Emit` method in `go.opentelemetry.io/otel/attribute`.
  Use `Value.String` instead. (#8176)

### Fixed

- Limit OTLP request size to 64 MiB by default in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`.
The limit applies before compression, oversized requests are treated as
non-retryable errors, and the limit can be configured with the new
`WithMaxRequestSize` option. (#8157, #8365)
- Limit OTLP request size to 64 MiB by default in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`.
The limit applies before compression, oversized requests are treated as
non-retryable errors, and the limit can be configured with the new
`WithMaxRequestSize` option. (#8157, #8365)
- Limit OTLP request size to 64 MiB by default in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`.
The limit applies before compression, oversized requests are treated as
non-retryable errors, and the limit can be configured with the new
`WithMaxRequestSize` option. (#8157, #8365)
- Limit OTLP request size to 64 MiB by default in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
The limit applies before compression, oversized requests are treated as
non-retryable errors, and the limit can be configured with the new
`WithMaxRequestSize` option. (#8157, #8365)
- Limit OTLP request size to 64 MiB by default in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`.
The limit applies before compression, oversized requests are treated as
non-retryable errors, and the limit can be configured with the new
`WithMaxRequestSize` option. (#8157, #8365)
- Limit OTLP request size to 64 MiB by default in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`.
The limit applies before compression, oversized requests are treated as
non-retryable errors, and the limit can be configured with the new
`WithMaxRequestSize` option. (#8157, #8365)
- Fix gzipped request body replay on redirect in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
(#8135)
- Fix gzipped request body replay on redirect in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8152)
- `go.opentelemetry.io/otel/exporters/prometheus` now uses
`Value.String` formatting for label values following the [OpenTelemetry
AnyValue representation for non-OTLP
protocols](https://opentelemetry.io/docs/specs/otel/common/#anyvalue).
(#8170)
- Propagate errors from the exporter when calling `Shutdown` on
`BatchSpanProcessor` in `go.opentelemetry.io/otel/sdk/trace`. (#8197)
- Fix stale status code reporting on self-observability metrics in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` and
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8226)
- Fix a concurrent `Collect` data race and potential panic in
`go.opentelemetry.io/otel/exporters/prometheus` when
`WithResourceAsConstantLabels` option is used. (#8227)
- Fix race condition in `FixedSizeReservoir` in
`go.opentelemetry.io/otel/sdk/metric/exemplar` by reverting #7447.
(#8249)
- Fix `FixedSizeReservoir` in
`go.opentelemetry.io/otel/sdk/metric/exemplar` to safely handle zero
size.
A capacity check in the constructor initializes the reservoir safely and
skips initialization for zero-cap; early returns in `Offer()` and
`Collect()` ensure no-op behavior. (#8295)
- Fix counting of spans and logs in self-observability metrics in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`,
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`,
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`, and
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8254)
- Drop conflicting scope attributes named `name`, `version`, or
`schema_url` from metric labels in
`go.opentelemetry.io/otel/exporters/prometheus`, preserving the
dedicated `otel_scope_name`, `otel_scope_version`, and
`otel_scope_schema_url` labels. (#8264)
- Close schema files opened by `ParseFile` in
`go.opentelemetry.io/otel/schema/v1.0` and
`go.opentelemetry.io/otel/schema/v1.1`.
([GHSA-995v-fvrw-c78m](https://github.com/open-telemetry/opentelemetry-go/security/advisories/GHSA-995v-fvrw-c78m))
- Enforce the 8192-byte baggage size limit during extraction/parsing,
changing behavior when the limit is exceeded in
`go.opentelemetry.io/otel/baggage` and
`go.opentelemetry.io/otel/propagation`. (#8222)
- Fix `go.opentelemetry.io/otel/semconv/v1.41.0` to include `Attr*`
helper methods for required attributes on observable instruments.
(#8361)
- Limit baggage extraction error reporting in
`go.opentelemetry.io/otel/propagation` to prevent malformed or oversized
baggage headers from flooding logs.
([GHSA-5wrp-cwcj-q835](https://github.com/open-telemetry/opentelemetry-go/security/advisories/GHSA-5wrp-cwcj-q835))
2026-05-27 18:42:37 +02:00
Ali Asghar d0b6cbdff5 sdk/metric: document unit-sensitivity of DefaultAggregationSelector (#8224)
Fixes #5891

---------

Signed-off-by: Ali <alliasgher123@gmail.com>
Co-authored-by: Robert Pająk <pellared@hotmail.com>
2026-05-26 18:10:50 +02:00
Vansh Agarwal a51ddb125a fix: handle FixedSizeReservoir size=0 without panic (#8295)
Fixes #8232

- Added guard for size=0 in FixedSizeReservoir
- Prevents panic during Offer/update
- Added test to ensure no panic occurs

---------

Co-authored-by: David Ashpole <dashpole@google.com>
2026-05-22 13:32:33 +02:00
David Ashpole 15063b23a1 Disable exemplar reservoir for asynchronous instruments by default (#8286)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/8285

Asynchronous instruments do not accept context, so the default
TraceBased exemplar filter can never record an exemplar. Use the
DropReservoir when the TraceBased exemplar filter is used, similar to
https://github.com/open-telemetry/opentelemetry-go/pull/8211.


### Benchmarks

Since callbacks are made as part of collect, there is a significant
baseline overhead from collection included in the benchmark.

```
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/sdk/metric
cpu: AMD EPYC 7B12
                                          │   main.txt   │              new.txt               │
                                          │    sec/op    │   sec/op     vs base               │
AsyncMeasureNewAttributeSet/AlwaysOn-24     3.662µ ± 13%   3.735µ ± 8%        ~ (p=0.699 n=6)
AsyncMeasureNewAttributeSet/TraceBased-24   3.586µ ± 10%   1.195µ ± 5%  -66.69% (p=0.002 n=6)
geomean                                     3.623µ         2.112µ       -41.70%

                                          │   main.txt   │               new.txt               │
                                          │     B/op     │     B/op      vs base               │
AsyncMeasureNewAttributeSet/AlwaysOn-24     3.344Ki ± 0%   3.343Ki ± 0%        ~ (p=0.571 n=6)
AsyncMeasureNewAttributeSet/TraceBased-24    3424.5 ± 0%     592.0 ± 0%  -82.71% (p=0.002 n=6)
geomean                                     3.344Ki        1.390Ki       -58.43%

                                          │  main.txt  │               new.txt               │
                                          │ allocs/op  │ allocs/op   vs base                 │
AsyncMeasureNewAttributeSet/AlwaysOn-24     16.00 ± 0%   16.00 ± 0%        ~ (p=1.000 n=6) ¹
AsyncMeasureNewAttributeSet/TraceBased-24   16.00 ± 0%   12.00 ± 0%  -25.00% (p=0.002 n=6)
geomean                                     16.00        13.86       -13.40%
¹ all samples are equal
```
2026-05-22 09:57:06 +02:00
Dipanshu singh 39d0370d0f docs: clarify that View attribute filters do not apply to Exemplars (#8339)
This PR updates the documentation to clarify how View attribute filters
interact with Exemplars.

Currently, it's not very obvious that when a View filters out certain
attributes, those dropped attributes might still appear on Exemplars.
According to the OTel specification, Exemplars retain the original
measurement attributes regardless of the View or aggregation
configuration.

This behavior can be confusing for users, so I've added a brief note to
the godocs for View, AttributeFilter, and the package-level doc.go to
make this explicit (similar to the recent documentation updates in the
.NET SDK).

fixes #8330

---------

Co-authored-by: Robert Pająk <pellared@hotmail.com>
2026-05-22 09:28:20 +02:00
Matthieu MOREL f6c8baa895 Fix receiver-naming issues from revive (#8093)
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2026-05-22 09:01:15 +02:00
mujib77 6ceeae804a Fix Extrema failure test (#8338)
The Extrema failure test referenced minA/minB variables that no longer
exist, causing tests_fail builds to fail.
2026-05-22 08:49:57 +02:00
renovate[bot] 4fb7134cdd fix(deps): update golang.org/x (#8363) 2026-05-22 07:45:50 +02:00
Tyler Yahn 442cdbdd94 Generate and upgrade to semconv/v1.41.0 (#8324)
Fix https://github.com/open-telemetry/opentelemetry-go/issues/8299

Relevant upstream v1.41.0 release notes:

> ### 🛑 Breaking changes 🛑
> 
> - `graphql`: Change `graphql.document` attribute requirement level
from Recommended to Opt-In due to sensitive data, cardinality, and size
concerns
([#2985](https://github.com/open-telemetry/semantic-conventions/issues/2985))
> - `process`: Move process.executable to its own entity.
([#3535](https://github.com/open-telemetry/semantic-conventions/issues/3535))
> - `process`: Update requirement levels for process attributes to
ensure consistent identification and description across platforms.
([#864](https://github.com/open-telemetry/semantic-conventions/issues/864))
> - `rpc`: Remove `client.address` and `client.port` attributes from RPC
server spans.
([#3487](https://github.com/open-telemetry/semantic-conventions/issues/3487),
[#3488](https://github.com/open-telemetry/semantic-conventions/issues/3488))
> 
> ### 💡 Enhancements 💡
> 
> - `Go`: Add opt-in go.memory.gc.pause.duration histogram metric.
([#3353](https://github.com/open-telemetry/semantic-conventions/issues/3353))
> - `deployment`: Stabilize `deployment.environment.name` attribute.
([#3339](https://github.com/open-telemetry/semantic-conventions/issues/3339))
> - `deployment`: Add enum values for `deployment.environment.name`
attribute.
([#2910](https://github.com/open-telemetry/semantic-conventions/issues/2910))
> - `go`: Add the go.cpu.time opt-in metric, and add
go.cpu.detailed_state and go.memory.detailed_type attributes to CPU and
memory metrics respectively with wildcard values.
([#3354](https://github.com/open-telemetry/semantic-conventions/issues/3354))
> - `go`: Add the opt-in go.memory.gc.cycles metric.
([#3353](https://github.com/open-telemetry/semantic-conventions/issues/3353))
> - `telemetry`: Promote `telemetry.distro.name` and
`telemetry.distro.version` attributes to 'stable'.
([#3650](https://github.com/open-telemetry/semantic-conventions/issues/3650))

This PR also:
- fixes semconv migration generation to ignore unexported declarations
when computing renames/removals
- upgrades repo imports, depguard, docs, templates, and schema URL
expectations to `go.opentelemetry.io/otel/semconv/v1.41.0`
- adds missing generated-file headers to semconvkit templates and
regenerates the affected `v1.41.0` files via `TAG="v1.41.0" make
semconv-generate`

---------

Co-authored-by: David Ashpole <dashpole@google.com>
2026-05-14 14:06:05 -04:00
Mikhail Mazurskiy c45d9a3301 fix: clear cached objects to enable GC (#8233)
There is a the same problem in the semconv package, but I'm not sure how
to regenerate those files.

Also,
[`ResourceMetrics`](https://github.com/open-telemetry/opentelemetry-go/blob/bec9f66b45ae1e679212285467572d132b627ff4/exporters/prometheus/exporter.go#L181)
should be cleared too, but it's not. I wonder how things work today
because this object has a slice that keeps growing, doesn't it? I
decided not to touch it for now.

`sdk/metric.BenchmarkEndToEndCounterAdd` shows no change:

```
goos: darwin
goarch: arm64
pkg: go.opentelemetry.io/otel/sdk/metric
cpu: Apple M4 Max
                                                                          │  before.txt  │              after.txt               │
                                                                          │    sec/op    │    sec/op     vs base                │
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributeSet-16    64.12n ± ∞ ¹   63.45n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributes-16      62.82n ± ∞ ¹   63.04n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-16        90.09n ± ∞ ¹   81.45n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributes-16          90.15n ± ∞ ¹   92.02n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/1/Naive/WithAttributes-16            102.2n ± ∞ ¹   102.4n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributeSet-16    61.13n ± ∞ ¹   62.71n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributes-16      59.10n ± ∞ ¹   61.69n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributeSet-16        144.4n ± ∞ ¹   149.5n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributes-16          223.0n ± ∞ ¹   223.3n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Naive/WithAttributes-16            277.8n ± ∞ ¹   277.2n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributeSet-16   62.41n ± ∞ ¹   59.82n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributes-16     65.09n ± ∞ ¹   65.49n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributeSet-16       262.4n ± ∞ ¹   270.1n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributes-16         392.8n ± ∞ ¹   418.6n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Naive/WithAttributes-16           505.8n ± ∞ ¹   523.3n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributeSet-16    77.02n ± ∞ ¹   77.29n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributes-16      77.35n ± ∞ ¹   77.34n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributeSet-16        94.47n ± ∞ ¹   97.93n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributes-16          107.8n ± ∞ ¹   110.4n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Naive/WithAttributes-16            121.4n ± ∞ ¹   121.6n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributeSet-16    172.4n ± ∞ ¹   169.0n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributes-16      165.7n ± ∞ ¹   167.6n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributeSet-16        291.1n ± ∞ ¹   294.8n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributes-16          355.7n ± ∞ ¹   358.8n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Naive/WithAttributes-16            408.4n ± ∞ ¹   402.2n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributeSet-16   321.4n ± ∞ ¹   322.3n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributes-16     315.3n ± ∞ ¹   314.9n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributeSet-16       557.3n ± ∞ ¹   576.7n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributes-16         685.9n ± ∞ ¹   712.2n ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Naive/WithAttributes-16           796.0n ± ∞ ¹   809.4n ± ∞ ¹       ~ (p=1.000 n=1) ²
geomean                                                                     168.5n         170.0n        +0.87%
¹ need >= 6 samples for confidence interval at level 0.95
² need >= 4 samples to detect a difference at alpha level 0.05

                                                                          │  before.txt   │               after.txt               │
                                                                          │     B/op      │     B/op       vs base                │
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributeSet-16      0.000 ± ∞ ¹     0.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributes-16        0.000 ± ∞ ¹     0.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-16          88.00 ± ∞ ¹     88.00 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributes-16            152.0 ± ∞ ¹     152.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/1/Naive/WithAttributes-16              232.0 ± ∞ ¹     232.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributeSet-16      0.000 ± ∞ ¹     0.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributes-16        0.000 ± ∞ ¹     0.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributeSet-16          344.0 ± ∞ ¹     344.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributes-16            665.0 ± ∞ ¹     665.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Naive/WithAttributes-16             1000.0 ± ∞ ¹    1000.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributeSet-16     0.000 ± ∞ ¹     0.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributes-16       0.000 ± ∞ ¹     0.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributeSet-16         729.0 ± ∞ ¹     729.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributes-16         1.399Ki ± ∞ ¹   1.400Ki ± ∞ ¹       ~ (p=1.000 n=1) ³
EndToEndCounterAdd/NoFilter/Attributes/10/Naive/WithAttributes-16           2.102Ki ± ∞ ¹   2.102Ki ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributeSet-16      64.00 ± ∞ ¹     64.00 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributes-16        64.00 ± ∞ ¹     64.00 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributeSet-16          152.0 ± ∞ ¹     152.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributes-16            216.0 ± ∞ ¹     216.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Naive/WithAttributes-16              296.0 ± ∞ ¹     296.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributeSet-16      576.0 ± ∞ ¹     576.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributes-16        576.0 ± ∞ ¹     576.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributeSet-16          921.0 ± ∞ ¹     921.0 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributes-16          1.212Ki ± ∞ ¹   1.212Ki ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Naive/WithAttributes-16            1.539Ki ± ∞ ¹   1.539Ki ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributeSet-16   1.312Ki ± ∞ ¹   1.312Ki ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributes-16     1.312Ki ± ∞ ¹   1.312Ki ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributeSet-16       2.025Ki ± ∞ ¹   2.025Ki ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributes-16         2.713Ki ± ∞ ¹   2.714Ki ± ∞ ¹       ~ (p=1.000 n=1) ³
EndToEndCounterAdd/Filtered/Attributes/10/Naive/WithAttributes-16           3.414Ki ± ∞ ¹   3.414Ki ± ∞ ¹       ~ (p=1.000 n=1) ²
geomean                                                                                 ⁴                  +0.00%               ⁴
¹ need >= 6 samples for confidence interval at level 0.95
² all samples are equal
³ need >= 4 samples to detect a difference at alpha level 0.05
⁴ summaries must be >0 to compute geomean

                                                                          │ before.txt  │              after.txt              │
                                                                          │  allocs/op  │  allocs/op   vs base                │
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributeSet-16    0.000 ± ∞ ¹   0.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributes-16      0.000 ± ∞ ¹   0.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-16        2.000 ± ∞ ¹   2.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributes-16          3.000 ± ∞ ¹   3.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/1/Naive/WithAttributes-16            5.000 ± ∞ ¹   5.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributeSet-16    0.000 ± ∞ ¹   0.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributes-16      0.000 ± ∞ ¹   0.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributeSet-16        2.000 ± ∞ ¹   2.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributes-16          3.000 ± ∞ ¹   3.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/5/Naive/WithAttributes-16            5.000 ± ∞ ¹   5.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributeSet-16   0.000 ± ∞ ¹   0.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributes-16     0.000 ± ∞ ¹   0.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributeSet-16       2.000 ± ∞ ¹   2.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributes-16         3.000 ± ∞ ¹   3.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/NoFilter/Attributes/10/Naive/WithAttributes-16           5.000 ± ∞ ¹   5.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributeSet-16    1.000 ± ∞ ¹   1.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributes-16      1.000 ± ∞ ¹   1.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributeSet-16        3.000 ± ∞ ¹   3.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributes-16          4.000 ± ∞ ¹   4.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/1/Naive/WithAttributes-16            6.000 ± ∞ ¹   6.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributeSet-16    2.000 ± ∞ ¹   2.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributes-16      2.000 ± ∞ ¹   2.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributeSet-16        4.000 ± ∞ ¹   4.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributes-16          5.000 ± ∞ ¹   5.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/5/Naive/WithAttributes-16            7.000 ± ∞ ¹   7.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributeSet-16   2.000 ± ∞ ¹   2.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributes-16     2.000 ± ∞ ¹   2.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributeSet-16       4.000 ± ∞ ¹   4.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributes-16         5.000 ± ∞ ¹   5.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
EndToEndCounterAdd/Filtered/Attributes/10/Naive/WithAttributes-16           7.000 ± ∞ ¹   7.000 ± ∞ ¹       ~ (p=1.000 n=1) ²
geomean                                                                               ³                +0.00%               ³
¹ need >= 6 samples for confidence interval at level 0.95
² all samples are equal
³ summaries must be >0 to compute geomean
```

---------

Co-authored-by: David Ashpole <dashpole@google.com>
2026-05-14 13:49:51 -04:00
Sam Xie 816ac54d22 Fix benchmark ci (#8282)
Benchmark result:
https://codspeed.io/open-telemetry/opentelemetry-go/branches/XSAM%3Afix-benchmark-ci

The benchmark action is no longer compliant with 'Too many benchmarks in
a single upload'.
https://github.com/open-telemetry/opentelemetry-go/runs/73911767952

We can ignore the warning "Performance Regression: -80%" for now, as we
don't have a proper benchmark baseline yet.

---------

Co-authored-by: Robert Pająk <pellared@hotmail.com>
2026-05-08 17:39:33 -07:00
renovate[bot] cf2a4a180f chore(deps): update module mvdan.cc/gofumpt to v0.10.0 (#8304)
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [mvdan.cc/gofumpt](https://redirect.github.com/mvdan/gofumpt) |
`v0.9.2` → `v0.10.0` |
![age](https://developer.mend.io/api/mc/badges/age/go/mvdan.cc%2fgofumpt/v0.10.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/go/mvdan.cc%2fgofumpt/v0.9.2/v0.10.0?slim=true)
|

---

### Release Notes

<details>
<summary>mvdan/gofumpt (mvdan.cc/gofumpt)</summary>

###
[`v0.10.0`](https://redirect.github.com/mvdan/gofumpt/blob/HEAD/CHANGELOG.md#v0100---2026-05-04)

[Compare
Source](https://redirect.github.com/mvdan/gofumpt/compare/v0.9.2...v0.10.0)

This release is based on Go 1.26's gofmt, and requires Go 1.25 or later.

A new rule is introduced to drop unnecessary parentheses around
expressions
where the inner expression is unambiguous on its own, such as `f((3))`.
Parentheses are kept where they are useful, such as on binary
expressions. See
[#&#8203;44](https://redirect.github.com/mvdan/gofumpt/issues/44).

A new rule is introduced to require multi-line function calls to match
the opening and closing parenthesis in terms of the use of newlines. See
[#&#8203;74](https://redirect.github.com/mvdan/gofumpt/issues/74).

The `-extra` flag now accepts a comma-separated list of rule names to
enable
individual extra rules, rather than enabling all of them at once. See
[#&#8203;339](https://redirect.github.com/mvdan/gofumpt/issues/339).

The following changes are included as well:

- Avoid crashing on `go.mod` files without a `module` directive -
[#&#8203;350](https://redirect.github.com/mvdan/gofumpt/issues/350)
- Avoid failing when an ignored directory cannot be read -
[#&#8203;351](https://redirect.github.com/mvdan/gofumpt/issues/351)
- Avoid prefixing more kinds of commented-out Go code with spaces -
[#&#8203;230](https://redirect.github.com/mvdan/gofumpt/issues/230)
- Avoid prefixing a shebang comment with a space -
[#&#8203;237](https://redirect.github.com/mvdan/gofumpt/issues/237)
- Narrow the newlines on assignments rule to ignore complex cases -
[#&#8203;354](https://redirect.github.com/mvdan/gofumpt/issues/354)
- Fix three bugs which caused a second gofumpt run to make changes -
[#&#8203;132](https://redirect.github.com/mvdan/gofumpt/issues/132),
[#&#8203;345](https://redirect.github.com/mvdan/gofumpt/issues/345)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/open-telemetry/opentelemetry-go).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNTkuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE1OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJTa2lwIENoYW5nZWxvZyIsImRlcGVuZGVuY2llcyJdfQ==-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tyler Yahn <codingalias@gmail.com>
2026-05-08 12:50:12 -07:00
renovate[bot] 25f973a298 fix(deps): update module golang.org/x/sys to v0.44.0 (#8322) 2026-05-08 16:07:36 +02:00
David Ashpole 8bc88510d3 Optimize metrics sdk measurement with AlwaysOff exemplar filter (#8267)
Follow-up to
https://github.com/open-telemetry/opentelemetry-go/pull/8211.

Because the exemplar reservoir is an interface, it can't be in-lined
even when it is a no-op, so it has significant overhead. Skip it when a
drop reservoir is used. This seems to have an overhead of something like
~10ns, which shows up mostly on the precomputed benchmarks.

Benchmarks

```
goarch: amd64
pkg: go.opentelemetry.io/otel/sdk/metric
cpu: Intel(R) Xeon(R) CPU @ 2.20GHz
                                                                          │ benchmark_results_before.txt │     benchmark_results_after.txt     │
                                                                          │            sec/op            │    sec/op     vs base               │
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributeSet-24                    62.65n ± 15%   54.59n ± 12%  -12.88% (p=0.026 n=6)
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributes-24                      63.67n ± 10%   52.21n ±  6%  -17.99% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-24                        238.8n ± 14%   240.0n ± 10%        ~ (p=1.000 n=6)
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributes-24                          220.7n ± 14%   245.6n ± 13%        ~ (p=0.180 n=6)
EndToEndCounterAdd/NoFilter/Attributes/1/Naive/WithAttributes-24                            373.4n ± 26%   352.9n ± 11%        ~ (p=0.240 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributeSet-24                    69.73n ± 16%   48.85n ± 14%  -29.94% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributes-24                      61.32n ±  3%   49.01n ±  5%  -20.08% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributeSet-24                        988.4n ± 48%   759.9n ± 55%  -23.12% (p=0.041 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributes-24                          954.1n ± 90%   667.9n ± 19%  -30.00% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Naive/WithAttributes-24                            1.515µ ± 32%   1.233µ ± 12%        ~ (p=0.240 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributeSet-24                   70.86n ± 11%   53.90n ± 16%  -23.94% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributes-24                     69.20n ± 21%   48.95n ± 12%  -29.27% (p=0.004 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributeSet-24                       1.483µ ± 28%   1.283µ ± 29%        ~ (p=0.310 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributes-24                         1.421µ ± 41%   1.664µ ± 49%        ~ (p=0.394 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Naive/WithAttributes-24                           2.784µ ± 66%   2.109µ ± 19%  -24.23% (p=0.041 n=6)
geomean                                                                                     299.2n         252.1n        -15.75%

```

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-05-01 11:01:46 -04:00
Nesterov Yehor 1a877475b7 Apply attribute value limit for BYTESLICE and KindBytes (#7990)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/7954

Apply the SDK attribute value limit to the new BYTESLICE attribute type.

The limiter has been implemented for trace and log attributes, ensuring
values are truncated according to the configured attribute size limit
(counting each byte as 1).

```
goos: darwin
goarch: arm64
pkg: go.opentelemetry.io/otel/sdk/trace
cpu: Apple M1
BenchmarkSpanLimits/None-8         	  275883	      4062 ns/op	   12448 B/op	      38 allocs/op
BenchmarkSpanLimits/AttributeValueLengthLimit-8         	  266834	      4407 ns/op	   13012 B/op	      47 allocs/op
BenchmarkSpanLimits/AttributeCountLimit-8               	  299941	      4025 ns/op	   11616 B/op	      38 allocs/op
BenchmarkSpanLimits/EventCountLimit-8                   	  305880	      3795 ns/op	   11376 B/op	      35 allocs/op
BenchmarkSpanLimits/LinkCountLimit-8                    	  314924	      4375 ns/op	   10976 B/op	      35 allocs/op
BenchmarkSpanLimits/AttributePerEventCountLimit-8       	  275667	      4125 ns/op	   12448 B/op	      38 allocs/op
BenchmarkSpanLimits/AttributePerLinkCountLimit-8        	  285484	      4022 ns/op	   12448 B/op	      38 allocs/op
PASS
ok  	go.opentelemetry.io/otel/sdk/trace	9.394s
```

---------

Co-authored-by: Robert Pająk <pellared@hotmail.com>
2026-04-29 14:31:40 +02:00
David Ashpole 760898d668 Run benchmarks using Settable for more accurate comparrisons (#8252)
I had avoided using Settable in our benchmarks in
https://github.com/open-telemetry/opentelemetry-go/pull/8178 because I
thought it would introduce a dependency on the x package in our go.mod
file. But it turns out it doesn't (based on
https://github.com/open-telemetry/opentelemetry-go/pull/8251).

This will make it easier to compare WithAttributeSet to
WithUnsafeAttributes.

```
                                                                          │ before_bench.txt │           after_bench.txt            │
                                                                          │      sec/op      │    sec/op      vs base               │
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributeSet-24       60.48n ±   7%    61.83n ± 20%        ~ (p=1.000 n=6)
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributes-24         60.18n ±   9%    65.46n ±  8%        ~ (p=0.065 n=6)
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-24           256.2n ±   6%    272.4n ± 18%   +6.34% (p=0.041 n=6)
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributes-24             311.4n ±  18%    282.4n ± 26%        ~ (p=0.132 n=6)
EndToEndCounterAdd/NoFilter/Attributes/1/Naive/WithAttributes-24               350.4n ±  13%    331.2n ± 45%        ~ (p=0.818 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributeSet-24       64.50n ±  10%    71.22n ± 11%        ~ (p=0.093 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributes-24         61.45n ±  15%    69.04n ± 18%        ~ (p=0.180 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributeSet-24           700.1n ±  36%    776.0n ± 22%        ~ (p=0.394 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributes-24             868.4n ±  14%    738.2n ±  8%  -14.99% (p=0.015 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Naive/WithAttributes-24               974.8n ±  19%   1083.5n ± 10%        ~ (p=0.180 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributeSet-24      67.68n ±  15%    64.42n ± 20%        ~ (p=1.000 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributes-24        67.59n ±   7%    63.41n ± 21%        ~ (p=0.937 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributeSet-24          1.310µ ±  27%    1.323µ ± 20%        ~ (p=0.589 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributes-24            2.077µ ±  34%    1.492µ ± 19%  -28.15% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Naive/WithAttributes-24              2.041µ ±  35%    1.977µ ± 43%        ~ (p=0.485 n=6)
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributeSet-24       208.9n ±   7%    214.3n ± 12%        ~ (p=0.784 n=6)
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributes-24         202.5n ±   6%    201.7n ± 19%        ~ (p=0.937 n=6)
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributeSet-24           417.5n ±   7%    403.9n ± 16%        ~ (p=0.394 n=6)
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributes-24             496.8n ±  13%    383.1n ±  8%  -22.89% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/1/Naive/WithAttributes-24               542.8n ±  54%    521.7n ± 18%        ~ (p=0.589 n=6)
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributeSet-24       732.6n ±  15%    822.3n ± 23%        ~ (p=0.065 n=6)
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributes-24         803.0n ±  12%    813.9n ± 27%        ~ (p=0.818 n=6)
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributeSet-24           1.389µ ±  28%    1.546µ ± 16%        ~ (p=0.699 n=6)
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributes-24             1.756µ ±  12%    1.399µ ± 12%  -20.36% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/5/Naive/WithAttributes-24               1.730µ ±  21%    1.824µ ± 20%        ~ (p=0.818 n=6)
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributeSet-24      5.500µ ± 155%    1.433µ ± 22%  -73.94% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributes-24        2.566µ ±  65%    1.365µ ± 23%  -46.82% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributeSet-24          6.198µ ±  78%    3.188µ ± 14%  -48.57% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributes-24            5.343µ ±  63%    2.963µ ± 10%  -44.55% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/10/Naive/WithAttributes-24              4.293µ ± 279%    3.213µ ± 30%        ~ (p=0.065 n=6)
geomean                                                                        591.5n           518.3n        -12.37%

                                                                          │ before_bench.txt │            after_bench.txt            │
                                                                          │       B/op       │     B/op      vs base                 │
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributeSet-24        0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributes-24          0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-24            88.00 ± 0%       64.00 ± 0%  -27.27% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributes-24             152.00 ± 0%       64.00 ± 0%  -57.89% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/1/Naive/WithAttributes-24                232.0 ± 0%       232.0 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributeSet-24        0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributes-24          0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributeSet-24            344.0 ± 0%       320.0 ± 0%   -6.98% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributes-24              664.0 ± 0%       320.0 ± 0%  -51.81% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Naive/WithAttributes-24               1000.0 ± 0%      1000.0 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributeSet-24       0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributes-24         0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributeSet-24           729.0 ± 0%       705.0 ± 0%   -3.29% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributes-24            1434.0 ± 0%       705.0 ± 0%  -50.84% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Naive/WithAttributes-24             2.102Ki ± 0%     2.102Ki ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributeSet-24        64.00 ± 0%       64.00 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributes-24          64.00 ± 0%       64.00 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributeSet-24            152.0 ± 0%       128.0 ± 0%  -15.79% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributes-24              216.0 ± 0%       128.0 ± 0%  -40.74% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/1/Naive/WithAttributes-24                296.0 ± 0%       296.0 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributeSet-24        576.0 ± 0%       576.0 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributes-24          576.0 ± 0%       576.0 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributeSet-24            921.0 ± 0%       898.0 ± 0%   -2.50% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributes-24             1241.0 ± 0%       897.0 ± 0%  -27.72% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/5/Naive/WithAttributes-24              1.539Ki ± 0%     1.539Ki ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributeSet-24     1.312Ki ± 0%     1.312Ki ± 0%        ~ (p=1.000 n=6)
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributes-24       1.312Ki ± 0%     1.312Ki ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributeSet-24         2.025Ki ± 0%     2.004Ki ± 0%   -1.06% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributes-24           2.713Ki ± 0%     2.002Ki ± 0%  -26.19% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/10/Naive/WithAttributes-24             3.414Ki ± 0%     3.414Ki ± 0%        ~ (p=1.000 n=6)
geomean                                                                                    ²                 -12.74%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                                                          │ before_bench.txt │           after_bench.txt           │
                                                                          │    allocs/op     │ allocs/op   vs base                 │
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributeSet-24        0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/1/Precomputed/WithAttributes-24          0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-24            2.000 ± 0%     1.000 ± 0%  -50.00% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributes-24              3.000 ± 0%     1.000 ± 0%  -66.67% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/1/Naive/WithAttributes-24                5.000 ± 0%     5.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributeSet-24        0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/5/Precomputed/WithAttributes-24          0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributeSet-24            2.000 ± 0%     1.000 ± 0%  -50.00% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributes-24              3.000 ± 0%     1.000 ± 0%  -66.67% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/5/Naive/WithAttributes-24                5.000 ± 0%     5.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributeSet-24       0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/10/Precomputed/WithAttributes-24         0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributeSet-24           2.000 ± 0%     1.000 ± 0%  -50.00% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributes-24             3.000 ± 0%     1.000 ± 0%  -66.67% (p=0.002 n=6)
EndToEndCounterAdd/NoFilter/Attributes/10/Naive/WithAttributes-24               5.000 ± 0%     5.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributeSet-24        1.000 ± 0%     1.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/1/Precomputed/WithAttributes-24          1.000 ± 0%     1.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributeSet-24            3.000 ± 0%     2.000 ± 0%  -33.33% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributes-24              4.000 ± 0%     2.000 ± 0%  -50.00% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/1/Naive/WithAttributes-24                6.000 ± 0%     6.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributeSet-24        2.000 ± 0%     2.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/5/Precomputed/WithAttributes-24          2.000 ± 0%     2.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributeSet-24            4.000 ± 0%     3.000 ± 0%  -25.00% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributes-24              5.000 ± 0%     3.000 ± 0%  -40.00% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/5/Naive/WithAttributes-24                7.000 ± 0%     7.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributeSet-24       2.000 ± 0%     2.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/10/Precomputed/WithAttributes-24         2.000 ± 0%     2.000 ± 0%        ~ (p=1.000 n=6) ¹
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributeSet-24           4.000 ± 0%     3.000 ± 0%  -25.00% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributes-24             5.000 ± 0%     3.000 ± 0%  -40.00% (p=0.002 n=6)
EndToEndCounterAdd/Filtered/Attributes/10/Naive/WithAttributes-24               7.000 ± 0%     7.000 ± 0%        ~ (p=1.000 n=6) ¹
geomean                                                                                    ²               -23.59%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean
```
2026-04-23 12:57:13 -04:00
David Ashpole 25ba7a7218 Revert "Optimize fixedsize reservoir (#7447)" (#8249)
This reverts commit 714ca7c32e.

Fixes https://github.com/open-telemetry/opentelemetry-go/issues/8238
2026-04-22 14:51:17 +02:00
Robert Pająk 5f80184b57 sdk/metric: apply default cardinality limit of 2000 (#8247)
Per
https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#cardinality-limits:

> If none of the previous values are defined, the default value of 2000
SHOULD be used.
2026-04-22 14:40:51 +02:00
David Ashpole 6f81801cd8 Use a DropReservoir when an exemplar.AlwaysOffFilter is provided (#8211)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/6260,
https://github.com/open-telemetry/opentelemetry-go/issues/6333

The [spec for always
off](https://github.com/open-telemetry/opentelemetry-specification/blob/d500678e4612b56ff2cd5f03e67cd845977d1746/specification/metrics/sdk.md#alwaysoff)
suggests this should "disable" the Exemplar feature:

> An ExemplarFilter which makes no measurements eligible for being an
Exemplar.
Using this ExemplarFilter is as good as disabling the Exemplar feature.

There were a few reports of much higher memory usage when exemplars were
added. I looked into the reports, and it looks like exemplar reservoirs
are expensive in terms of memory compared to the aggregation itself.
Ideally, we shouldn't construct the reservoir when an AlwaysOff exemplar
filter is used.

I couldn't find a super clean way to do this...
`exemplar.AlwaysOffFilter` is a function, so I couldn't easily compare
it without comparing the pointers. I'm open to other suggestions. The
internet says that compiler optimizations could cause this logic to
fail, but worst-case you get the existing behavior.

### Benchmarks

I needed a benchmark that creates a new attribute set for each call to
be able to see how much memory each attribute set uses, so I added a new
one, and ran it against main.

Overall, it reduces the amount of memory used per-attribute-set by
70-88%, which is pretty substantial.

Overall, 

```
                                                  │   old.txt   │               new.txt               │
                                                  │   sec/op    │    sec/op     vs base               │
BenchmarkMeasureNewAttributeSet/AlwaysOn/Int64Counter-24            3.523µ ± 2%   3.745µ ± 29%   +6.32% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Float64Counter-24          3.714µ ± 6%   3.879µ ±  5%        ~ (p=0.132 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Int64UpDownCounter-24      3.811µ ± 8%   3.941µ ±  5%        ~ (p=0.065 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Float64UpDownCounter-24    3.714µ ± 5%   3.822µ ±  1%        ~ (p=0.132 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Int64Histogram-24          3.126µ ± 4%   3.333µ ±  4%   +6.61% (p=0.004 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Float64Histogram-24        3.099µ ± 4%   3.204µ ±  8%        ~ (p=0.093 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Int64Gauge-24              3.745µ ± 7%   3.902µ ±  4%        ~ (p=0.240 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Float64Gauge-24            3.746µ ± 7%   3.862µ ±  2%        ~ (p=0.102 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Int64Counter-24           3.621µ ± 3%   1.665µ ±  1%  -54.00% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Float64Counter-24         3.639µ ± 2%   1.686µ ±  4%  -53.68% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Int64UpDownCounter-24     3.563µ ± 4%   1.700µ ±  4%  -52.29% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Float64UpDownCounter-24   3.634µ ± 1%   1.690µ ±  4%  -53.49% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Int64Histogram-24         2.892µ ± 2%   2.005µ ±  2%  -30.66% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Float64Histogram-24       2.962µ ± 5%   2.057µ ±  6%  -30.55% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Int64Gauge-24             3.692µ ± 5%   1.599µ ±  2%  -56.68% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Float64Gauge-24           3.651µ ± 3%   1.612µ ±  2%  -55.86% (p=0.002 n=6)
geomean                                             3.495µ        2.541µ        -27.30%

                                                  │   old.txt    │               new.txt               │
                                                  │     B/op     │     B/op      vs base               │
BenchmarkMeasureNewAttributeSet/AlwaysOn/Int64Counter-24            3.107Ki ± 0%   3.107Ki ± 0%        ~ (p=0.121 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Float64Counter-24          3.108Ki ± 0%   3.107Ki ± 0%        ~ (p=0.177 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Int64UpDownCounter-24      3.108Ki ± 0%   3.108Ki ± 0%        ~ (p=0.675 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Float64UpDownCounter-24    3.107Ki ± 0%   3.107Ki ± 0%        ~ (p=1.000 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Int64Histogram-24          2.622Ki ± 0%   2.622Ki ± 0%        ~ (p=0.394 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Float64Histogram-24        2.622Ki ± 0%   2.622Ki ± 0%        ~ (p=0.636 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Int64Gauge-24              3.108Ki ± 0%   3.107Ki ± 0%        ~ (p=0.167 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOn/Float64Gauge-24            3.107Ki ± 0%   3.108Ki ± 0%        ~ (p=0.182 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Int64Counter-24            3182.0 ± 0%     361.0 ± 0%  -88.65% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Float64Counter-24          3182.5 ± 0%     360.5 ± 0%  -88.67% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Int64UpDownCounter-24      3182.0 ± 0%     359.5 ± 1%  -88.70% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Float64UpDownCounter-24    3182.0 ± 0%     361.0 ± 0%  -88.65% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Int64Histogram-24          2684.0 ± 0%     773.0 ± 0%  -71.20% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Float64Histogram-24        2684.0 ± 0%     773.0 ± 0%  -71.20% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Int64Gauge-24              3182.0 ± 0%     361.0 ± 1%  -88.65% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Float64Gauge-24            3182.0 ± 0%     361.0 ± 0%  -88.65% (p=0.002 n=6)
geomean                                             2.978Ki        1.127Ki       -62.17%

                                                  │   old.txt   │               new.txt               │
                                                  │  allocs/op  │ allocs/op   vs base                 │
BenchmarkMeasureNewAttributeSet/AlwaysOn/Int64Counter-24             12.00 ± 0%   12.00 ± 0%        ~ (p=1.000 n=6) ¹
BenchmarkMeasureNewAttributeSet/AlwaysOn/Float64Counter-24           12.00 ± 0%   12.00 ± 0%        ~ (p=1.000 n=6) ¹
BenchmarkMeasureNewAttributeSet/AlwaysOn/Int64UpDownCounter-24       12.00 ± 0%   12.00 ± 0%        ~ (p=1.000 n=6) ¹
BenchmarkMeasureNewAttributeSet/AlwaysOn/Float64UpDownCounter-24     12.00 ± 0%   12.00 ± 0%        ~ (p=1.000 n=6) ¹
BenchmarkMeasureNewAttributeSet/AlwaysOn/Int64Histogram-24           13.00 ± 0%   13.00 ± 0%        ~ (p=1.000 n=6) ¹
BenchmarkMeasureNewAttributeSet/AlwaysOn/Float64Histogram-24         13.00 ± 0%   13.00 ± 0%        ~ (p=1.000 n=6) ¹
BenchmarkMeasureNewAttributeSet/AlwaysOn/Int64Gauge-24               12.00 ± 0%   12.00 ± 0%        ~ (p=1.000 n=6) ¹
BenchmarkMeasureNewAttributeSet/AlwaysOn/Float64Gauge-24             12.00 ± 0%   12.00 ± 0%        ~ (p=1.000 n=6) ¹
BenchmarkMeasureNewAttributeSet/AlwaysOff/Int64Counter-24           12.000 ± 0%   7.000 ± 0%  -41.67% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Float64Counter-24         12.000 ± 0%   7.000 ± 0%  -41.67% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Int64UpDownCounter-24     12.000 ± 0%   7.000 ± 0%  -41.67% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Float64UpDownCounter-24   12.000 ± 0%   7.000 ± 0%  -41.67% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Int64Histogram-24         13.000 ± 0%   9.000 ± 0%  -30.77% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Float64Histogram-24       13.000 ± 0%   9.000 ± 0%  -30.77% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Int64Gauge-24             12.000 ± 0%   7.000 ± 0%  -41.67% (p=0.002 n=6)
BenchmarkMeasureNewAttributeSet/AlwaysOff/Float64Gauge-24           12.000 ± 0%   7.000 ± 0%  -41.67% (p=0.002 n=6)
geomean                                              12.24        9.553       -21.97%
¹ all samples are equal
```

Gemini helped me write this.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-21 16:08:33 -04:00
Robert Pająk bec9f66b45 sdk/trace: apply AttributeValueLengthLimit to attribute.SLICE (#8217)
Fixes #7955

Per the OTel spec, attribute value limits must be applied recursively to
array elements. Previously truncateAttr only handled STRING and
STRINGSLICE.

Add a SLICE case to truncateAttr and two unexported helpers:
- truncateValue: recursively truncates STRING, STRINGSLICE, and SLICE
- needsTruncation: pre-scan guard that avoids allocating a new slice
when no element would be modified (mirrors sdk/log's pattern)

```
goarch: amd64
pkg: go.opentelemetry.io/otel/sdk/trace
cpu: 13th Gen Intel(R) Core(TM) i7-13800H
BenchmarkSpanLimits/None-20                                       205869              6757 ns/op           11296 B/op         38 allocs/op
BenchmarkSpanLimits/AttributeValueLengthLimit-20                  189799              5271 ns/op           11712 B/op         45 allocs/op
BenchmarkSpanLimits/AttributeCountLimit-20                        135494              9970 ns/op           10592 B/op         38 allocs/op
BenchmarkSpanLimits/EventCountLimit-20                            121084              9672 ns/op           10224 B/op         35 allocs/op
BenchmarkSpanLimits/LinkCountLimit-20                             110524              9419 ns/op            9824 B/op         35 allocs/op
BenchmarkSpanLimits/AttributePerEventCountLimit-20                123159              9308 ns/op           11296 B/op         38 allocs/op
BenchmarkSpanLimits/AttributePerLinkCountLimit-20                 146022              9337 ns/op           11296 B/op         38 allocs/op
```

The new `attribute.SLICE` item makes
`BenchmarkSpanLimits/AttributeValueLengthLimit` ~12% slower with 5 extra
allocs in that path compared to `main`. This is fine as 3 strings and 2
arrays need to be allocated because of the limits+truncation.

```
SpanLimits/AttributeValueLengthLimit   5.030µs ± 2%   5.651µs ± 2%  +12.34% (p=0.000 n=10)
SpanLimits/AttributeValueLengthLimit   10.53KiB ± 0% 11.44KiB ± 0% +8.61%  (p=0.000 n=10)
SpanLimits/AttributeValueLengthLimit   40.00 allocs   45.00 allocs +12.50% (p=0.000 n=10)
```
2026-04-17 18:17:45 +02:00
Robert Pająk ac9a33d214 test: truncate attribute string values using Unicode rune count (#8219)
Add test cases to ensure correct behavior.

From https://opentelemetry.io/docs/specs/otel/common/#attribute-limits:

> set an attribute value length limit such that for each attribute
value:
> - if it is a string, if it exceeds that limit (counting any character
in it as 1), SDKs MUST truncate that value, so that its length is at
most equal to the limit,
2026-04-17 17:52:31 +02:00
David Ashpole 3356ad3f1a Fix typos found by copilot (#8221)
Found during copilot code reviews on other PRs.


https://github.com/open-telemetry/opentelemetry-go/pull/8211#discussion_r3094951812
2026-04-16 12:17:21 -07:00
Robert Pająk d13f8ecb2d attribute: add SLICE type support (#8166)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/7934

```
$ go test -run=^$ -bench=BenchmarkSlice
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/attribute
cpu: 13th Gen Intel(R) Core(TM) i7-13800H
BenchmarkSlice/Len3/Value-20                    25297926                52.56 ns/op          144 B/op          1 allocs/op
BenchmarkSlice/Len3/KeyValue-20                 21315132                55.97 ns/op          144 B/op          1 allocs/op
BenchmarkSlice/Len3/AsSlice-20                  24214248                50.03 ns/op          144 B/op          1 allocs/op
BenchmarkSlice/Len3/String-20                   14148270                86.48 ns/op           48 B/op          1 allocs/op
BenchmarkSlice/Len3/Emit-20                     13605388                85.18 ns/op           48 B/op          1 allocs/op
BenchmarkSlice/Len5Nested/Value-20              16086171                71.30 ns/op          240 B/op          1 allocs/op
BenchmarkSlice/Len5Nested/KeyValue-20           15547844                75.81 ns/op          240 B/op          1 allocs/op
BenchmarkSlice/Len5Nested/AsSlice-20            17806996                66.16 ns/op          240 B/op          1 allocs/op
BenchmarkSlice/Len5Nested/String-20              7409064               165.2 ns/op            64 B/op          1 allocs/op
BenchmarkSlice/Len5Nested/Emit-20                7666302               161.0 ns/op            64 B/op          1 allocs/op
PASS
ok      go.opentelemetry.io/otel/attribute      12.980s
```

```
$ go test -run=^$ -bench=BenchmarkHashKVs
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/attribute
cpu: 13th Gen Intel(R) Core(TM) i7-13800H
BenchmarkHashKVs-20      1268742               940.5 ns/op             0 B/op          0 allocs/op
PASS
ok      go.opentelemetry.io/otel/attribute      1.198s
```
2026-04-16 12:38:32 +02:00
Ali Asghar c56c84380c sdk/trace: propagate SpanExporter.Shutdown error from BatchSpanProcessor (#8197)
Fixes #6878.

`bsp.e.Shutdown(ctx)` was called with `:=` inside an `if` statement,
creating a new variable that shadowed the outer `err`. The error was
handled via `otel.Handle` but never returned to the caller of
`BatchSpanProcessor.Shutdown`.

### Fix

Use a dedicated `exportErr` variable. The goroutine writes it before
closing the `wait` channel; the caller reads it only in the `<-wait`
select case (where the goroutine is guaranteed done). This is race-free
— addressing the concern raised by @seh in #6878.

All existing `TestBatchSpanProcessor*` tests pass.

---------

Signed-off-by: alliasgher <alliasgher123@gmail.com>
Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
Co-authored-by: Robert Pająk <pellared@hotmail.com>
2026-04-15 09:04:18 -07:00
David Ashpole 88a71eeb67 Fix exemplar tests in containerized environments (#8188)
The actual default reservoir provider uses runtime.GOMAXPROCS(0) to work
properly in containerized environments. When I was running the test, the
fact that the test used runtime.NumCPU() caused the test to fail.


https://github.com/open-telemetry/opentelemetry-go/blob/48dd8b1a0975e14a09d615f8ee80212b20f1e107/sdk/metric/exemplar.go#L70-L73
2026-04-14 10:26:22 -04:00
David Ashpole d96b420138 Add support for the development attributes advisory parameter (#8135)
From [the
spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-advisory-parameter-attributes):

> ##### Instrument advisory parameter: `Attributes`

> **Status**: [Development](../document-status.md)

> Applies to all instrument types.

> `Attributes` (a list of [attribute
keys](../common/README.md#attribute)) is
the recommended set of attribute keys to be used for the resulting
metrics.

We already have `WithAttributes` options, so i've opted to name this
`WithDefaultAttributes` to avoid naming collisions. We could also
consider `WithAttributeKeys`, or `WithDefaultAttributeKeys`

Follows the pattern for experimental options introduced in
https://github.com/open-telemetry/opentelemetry-go/pull/8111

---------

Co-authored-by: Robert Pająk <pellared@hotmail.com>
2026-04-10 14:38:44 -04:00
Robert Pająk 1519eb8c33 attribute: Set.MarshalLog to use Value.String instead of Value.Emit (#8169)
Towards https://github.com/open-telemetry/opentelemetry-go/issues/8145
2026-04-10 15:11:31 +02:00
Robert Pająk ace6b2479e metricdatatest: support BYTESLICE attribute comparisons (#8167)
Address
https://github.com/open-telemetry/opentelemetry-go/pull/7948#discussion_r3058370139
2026-04-10 14:43:50 +02:00
renovate[bot] f92fc890b6 fix(deps): update module golang.org/x/tools to v0.44.0 (#8173)
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [golang.org/x/tools](https://pkg.go.dev/golang.org/x/tools) |
[`v0.43.0` →
`v0.44.0`](https://cs.opensource.google/go/x/tools/+/refs/tags/v0.43.0...refs/tags/v0.44.0)
|
![age](https://developer.mend.io/api/mc/badges/age/go/golang.org%2fx%2ftools/v0.44.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/go/golang.org%2fx%2ftools/v0.43.0/v0.44.0?slim=true)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/5322) for more information.

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/open-telemetry/opentelemetry-go).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjExMC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJTa2lwIENoYW5nZWxvZyIsImRlcGVuZGVuY2llcyJdfQ==-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: dmathieu <damien.mathieu@elastic.co>
2026-04-10 10:24:24 +02:00
David Ashpole 0c09e08e7f Add experimental support for batching in periodic reader (#8071)
Adds experimental support for maxExportBatchSize using the
`OTEL_GO_X_METRIC_EXPORT_BATCH_SIZE=<size>` environment variable.

Previous prototype:
https://github.com/open-telemetry/opentelemetry-go/pull/7930

This preserves existing behavior for timeouts when batching is not used,
but individually applies the timeout to export calls when batching is
used.
2026-04-09 09:31:05 -04:00
David Ashpole edd072f2c9 Improve test coverage for exponential histogram edge cases (#8129)
Some small testing improvements forked from
https://github.com/open-telemetry/opentelemetry-go/pull/8077.

This also fixes a flake where the order in which sums are added can
change the resulting sum. Use assertSumEqual to handle this similar to
other places in the test.

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
2026-04-08 11:58:29 -07:00
renovate[bot] 3157d0a7d9 fix(deps): update module golang.org/x/sys to v0.43.0 (#8156)
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) | [`v0.42.0` →
`v0.43.0`](https://cs.opensource.google/go/x/sys/+/refs/tags/v0.42.0...refs/tags/v0.43.0)
|
![age](https://developer.mend.io/api/mc/badges/age/go/golang.org%2fx%2fsys/v0.43.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/go/golang.org%2fx%2fsys/v0.42.0/v0.43.0?slim=true)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/5322) for more information.

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these
updates again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/open-telemetry/opentelemetry-go).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDIuMTEiLCJ1cGRhdGVkSW5WZXIiOiI0My4xMDIuMTEiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbIlNraXAgQ2hhbmdlbG9nIiwiZGVwZW5kZW5jaWVzIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-08 14:40:06 +02:00
Robert Pająk 3b18b21580 unwrap error chains created with fmt.Errorf (#8133)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/7975

Per
https://github.com/open-telemetry/opentelemetry-go/issues/7975#issuecomment-4183251694

Per https://github.com/open-telemetry/semantic-conventions/issues/3588

Credits:
- Balaji01-4D for
https://github.com/open-telemetry/opentelemetry-go/pull/8018
- seh for providing valuable feedback
2026-04-07 20:03:30 +02:00
David Ashpole 28df982c8b Add support for experimental options in the metrics API (#8111)
Part of https://github.com/open-telemetry/opentelemetry-go/issues/8110

Related to
https://github.com/open-telemetry/opentelemetry-go/issues/5882.

I'm hoping to find a better way to support experimental Options types in
our API packages. This is one approach to consider.

This contains no public API changes. It introduces a type:
`ExperimentalOption` in `/metric/internal/x`, which can be used by our
experimental options defined outside of the module. Options that embed
this interface are ignored by `New*Config` builder functions in the
metrics API to prevent them from panicing when used. Only SDKs that
explicitly support the experimental option in question will respect it.
Alternative SDKs will ignore the experimental options. We would still
need to treat ExperimentalOption as a stable artifact, since the SDK
will indirectly depend on it.

See
https://github.com/open-telemetry/opentelemetry-go/compare/main...dashpole:opentelemetry-go:attributes_advisory
for how this would be used to support the advisory attributes parameter.
2026-04-03 15:56:57 -04:00
Damien Mathieu 9276201a64 Release v1.43.0 / v0.65.0 / v0.19.0 (#8128)
Release issue:
https://github.com/open-telemetry/opentelemetry-go/issues/8127

## Added

- Add `IsRandom` and `WithRandom` on `TraceFlags`, and `IsRandom` on
`SpanContext` in `go.opentelemetry.io/otel/trace`
for [W3C Trace Context Level 2 Random Trace ID
Flag](https://www.w3.org/TR/trace-context-2/#random-trace-id-flag)
support. (#8012)
- Add service detection with `WithService` in
`go.opentelemetry.io/otel/sdk/resource`. (#7642)
- Add `DefaultWithContext` and `EnvironmentWithContext` in
`go.opentelemetry.io/otel/sdk/resource` to support plumbing
`context.Context` through default and environment detectors. (#8051)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`.
(#8038)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`.
(#8038)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#8038)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`.
(#8038)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
(#8038)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8038)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest`. (#8038)
- Add support for per-series start time tracking for cumulative metrics
in `go.opentelemetry.io/otel/sdk/metric`.
  Set `OTEL_GO_X_PER_SERIES_START_TIMESTAMPS=true` to enable. (#8060)
- Add `WithCardinalityLimitSelector` for metric reader for configuring
cardinality limits specific to the instrument kind. (#7855)

## Changed

- Introduce the `EMPTY` Type in `go.opentelemetry.io/otel/attribute` to
reflect that an empty value is now a valid value, with `INVALID`
remaining as a deprecated alias of `EMPTY`. (#8038)
- Refactor slice handling in `go.opentelemetry.io/otel/attribute` to
optimize short slice values with fixed-size fast paths. (#8039)
- Improve performance of span metric recording in
`go.opentelemetry.io/otel/sdk/trace` by returning early if
self-observability is not enabled. (#8067)
- Improve formatting of metric data diffs in
`go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest`. (#8073)

## Deprecated

- Deprecate `INVALID` in `go.opentelemetry.io/otel/attribute`. Use
`EMPTY` instead. (#8038)

## Fixed

- Return spec-compliant `TraceIdRatioBased` description. This is a
breaking behavioral change, but it is necessary to
make the implementation
[spec-compliant](https://opentelemetry.io/docs/specs/otel/trace/sdk/#traceidratiobased).
(#8027)
- Fix a race condition in `go.opentelemetry.io/otel/sdk/metric` where
the lastvalue aggregation could collect the value 0 even when no
zero-value measurements were recorded. (#8056)
- Limit HTTP response body to 4 MiB in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` to
mitigate excessive memory usage caused by a misconfigured or malicious
server.
Responses exceeding the limit are treated as non-retryable errors.
(#8108)
- Limit HTTP response body to 4 MiB in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` to
mitigate excessive memory usage caused by a misconfigured or malicious
server.
Responses exceeding the limit are treated as non-retryable errors.
(#8108)
- Limit HTTP response body to 4 MiB in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` to
mitigate excessive memory usage caused by a misconfigured or malicious
server.
Responses exceeding the limit are treated as non-retryable errors.
(#8108)
- `WithHostID` detector in `go.opentelemetry.io/otel/sdk/resource` to
use full path for `kenv` command on BSD. (#8113)
- Fix missing `request.GetBody` in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` to
correctly handle HTTP2 GOAWAY frame. (#8096)

---------

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
2026-04-03 10:30:03 +02:00
Damien Mathieu 35214b6013 Use an absolute path when calling bsd kenv (#8113)
Co-authored-by: Robert Pająk <pellared@hotmail.com>
2026-04-01 11:05:13 +02:00
David Ashpole ab27913693 metricdatatest: Improve printing of diffs (#8073)
I've been getting tired of trying to parse blobs of OTLP-like text when
debugging metrics SDK test failures. This PR updating the printing of
diffs between metrics.

### Changes

This combines the `compareDiff`, and `diffSlices` functions into a
single `diffSlices` function. The `compare` parameter now returns a
`[]string` instead of a bool, to allow us to get a list of specific
differences between elements. `diffSlices` now also accepts a
`formatContext` parameter that provides the context (e.g. which scope,
which metric, etc) to print before printing the difference itself.

I've chosen to use the scope name, metric name, and attributes as the
context for scope, metric, and datapoint respectively. We could print
out more (as those are not the only identifying fields), but that is
usually enough to point to the problem.

### Example

I "broke" one of the OpenCensus tests by changing the expected SpanID
from 2 -> 1. You can see the resulting error message before and after
below:

Before:
```
--- FAIL: TestConvertMetrics (0.00s)
    --- FAIL: TestConvertMetrics/normal_Histogram,_summary,_gauges,_and_sums (0.00s)
        metric_test.go:940: [ScopeMetrics Metrics not equal:
            missing expected values:
            metricdata.Metrics{Name:"foo.com/histogram-a", Description:"a testing histogram", Unit:"1", 
Data:metricdata.Histogram[float64]{DataPoints:[]metricdata.HistogramDataPoint[float64]
{metricdata.HistogramDataPoint[float64]{Attributes:attribute.Set{hash:0x83dbf482c8017da3, data:
[2]attribute.KeyValue{attribute.KeyValue{Key:"a", Value:attribute.Value{vtype:4, numeric:0x0, stringly:"hello", 
slice:interface {}(nil)}}, attribute.KeyValue{Key:"b", Value:attribute.Value{vtype:4, numeric:0x0, stringly:"world", 
slice:interface {}(nil)}}}}, StartTime:time.Date(2026, time.March, 18, 15, 46, 53, 76753334, time.Local), 
Time:time.Date(2026, time.March, 18, 15, 47, 53, 77753334, time.Local), Count:0x8, Bounds:[]float64{1, 2, 3}, 
BucketCounts:[]uint64{0x1, 0x2, 0x5}, Min:metricdata.Extrema[float64]{value:0, valid:false}, 
Max:metricdata.Extrema[float64]{value:0, valid:false}, Sum:100, Exemplars:[]metricdata.Exemplar[float64]
{metricdata.Exemplar[float64]{FilteredAttributes:[]attribute.KeyValue{attribute.KeyValue{Key:"bool", 
Value:attribute.Value{vtype:1, numeric:0x1, stringly:"", slice:interface {}(nil)}}}, Time:time.Date(2026, time.March, 18, 15, 
47, 43, 77753334, time.Local), Value:0.8, SpanID:[]uint8{0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, TraceID:[]uint8{0x1, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, metricdata.Exemplar[float64]{FilteredAttributes:
[]attribute.KeyValue(nil), Time:time.Date(2026, time.March, 18, 15, 47, 43, 77753334, time.Local), Value:1.5, SpanID:
[]uint8{0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, TraceID:[]uint8{0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0}}, metricdata.Exemplar[float64]{FilteredAttributes:[]attribute.KeyValue(nil), Time:time.Date(2026, 
time.March, 18, 15, 47, 43, 77753334, time.Local), Value:2.6, SpanID:[]uint8{0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
TraceID:[]uint8{0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}}}, 
metricdata.HistogramDataPoint[float64]{Attributes:attribute.Set{hash:0x83dbf482c8017da3, data:
[2]attribute.KeyValue{attribute.KeyValue{Key:"a", Value:attribute.Value{vtype:4, numeric:0x0, stringly:"hello", 
slice:interface {}(nil)}}, attribute.KeyValue{Key:"b", Value:attribute.Value{vtype:4, numeric:0x0, stringly:"world", 
slice:interface {}(nil)}}}}, StartTime:time.Date(2026, time.March, 18, 15, 46, 53, 76753334, time.Local), 
Time:time.Date(2026, time.March, 18, 15, 47, 53, 76753334, time.Local), Count:0xa, Bounds:[]float64{1, 2, 3}, 
BucketCounts:[]uint64{0x1, 0x4, 0x5}, Min:metricdata.Extrema[float64]{value:0, valid:false}, 
Max:metricdata.Extrema[float64]{value:0, valid:false}, Sum:110, Exemplars:[]metricdata.Exemplar[float64]
{metricdata.Exemplar[float64]{FilteredAttributes:[]attribute.KeyValue(nil), Time:time.Date(2026, time.March, 18, 15, 47, 
43, 77753334, time.Local), Value:0.9, SpanID:[]uint8{0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, TraceID:[]uint8{0x7, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, metricdata.Exemplar[float64]{FilteredAttributes:
[]attribute.KeyValue(nil), Time:time.Date(2026, time.March, 18, 15, 47, 43, 77753334, time.Local), Value:1.1, SpanID:
[]uint8{0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, TraceID:[]uint8{0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0}}, metricdata.Exemplar[float64]{FilteredAttributes:[]attribute.KeyValue(nil), Time:time.Date(2026, 
time.March, 18, 15, 47, 43, 77753334, time.Local), Value:2.7, SpanID:[]uint8{0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
TraceID:[]uint8{0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}}}}, Temporality:0x1}}
            unexpected additional values:
            metricdata.Metrics{Name:"foo.com/histogram-a", Description:"a testing histogram", Unit:"1", 
Data:metricdata.Histogram[float64]{DataPoints:[]metricdata.HistogramDataPoint[float64]
{metricdata.HistogramDataPoint[float64]{Attributes:attribute.Set{hash:0x83dbf482c8017da3, data:
[2]attribute.KeyValue{attribute.KeyValue{Key:"a", Value:attribute.Value{vtype:4, numeric:0x0, stringly:"hello", 
slice:interface {}(nil)}}, attribute.KeyValue{Key:"b", Value:attribute.Value{vtype:4, numeric:0x0, stringly:"world", 
slice:interface {}(nil)}}}}, StartTime:time.Date(2026, time.March, 18, 15, 46, 53, 76753334, time.Local), 
Time:time.Date(2026, time.March, 18, 15, 47, 53, 77753334, time.Local), Count:0x8, Bounds:[]float64{1, 2, 3}, 
BucketCounts:[]uint64{0x1, 0x2, 0x5}, Min:metricdata.Extrema[float64]{value:0, valid:false}, 
Max:metricdata.Extrema[float64]{value:0, valid:false}, Sum:100, Exemplars:[]metricdata.Exemplar[float64]
{metricdata.Exemplar[float64]{FilteredAttributes:[]attribute.KeyValue{attribute.KeyValue{Key:"bool", 
Value:attribute.Value{vtype:1, numeric:0x1, stringly:"", slice:interface {}(nil)}}}, Time:time.Date(2026, time.March, 18, 15, 
47, 43, 77753334, time.Local), Value:0.8, SpanID:[]uint8{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, TraceID:[]uint8{0x1, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, metricdata.Exemplar[float64]{FilteredAttributes:
[]attribute.KeyValue(nil), Time:time.Date(2026, time.March, 18, 15, 47, 43, 77753334, time.Local), Value:1.5, SpanID:
[]uint8{0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, TraceID:[]uint8{0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0}}, metricdata.Exemplar[float64]{FilteredAttributes:[]attribute.KeyValue(nil), Time:time.Date(2026, 
time.March, 18, 15, 47, 43, 77753334, time.Local), Value:2.6, SpanID:[]uint8{0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
TraceID:[]uint8{0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}}}, 
metricdata.HistogramDataPoint[float64]{Attributes:attribute.Set{hash:0x83dbf482c8017da3, data:
[2]attribute.KeyValue{attribute.KeyValue{Key:"a", Value:attribute.Value{vtype:4, numeric:0x0, stringly:"hello", 
slice:interface {}(nil)}}, attribute.KeyValue{Key:"b", Value:attribute.Value{vtype:4, numeric:0x0, stringly:"world", 
slice:interface {}(nil)}}}}, StartTime:time.Date(2026, time.March, 18, 15, 46, 53, 76753334, time.Local), 
Time:time.Date(2026, time.March, 18, 15, 47, 53, 76753334, time.Local), Count:0xa, Bounds:[]float64{1, 2, 3}, 
BucketCounts:[]uint64{0x1, 0x4, 0x5}, Min:metricdata.Extrema[float64]{value:0, valid:false}, 
Max:metricdata.Extrema[float64]{value:0, valid:false}, Sum:110, Exemplars:[]metricdata.Exemplar[float64]
{metricdata.Exemplar[float64]{FilteredAttributes:[]attribute.KeyValue(nil), Time:time.Date(2026, time.March, 18, 15, 47, 
43, 77753334, time.Local), Value:0.9, SpanID:[]uint8{0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, TraceID:[]uint8{0x7, 0x0, 
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, metricdata.Exemplar[float64]{FilteredAttributes:
[]attribute.KeyValue(nil), Time:time.Date(2026, time.March, 18, 15, 47, 43, 77753334, time.Local), Value:1.1, SpanID:
[]uint8{0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, TraceID:[]uint8{0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0, 0x0}}, metricdata.Exemplar[float64]{FilteredAttributes:[]attribute.KeyValue(nil), Time:time.Date(2026, 
time.March, 18, 15, 47, 43, 77753334, time.Local), Value:2.7, SpanID:[]uint8{0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
TraceID:[]uint8{0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}}}}, Temporality:0x1}}
            ]
FAIL
FAIL    go.opentelemetry.io/otel/bridge/opencensus/internal/ocmetric    0.037s
```

After:

```
--- FAIL: TestConvertMetrics (0.00s)
    --- FAIL: TestConvertMetrics/normal_Histogram,_summary,_gauges,_and_sums (0.00s)
        metric_test.go:940: [ScopeMetrics Metrics not equal:
            Metric "foo.com/histogram-a":
                Metrics Data not equal:
                Histogram not equal:
                Histogram DataPoints not equal:
                HistogramDataPoint [a=hello,b=world]:
                        Exemplars not equal:
                        Exemplar:
                                SpanID not equal:
                                expected: [2 0 0 0 0 0 0 0]
                                actual: [1 0 0 0 0 0 0 0]
            ]
FAIL
FAIL    go.opentelemetry.io/otel/bridge/opencensus/internal/ocmetric    0.036s
```
2026-03-30 15:51:15 -04:00