mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2026-06-03 18:35:08 +02:00
b344564bf0bcbca640f20bbced315037c411be08
1162 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
597532c4d4 |
Add observable instrument variants to semconv v1.41.0 (#8350)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/7342 Generates both observable and synchronous variants of instruments per https://github.com/open-telemetry/opentelemetry-go/issues/7342#issuecomment-3292806559 |
||
|
|
f12c29f68a |
Generating histogram boundaries from weaver.yaml (#8015)
Adding support for histogram boundaries to be generated from weaver fixes #8002 --------- Co-authored-by: Robert Pająk <pellared@hotmail.com> |
||
|
|
97447f5c54 |
Add max baggage length as limitation (#8222)
```
goos: darwin
goarch: arm64
pkg: go.opentelemetry.io/otel/baggage
cpu: Apple M1 Max
│ /tmp/old.txt │ /tmp/new.txt │
│ sec/op │ sec/op vs base │
New-10 413.5n ± 1% 410.1n ± 1% ~ (p=0.184 n=10)
NewMemberRaw-10 12.65n ± 1% 12.62n ± 1% ~ (p=0.270 n=10)
Parse-10 1.252µ ± 2% 1.254µ ± 1% ~ (p=0.778 n=10)
String-10 594.9n ± 1% 593.4n ± 1% ~ (p=0.279 n=10)
ValueEscape/nothing_to_escape-10 4.890n ± 1% 4.885n ± 0% ~ (p=0.579 n=10)
ValueEscape/requires_escaping-10 22.02n ± 1% 21.47n ± 1% -2.50% (p=0.000 n=10)
ValueEscape/long_value-10 507.4n ± 1% 506.6n ± 2% ~ (p=0.481 n=10)
MemberString-10 486.7n ± 15% 514.0n ± 5% ~ (p=0.190 n=10)
ParseOversized-10 22544795.0n ± 1% 130.8n ± 4% -100.00% (p=0.000 n=10)
geomean 510.0n 133.8n -73.76%
│ /tmp/old.txt │ /tmp/new.txt │
│ B/op │ B/op vs base │
New-10 592.0 ± 0% 592.0 ± 0% ~ (p=1.000 n=10) ¹
NewMemberRaw-10 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
Parse-10 1.039Ki ± 0% 1.039Ki ± 0% ~ (p=1.000 n=10) ¹
String-10 840.0 ± 0% 840.0 ± 0% ~ (p=1.000 n=10) ¹
ValueEscape/nothing_to_escape-10 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
ValueEscape/requires_escaping-10 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=10) ¹
ValueEscape/long_value-10 576.0 ± 0% 576.0 ± 0% ~ (p=1.000 n=10) ¹
MemberString-10 656.0 ± 0% 656.0 ± 0% ~ (p=1.000 n=10) ¹
ParseOversized-10 801126.50 ± 0% 88.00 ± 0% -99.99% (p=0.000 n=10)
geomean ² -63.68% ²
¹ all samples are equal
² summaries must be >0 to compute geomean
│ /tmp/old.txt │ /tmp/new.txt │
│ allocs/op │ allocs/op vs base │
New-10 6.000 ± 0% 6.000 ± 0% ~ (p=1.000 n=10) ¹
NewMemberRaw-10 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
Parse-10 18.00 ± 0% 18.00 ± 0% ~ (p=1.000 n=10) ¹
String-10 8.000 ± 0% 8.000 ± 0% ~ (p=1.000 n=10) ¹
ValueEscape/nothing_to_escape-10 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
ValueEscape/requires_escaping-10 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹
ValueEscape/long_value-10 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹
MemberString-10 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=10) ¹
ParseOversized-10 250007.000 ± 0% 3.000 ± 0% -100.00% (p=0.000 n=10)
geomean ² -71.61% ²
¹ all samples are equal
² summaries must be >0 to compute geomean
```
---------
Co-authored-by: Robert Pająk <pellared@hotmail.com>
|
||
|
|
f12d198f16 | Merge commit from fork | ||
|
|
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> |
||
|
|
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> |
||
|
|
f3695d093a |
Prometheus Exporter: Drop Scope attributes name, version and schema_url (#8264)
The Prometheus SIG is currently working to stabilize the Prometheus exporter spec and the OTLP<->Prometheus data model compatibility spec. While working on https://github.com/open-telemetry/opentelemetry-specification/pull/5052, I realized the Go SDK is not handling collisions between the Scope attribute and the Scope Name, Version, and SchemaURL. This PR address it :) --------- Signed-off-by: Arthur Silva Sens <arthursens2005@gmail.com> Co-authored-by: David Ashpole <dashpole@google.com> |
||
|
|
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> |
||
|
|
4dd8821c94 |
fix counting of spans/logs in self-observability metrics in otlp trace and log exporters (#8254)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/8253 |
||
|
|
b4e15cd1c7 |
Add MaxRequestSize option to OTLP exporters (#8157)
Per https://github.com/open-telemetry/opentelemetry-proto/pull/782 - Introduce WithMaxRequestSize option for OTLP exporters to set a limit on the size of serialized export requests. - Implement logic in the HTTP and gRPC clients to check the request size against the configured maximum before compression and sending. - The default configuration is that the maximum request size is 32 MiB. |
||
|
|
25ba7a7218 |
Revert "Optimize fixedsize reservoir (#7447)" (#8249)
This reverts commit
|
||
|
|
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. |
||
|
|
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> |
||
|
|
5ecaa5b54f |
feat: add self-observability metrics to otlpmetrichttp metric exporters (#8194)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/7011 This PR updates https://github.com/open-telemetry/opentelemetry-go/pull/7493, and addresses outstanding comments. See commit descriptions for the changes made on top of that PR. Credit to @tongoss for most of the work. Benchmark results: ``` goos: linux goarch: amd64 pkg: go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/observ cpu: Intel(R) Xeon(R) CPU @ 2.20GHz │ sec/op │ InstrumentationExportMetrics/NoError-24 787.4n ± 5% InstrumentationExportMetrics/PartialError-24 4.137µ ± 9% InstrumentationExportMetrics/FullError-24 3.938µ ± 7% geomean 2.341µ │ B/op │ InstrumentationExportMetrics/NoError-24 0.000 ± 0% InstrumentationExportMetrics/PartialError-24 787.0 ± 0% InstrumentationExportMetrics/FullError-24 787.0 ± 0% geomean ¹ ¹ summaries must be >0 to compute geomean │ allocs/op │ InstrumentationExportMetrics/NoError-24 0.000 ± 0% InstrumentationExportMetrics/PartialError-24 6.000 ± 0% InstrumentationExportMetrics/FullError-24 6.000 ± 0% geomean ¹ ¹ summaries must be >0 to compute geomean ``` ``` goos: linux goarch: amd64 pkg: go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp cpu: Intel(R) Xeon(R) CPU @ 2.20GHz │ sec/op │ ExporterExportMetrics/Observability-24 433.5µ ± 4% ExporterExportMetrics/NoObservability-24 439.3µ ± 4% geomean 436.4µ │ B/op │ ExporterExportMetrics/Observability-24 28.72Ki ± 2% ExporterExportMetrics/NoObservability-24 28.71Ki ± 2% geomean 28.71Ki │ allocs/op │ ExporterExportMetrics/Observability-24 446.0 ± 0% ExporterExportMetrics/NoObservability-24 446.0 ± 0% geomean 446.0 ``` Written with assistance from Gemini. --------- Co-authored-by: Robert Wu <robertxtw@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Flc゛ <i@flc.io> |
||
|
|
5bd5702ad2 |
Fix stale status code reporting on self-observability metrics (#8226)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/8218 This now omits the status code attribute when a request fails before getting a response, and doesn't use the previous response's status code when reporting self-observability metrics. |
||
|
|
fa9276b15e |
exporters: support SLICE attributes (#8216)
Fixes #8162 Follow-up to #8153 for `attribute.SLICE`. Add end-to-end exporter handling for `attribute.SLICE` in the remaining paths that still treated it as invalid or relied on fallback formatting. Changes: - encode `attribute.SLICE` as OTLP `AnyValue_ArrayValue` for trace, log, and metric transforms - serialize Zipkin `SLICE` attributes using the non-OTLP AnyValue string representation - add trace-side coverage for recursive `convAttrValue` slice conversion |
||
|
|
3384d39f6b | prometheus: fix Collect data race for constant resource labels (#8227) | ||
|
|
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) ``` |
||
|
|
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 ``` |
||
|
|
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> |
||
|
|
0231f02f59 |
fix(otlpmetrichttp): replay gzipped bodies on redirect (#8185)
Same as https://github.com/open-telemetry/opentelemetry-go/pull/8152 but for `otlpmetrichttp` When gzip compression is enabled, the OTLP metric HTTP client compressed the request body for the initial send but left GetBody wired to the original uncompressed protobuf payload. Any redirect or retry path that rebuilt the request from GetBody could then resend an uncompressed body while still advertising Content-Encoding: gzip. Update GetBody to return the gzipped buffer and add a redirect regression test that verifies the replayed body matches the original compressed request and can be decompressed successfully. |
||
|
|
48dd8b1a09 |
Add x.Settable to allow reusing attribute options (#8178)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/7851 This adopts this proposal from @MrAlias: https://github.com/open-telemetry/opentelemetry-go/issues/7851#issuecomment-3837399805 This adds a Set function to attrOpt, and changes attrOpt functions to use a pointer receiver. Users can use this by checking if the attribute option implements the `Settable` interface in `metric/x`. There are no public API changes to the metric package, as this is still an experiment. See the benchmark change and the interface documentation for how it can be used to avoid calling metric.WithAttributeSet. I updated the benchmark in https://github.com/open-telemetry/opentelemetry-go/commit/448394b549375f4f6742201e199e0339d0b78524, but didn't commit it here to avoid a dependency between the SDK and the `metric/x` package. As expected, this removes one allocation from the Dynamic case! The results are: ``` │ main.txt │ resettable.txt │ │ sec/op │ sec/op vs base │ EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-24 238.2n ± 5% 220.7n ± 9% -7.39% (p=0.002 n=6) EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributeSet-24 611.1n ± 4% 620.3n ± 2% ~ (p=0.394 n=6) EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributeSet-24 1.147µ ± 7% 1.171µ ± 5% ~ (p=0.258 n=6) EndToEndCounterAdd/Filtered/Attributes/1/Dynamic/WithAttributeSet-24 363.8n ± 6% 363.5n ± 6% ~ (p=1.000 n=6) EndToEndCounterAdd/Filtered/Attributes/5/Dynamic/WithAttributeSet-24 1.464µ ± 5% 1.475µ ± 10% ~ (p=0.727 n=6) EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributeSet-24 2.924µ ± 7% 2.589µ ± 6% -11.47% (p=0.002 n=6) │ main.txt │ resettable.txt │ │ B/op │ B/op vs base │ EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-24 88.00 ± 0% 64.00 ± 0% -27.27% (p=0.002 n=6) EndToEndCounterAdd/NoFilter/Attributes/5/Dynamic/WithAttributeSet-24 344.0 ± 0% 321.0 ± 0% -6.69% (p=0.002 n=6) EndToEndCounterAdd/NoFilter/Attributes/10/Dynamic/WithAttributeSet-24 729.0 ± 0% 706.0 ± 0% -3.16% (p=0.002 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/5/Dynamic/WithAttributeSet-24 921.0 ± 0% 899.0 ± 0% -2.39% (p=0.002 n=6) EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributeSet-24 2.026Ki ± 0% 2.006Ki ± 0% -1.01% (p=0.002 n=6) │ main.txt │ resettable.txt │ │ allocs/op │ allocs/op vs base │ EndToEndCounterAdd/NoFilter/Attributes/1/Dynamic/WithAttributeSet-24 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.002 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/10/Dynamic/WithAttributeSet-24 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.002 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/5/Dynamic/WithAttributeSet-24 4.000 ± 0% 3.000 ± 0% -25.00% (p=0.002 n=6) EndToEndCounterAdd/Filtered/Attributes/10/Dynamic/WithAttributeSet-24 4.000 ± 0% 3.000 ± 0% -25.00% (p=0.002 n=6) ``` --------- Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> |
||
|
|
866dd2504c |
attribute: deprecate Value.Emit (#8176)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/8145 |
||
|
|
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> |
||
|
|
73876cb450 |
prometheus: use Value.String instead of Value.Emit (#8170)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/8144 From https://opentelemetry.io/docs/specs/otel/compatibility/prometheus_and_openmetrics/#metric-attributes: > non-string Attribute values MUST be converted to string attributes following the [attribute specification](https://opentelemetry.io/docs/specs/otel/common/#attribute). |
||
|
|
1519eb8c33 |
attribute: Set.MarshalLog to use Value.String instead of Value.Emit (#8169)
Towards https://github.com/open-telemetry/opentelemetry-go/issues/8145 |
||
|
|
b1284dbfaa |
Support BYTESLICE attributes across trace and exporter paths (#8153)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/8164 Supersedes #8042 which does not address the `trace` or `zipkin` packages, and has unrelated support changes. Add end-to-end handling for `attribute.BYTESLICE` in the remaining trace and exporter paths that still dropped, invalidated, or stringified byte slice attributes. This change: - preserves byte slice attributes in `trace/auto` - encodes byte slice attributes as OTLP `AnyValue_BytesValue` in trace, log, and metric transforms - serializes Zipkin byte slice attributes as JSON arrays of byte values - adds regression tests for each updated path ## Problem `attribute.BYTESLICE` is public, but several downstream conversions still did not handle it correctly: - `trace/auto` dropped byte slice attributes during conversion - OTLP trace, log, and metric transforms fell through to their invalid default handling - Zipkin fell back to `Value.Emit()`, which produced a base64 string rather than an explicit byte-array representation That made `BYTESLICE` unusable or inconsistent depending on the export path. ## Changes ### Trace - Handle `attribute.BYTESLICE` in `trace/auto` by converting it to an internal telemetry bytes value. - Add a regression test covering byte slice conversion. ### OTLP - Handle `attribute.BYTESLICE` in: - trace attribute transform - log gRPC attribute transform - log HTTP attribute transform - metric HTTP attribute transform - metric gRPC attribute transform - Update the shared log and metric transform templates so generated outputs stay aligned. - Add regression tests for the trace transform, both log transform outputs, and both metric transform outputs. ### Zipkin - Handle `attribute.BYTESLICE` explicitly in Zipkin tag serialization. - Serialize byte slices as JSON arrays of byte values instead of base64 text. - Add a regression test for Zipkin byte slice serialization. --------- Co-authored-by: Robert Pająk <pellared@hotmail.com> |
||
|
|
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. |
||
|
|
552d7ac071 |
fix(otlploghttp): replay gzipped bodies on redirect (#8152)
When gzip compression is enabled, the OTLP log HTTP client compressed the request body for the initial send but left GetBody wired to the original uncompressed protobuf payload. Any redirect or retry path that rebuilt the request from GetBody could then resend an uncompressed body while still advertising Content-Encoding: gzip. Update GetBody to return the gzipped buffer and add a redirect regression test that verifies the replayed body matches the original compressed request and can be decompressed successfully. |
||
|
|
876f7c51e4 |
attribute: add String method for Value type (#8142)
Towards https://github.com/open-telemetry/opentelemetry-go/issues/7810 Fixes https://github.com/open-telemetry/opentelemetry-go/issues/8143 String representation follows: https://opentelemetry.io/docs/specs/otel/common/#anyvalue-representation-for-non-otlp-protocols This uses optimizations like https://github.com/open-telemetry/opentelemetry-go/pull/8039 and we inline the JSON-array/string encoding logic so we avoid the extra allocations and reflection overhead of marshaling through encoding/json (the code is inlined here not to reimplement JSON broadly, but to provide a spec-specific, allocation-conscious formatter for a constrained data model). Benchmarks of both `String` and `Emit` (that is going to be deprecated) showcase that `String` is even more efficient. ``` goos: linux goarch: amd64 pkg: go.opentelemetry.io/otel/attribute cpu: 13th Gen Intel(R) Core(TM) i7-13800H BenchmarkBool/String-20 100000000 10.20 ns/op 0 B/op 0 allocs/op BenchmarkBool/Emit-20 100000000 10.33 ns/op 0 B/op 0 allocs/op BenchmarkBoolSlice/Len2/String-20 28427863 36.15 ns/op 16 B/op 1 allocs/op BenchmarkBoolSlice/Len2/Emit-20 5433291 201.8 ns/op 40 B/op 5 allocs/op BenchmarkBoolSlice/Len8/String-20 12453201 99.46 ns/op 48 B/op 1 allocs/op BenchmarkBoolSlice/Len8/Emit-20 2185160 546.0 ns/op 88 B/op 11 allocs/op BenchmarkInt/String-20 100000000 10.73 ns/op 0 B/op 0 allocs/op BenchmarkInt/Emit-20 100000000 11.03 ns/op 0 B/op 0 allocs/op BenchmarkIntSlice/Len2/String-20 17855926 61.57 ns/op 48 B/op 1 allocs/op BenchmarkIntSlice/Len2/Emit-20 6237072 184.9 ns/op 56 B/op 4 allocs/op BenchmarkIntSlice/Len8/String-20 6573506 192.1 ns/op 176 B/op 1 allocs/op BenchmarkIntSlice/Len8/Emit-20 3620901 332.8 ns/op 136 B/op 4 allocs/op BenchmarkInt64/String-20 100000000 10.90 ns/op 0 B/op 0 allocs/op BenchmarkInt64/Emit-20 100000000 10.91 ns/op 0 B/op 0 allocs/op BenchmarkInt64Slice/Len2/String-20 20924970 59.59 ns/op 48 B/op 1 allocs/op BenchmarkInt64Slice/Len2/Emit-20 6755516 184.2 ns/op 56 B/op 4 allocs/op BenchmarkInt64Slice/Len8/String-20 6033630 207.9 ns/op 176 B/op 1 allocs/op BenchmarkInt64Slice/Len8/Emit-20 3491808 327.2 ns/op 136 B/op 4 allocs/op BenchmarkFloat64/String-20 23607802 52.21 ns/op 2 B/op 1 allocs/op BenchmarkFloat64/Emit-20 13578472 93.34 ns/op 16 B/op 2 allocs/op BenchmarkFloat64Slice/Len2/String-20 12066591 111.0 ns/op 64 B/op 1 allocs/op BenchmarkFloat64Slice/Len2/Emit-20 5177293 234.3 ns/op 56 B/op 4 allocs/op BenchmarkFloat64Slice/Len8/String-20 3041408 381.9 ns/op 208 B/op 1 allocs/op BenchmarkFloat64Slice/Len8/Emit-20 2369974 548.3 ns/op 136 B/op 4 allocs/op BenchmarkString/String-20 137506468 8.578 ns/op 0 B/op 0 allocs/op BenchmarkString/Emit-20 139229646 8.542 ns/op 0 B/op 0 allocs/op BenchmarkStringSlice/Len2/Emit-20 5809321 228.9 ns/op 120 B/op 4 allocs/op BenchmarkStringSlice/Len8/String-20 5089977 240.0 ns/op 96 B/op 1 allocs/op BenchmarkStringSlice/Len8/Emit-20 2569848 480.0 ns/op 344 B/op 4 allocs/op BenchmarkByteSlice/String-20 32244670 34.31 ns/op 16 B/op 1 allocs/op BenchmarkByteSlice/Emit-20 36643321 34.63 ns/op 16 B/op 1 allocs/op ``` |
||
|
|
99b2206d11 |
log/logtest: add Error field to Record type (#8148)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/8147 |
||
|
|
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 |
||
|
|
5e9a80b3ce |
attribute: add BYTESLICE type support (#7948)
Fixes #7933 Add BYTES type to https://pkg.go.dev/go.opentelemetry.io/otel/attribute - Introduces BYTES type and byte - Adds Bytes / BytesValue constructors - Implements hashing support - Adds base64 representation in Emit() - Adds test coverage for constructors, hashing, and set equality ``` $ go test -run=^$ -bench=BenchmarkByteSlice goos: linux goarch: amd64 pkg: go.opentelemetry.io/otel/attribute cpu: 13th Gen Intel(R) Core(TM) i7-13800H BenchmarkByteSlice/Value-20 149529567 7.993 ns/op 0 B/op 0 allocs/op BenchmarkByteSlice/KeyValue-20 136973736 8.768 ns/op 0 B/op 0 allocs/op BenchmarkByteSlice/AsByteSlice-20 562915658 2.120 ns/op 0 B/op 0 allocs/op BenchmarkByteSlice/Emit-20 29149410 40.26 ns/op 16 B/op 1 allocs/op PASS ``` --------- Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> Co-authored-by: Robert Pająk <pellared@hotmail.com> |
||
|
|
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> |
||
|
|
5e363de517 |
limit response body size for OTLP HTTP exporters (#8108)
Per https://github.com/open-telemetry/opentelemetry-proto/pull/781 |
||
|
|
35214b6013 |
Use an absolute path when calling bsd kenv (#8113)
Co-authored-by: Robert Pająk <pellared@hotmail.com> |
||
|
|
e70658e098 |
fix: support getBody in otelploghttp (#8096)
Based on #7931 Adding another `getBody` PR to the chain 😄. This one is harder to catch if it's a problem since logs aren't being sent in case of error. --------- Signed-off-by: Toma Puljak <toma.puljak@hotmail.com> Co-authored-by: Robert Pająk <pellared@hotmail.com> Co-authored-by: Damien Mathieu <42@dmathieu.com> |
||
|
|
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
```
|
||
|
|
015ed1a7a4 |
sdk/metric: Support specifying cardinality limits per instrument kinds (#7855)
Previously, we only had `WithCardinalityLimit()`, which adds a global cardinality limit. This PR adds a new API on the reader `WithCardinalityLimitSelector` that can be used to specify limits per instrument kinds. [spec](https://github.com/open-telemetry/opentelemetry-specification/blob/49845849d2d8df07059f82033f39e96c561927cf/specification/metrics/sdk.md?plain=1#L1282) [schema](https://github.com/open-telemetry/opentelemetry-configuration/blob/3dbebe292912f0c0c96ce5dcfefc45dfe5e20f39/snippets/CardinalityLimits_kitchen_sink.yaml#L11-L18) closes #7786 --------- Co-authored-by: David Ashpole <dashpole@google.com> Co-authored-by: Damien Mathieu <42@dmathieu.com> |
||
|
|
528ebabbf0 |
sdk/trace/internal/observ: guard SpanStarted and spanLive with Enabled (#8067)
Guards SpanStarted and spanLive with Enabled(ctx) to avoid building metric options/attributes when instruments are disabled. ``` BenchmarkTracer (noop MeterProvider): SpanStarted: ~1.77 ns/op -> ~0.48 ns/op (~3.7x) SpanLive: ~2.05 ns/op -> ~0.52 ns/op (~3.9x) SpanEnded: ~2.05 ns/op -> ~0.52 ns/op (~3.9x) ``` No behavior change when enabled; existing tests cover enabled path. ~~No CHANGELOG entry, following #7848.~~ Issue: #7800 --------- Co-authored-by: Damien Mathieu <42@dmathieu.com> |
||
|
|
025b01be59 |
Add support for the development per-series starttime feature (#8060)
Add a feature to use per-series start times to match the spec: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#start-timestamps This is a prerequisite to [finishing / closing](https://github.com/open-telemetry/opentelemetry-specification/pull/4702). Previous prototype: https://github.com/open-telemetry/opentelemetry-go/pull/7719 --------- Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> Co-authored-by: Robert Pająk <pellared@hotmail.com> |
||
|
|
d5f403cab5 |
sdk/resource: add WithContext variants for Default and Environment (#7808) (#8051)
## Description Address issue #7808 by plumbing `context.Context` through `resource.Environment` and `resource.Default`. Currently, these functions hardcode `context.Background()`, which prevents detectors (especially those that might perform network lookups or OS calls) from respecting timeouts or cancellations provided by the caller. ## Changes - Adds `EnvironmentWithContext(ctx context.Context)` as a new public function. - Adds `DefaultWithContext(ctx context.Context)` as a new public function. - Maintains backward compatibility by making `Environment()` and `Default()` thin wrappers around the new WithContext variants. ## Testing - Added unit tests in `sdk/resource/resource_test.go` to verify the new functions. - Verified that all `sdk/resource` tests pass. - Verified that make `golangci-lint` passes repository-wide. Fixes #7808 --------- Co-authored-by: Damien Mathieu <42@dmathieu.com> |
||
|
|
206ac291d0 |
Fix race in the lastvalue aggregation where 0 could be observed (#8056)
This initializes the value of the gauge with the correct value before it is stored in the map. We end up storing the same thing twice on the first call, but that isn't a big deal performance-wise. Discovered during https://github.com/open-telemetry/opentelemetry-go/pull/8021 |
||
|
|
2ffde5a428 |
trace: add Random Trace ID Flag (#8012)
## Summary Adds API support for the W3C tracecontext random flag on `TraceFlags` and `SpanContext` in `go.opentelemetry.io/otel/trace`: - **`TraceFlags.IsRandom()`** — reports whether the random bit is set - **`TraceFlags.WithRandom(bool)`** — sets or clears the random bit in a copy of the flags - **`SpanContext.IsRandom()`** — reports whether the random bit is set in the span context's trace flags These mirror the existing `IsSampled` / `WithSampled` pattern. ## Motivation The W3C Trace Context spec defines a random bit in trace flags to indicate probabilistic sampling. This is required for [TraceIdRatioBased sampler](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#traceidratiobased) support, where the random bit is set when a trace is probabilistically sampled and is used for extrapolated span metrics. ## Related Part of #7928 (Support TraceIdRatioBased Sampler). This PR adds the trace API needed for that work; sampler implementation and tracestate `th` handling will follow in separate PRs. ## Co-Author Joshua MacDonald <jmacd@users.noreply.github.com> --------- Co-authored-by: Joshua MacDonald <jmacd@users.noreply.github.com> Co-authored-by: Robert Pająk <pellared@hotmail.com> Co-authored-by: Damien Mathieu <42@dmathieu.com> |
||
|
|
9587c57d48 |
Optimize attribute slice conversion (#8039)
This PR refactors the internal slice conversion helpers in
`attribute/internal` to use generics and adds explicit short-length fast
paths for slice-backed attribute values.
The main changes are:
- replace the old type-specific internal helpers with generic
`SliceValue[T]` and `AsSlice[T]`
- preserve the comparable-array storage model used by `Value` and
`KeyValue`
- add fixed-size fast paths for lengths `0..3`
- add a matching short-length fast path in `IntSliceValue` before
falling back to `[]int64` conversion
- keep reflection as the fallback for larger slice lengths
- keep the existing `Value.As*Slice()` methods in `attribute` as thin
wrappers over the generic internal helpers
- add type-mismatch coverage for `AsSlice[T]`
- expand the benchmark suite so it measures both:
- short slices that hit the new fixed-size path
- longer slices that still use the reflective fallback
## Rationale
The package still needs reflection for arbitrary runtime lengths because
slice values are stored as comparable arrays behind `any`, and Go cannot
construct a runtime-sized array type without `reflect.ArrayOf`.
The fast path is intentionally small. The cutoff of `0..3` is based on a
combination of:
- benchmark gains for short slices
- semantic convention examples where `1..3` values are common
- downstream source analysis, which found that most external call sites
pass variables rather than inline literals, so static source scanning
does not justify a larger cutoff
## External Usage Validation
Downstream scan:
- sampled repos cloned and scanned: `285`
- most external call sites pass dynamic slice variables, not inline
literals
- final literal counts recovered statically:
- `StringSlice`: total `131`, dynamic `121`, literal len `0`: `1`, len
`1`: `8`, len `2`: `1`
- `IntSlice`: total `5`, all dynamic
- `Int64Slice`: total `6`, all dynamic
- `BoolSlice`: total `3`, all dynamic
- `Float64Slice`: total `3`, all dynamic
Semantic conventions reviewed locally in `semantic-conventions` include
several slice-valued attributes where short lists are normal, for
example:
- `browser.brands`
- `gen_ai.request.stop_sequences`
- `gen_ai.request.encoding_formats`
- `gen_ai.response.finish_reasons`
- `user.roles`
- `file.attributes`
There are also clearly unbounded cases like headers, metadata, command
args, and some cloud/provider arrays. That combination supports a small
fast path, but not an assumption that all real-world slices are tiny.
## Benchmarks
Changes to the benchmarks:
- internal microbenchmarks now run both `Len2` and `Len8`
- public `attribute` benchmarks now run both `Len2` and `Len8`
- repeated benchmark runs were compared with `benchstat`
`Len2` exercises the new fixed-size path. `Len8` exercises the
reflective fallback path.
Headline result:
- short slices improve substantially
- large slices stay close to baseline because they still use reflection
- `IntSlice` now gets the same short-slice win as the other slice types,
but larger `[]int` values still pay the `[]int` to `[]int64` conversion
cost
### Internal Helpers
```text
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/attribute/internal
cpu: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
│ /tmp/bench-internal-base-v2.txt │ /tmp/bench-internal-current-v2.txt │
│ sec/op │ sec/op vs base │
BoolSliceValue/Len2-8 124.00n ± 4% 19.36n ± 12% -84.39% (p=0.000 n=12)
BoolSliceValue/Len8-8 129.9n ± 2% 136.8n ± 3% +5.31% (p=0.000 n=12)
Int64SliceValue/Len2-8 146.00n ± 26% 26.13n ± 3% -82.10% (p=0.000 n=12)
Int64SliceValue/Len8-8 172.1n ± 4% 174.9n ± 5% ~ (p=0.443 n=12)
Float64SliceValue/Len2-8 151.70n ± 2% 26.25n ± 2% -82.70% (p=0.000 n=12)
Float64SliceValue/Len8-8 173.6n ± 2% 169.7n ± 4% ~ (p=0.155 n=12)
StringSliceValue/Len2-8 177.15n ± 2% 42.03n ± 3% -76.27% (p=0.000 n=12)
StringSliceValue/Len8-8 217.2n ± 6% 219.1n ± 6% ~ (p=0.504 n=12)
AsFloat64Slice/Len2-8 96.77n ± 3% 63.05n ± 27% -34.84% (p=0.000 n=12)
AsFloat64Slice/Len8-8 123.8n ± 18% 117.1n ± 4% ~ (p=1.000 n=12)
geomean 147.6n 71.85n -51.33%
│ /tmp/bench-internal-base-v2.txt │ /tmp/bench-internal-current-v2.txt │
│ B/op │ B/op vs base │
BoolSliceValue/Len2-8 4.000 ± 0% 2.000 ± 0% -50.00% (p=0.000 n=12)
BoolSliceValue/Len8-8 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=12) ¹
Int64SliceValue/Len2-8 32.00 ± 0% 16.00 ± 0% -50.00% (p=0.000 n=12)
Int64SliceValue/Len8-8 128.0 ± 0% 128.0 ± 0% ~ (p=1.000 n=12) ¹
Float64SliceValue/Len2-8 32.00 ± 0% 16.00 ± 0% -50.00% (p=0.000 n=12)
Float64SliceValue/Len8-8 128.0 ± 0% 128.0 ± 0% ~ (p=1.000 n=12) ¹
StringSliceValue/Len2-8 64.00 ± 0% 32.00 ± 0% -50.00% (p=0.000 n=12)
StringSliceValue/Len8-8 256.0 ± 0% 256.0 ± 0% ~ (p=1.000 n=12) ¹
AsFloat64Slice/Len2-8 40.00 ± 0% 40.00 ± 0% ~ (p=1.000 n=12) ¹
AsFloat64Slice/Len8-8 88.00 ± 0% 88.00 ± 0% ~ (p=1.000 n=12) ¹
geomean 47.77 36.21 -24.21%
¹ all samples are equal
│ /tmp/bench-internal-base-v2.txt │ /tmp/bench-internal-current-v2.txt │
│ allocs/op │ allocs/op vs base │
BoolSliceValue/Len2-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
BoolSliceValue/Len8-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
Int64SliceValue/Len2-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
Int64SliceValue/Len8-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
Float64SliceValue/Len2-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
Float64SliceValue/Len8-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
StringSliceValue/Len2-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
StringSliceValue/Len8-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
AsFloat64Slice/Len2-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
AsFloat64Slice/Len8-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
geomean 2.000 1.516 -24.21%
¹ all samples are equal
```
### Public `attribute` API
```text
goos: linux
goarch: amd64
pkg: go.opentelemetry.io/otel/attribute
cpu: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
│ /tmp/bench-attr-base-v2.txt │ /tmp/bench-attr-current-v3.txt │
│ sec/op │ sec/op vs base │
BoolSlice/Len2/Value-8 130.65n ± 3% 16.90n ± 3% -87.06% (p=0.000 n=12)
BoolSlice/Len2/KeyValue-8 135.85n ± 14% 23.49n ± 2% -82.71% (p=0.000 n=12)
BoolSlice/Len2/AsBoolSlice-8 50.22n ± 1% 19.12n ± 15% -61.92% (p=0.000 n=12)
BoolSlice/Len2/Emit-8 343.9n ± 1% 293.4n ± 1% -14.68% (p=0.000 n=12)
BoolSlice/Len8/Value-8 134.7n ± 2% 136.4n ± 2% +1.22% (p=0.011 n=12)
BoolSlice/Len8/KeyValue-8 137.7n ± 2% 140.6n ± 2% +2.11% (p=0.046 n=12)
BoolSlice/Len8/AsBoolSlice-8 53.59n ± 22% 61.15n ± 22% +14.11% (p=0.020 n=12)
BoolSlice/Len8/Emit-8 773.5n ± 1% 788.5n ± 2% +1.93% (p=0.028 n=12)
IntSlice/Len2/Value-8 140.85n ± 2% 36.20n ± 3% -74.30% (p=0.000 n=12)
IntSlice/Len2/KeyValue-8 149.65n ± 2% 42.84n ± 3% -71.37% (p=0.000 n=12)
IntSlice/Len2/Emit-8 318.2n ± 3% 279.6n ± 15% -12.15% (p=0.012 n=12)
IntSlice/Len8/Value-8 217.9n ± 1% 228.8n ± 2% +5.00% (p=0.001 n=12)
IntSlice/Len8/KeyValue-8 225.6n ± 29% 232.3n ± 3% ~ (p=0.767 n=12)
IntSlice/Len8/Emit-8 480.0n ± 1% 478.6n ± 2% ~ (p=0.899 n=12)
Int64Slice/Len2/Value-8 150.90n ± 1% 27.43n ± 3% -81.82% (p=0.000 n=12)
Int64Slice/Len2/KeyValue-8 152.05n ± 1% 34.34n ± 3% -77.42% (p=0.000 n=12)
Int64Slice/Len2/AsInt64Slice-8 58.69n ± 4% 28.58n ± 3% -51.30% (p=0.000 n=12)
Int64Slice/Len2/Emit-8 318.4n ± 3% 273.9n ± 1% -13.99% (p=0.000 n=12)
Int64Slice/Len8/Value-8 173.0n ± 8% 177.8n ± 2% ~ (p=0.173 n=12)
Int64Slice/Len8/KeyValue-8 184.0n ± 24% 184.3n ± 2% ~ (p=0.701 n=12)
Int64Slice/Len8/AsInt64Slice-8 72.04n ± 2% 83.05n ± 2% +15.30% (p=0.000 n=12)
Int64Slice/Len8/Emit-8 474.9n ± 19% 501.9n ± 18% +5.67% (p=0.020 n=12)
Float64Slice/Len2/Value-8 150.95n ± 3% 26.92n ± 3% -82.17% (p=0.000 n=12)
Float64Slice/Len2/KeyValue-8 153.95n ± 3% 33.08n ± 2% -78.52% (p=0.000 n=12)
Float64Slice/Len2/AsFloat64Slice-8 60.31n ± 24% 27.02n ± 1% -55.19% (p=0.000 n=12)
Float64Slice/Len2/Emit-8 434.2n ± 2% 380.4n ± 1% -12.40% (p=0.000 n=12)
Float64Slice/Len8/Value-8 173.7n ± 2% 175.2n ± 25% ~ (p=0.248 n=12)
Float64Slice/Len8/KeyValue-8 174.0n ± 4% 175.2n ± 2% ~ (p=0.702 n=12)
Float64Slice/Len8/AsFloat64Slice-8 71.17n ± 8% 78.00n ± 4% +9.58% (p=0.007 n=12)
Float64Slice/Len8/Emit-8 920.6n ± 20% 909.9n ± 8% ~ (p=0.378 n=12)
StringSlice/Len2/Value-8 174.00n ± 5% 41.97n ± 20% -75.88% (p=0.000 n=12)
StringSlice/Len2/KeyValue-8 179.85n ± 2% 46.76n ± 2% -74.00% (p=0.000 n=12)
StringSlice/Len2/AsStringSlice-8 76.03n ± 5% 39.83n ± 3% -47.61% (p=0.000 n=12)
StringSlice/Len2/Emit-8 386.0n ± 2% 332.3n ± 3% -13.91% (p=0.000 n=12)
StringSlice/Len8/Value-8 225.4n ± 4% 226.2n ± 4% ~ (p=0.311 n=12)
StringSlice/Len8/KeyValue-8 228.1n ± 7% 234.2n ± 4% ~ (p=0.386 n=12)
StringSlice/Len8/AsStringSlice-8 110.8n ± 25% 117.8n ± 4% ~ (p=0.173 n=12)
StringSlice/Len8/Emit-8 658.7n ± 3% 647.9n ± 5% ~ (p=0.319 n=12)
geomean 181.7n 110.7n -39.08%
│ /tmp/bench-attr-base-v2.txt │ /tmp/bench-attr-current-v3.txt │
│ B/op │ B/op vs base │
BoolSlice/Len2/Value-8 4.000 ± 0% 2.000 ± 0% -50.00% (p=0.000 n=12)
BoolSlice/Len2/KeyValue-8 4.000 ± 0% 2.000 ± 0% -50.00% (p=0.000 n=12)
BoolSlice/Len2/AsBoolSlice-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
BoolSlice/Len2/Emit-8 40.00 ± 0% 40.00 ± 0% ~ (p=1.000 n=12) ¹
BoolSlice/Len8/Value-8 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=12) ¹
BoolSlice/Len8/KeyValue-8 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=12) ¹
BoolSlice/Len8/AsBoolSlice-8 8.000 ± 0% 8.000 ± 0% ~ (p=1.000 n=12) ¹
BoolSlice/Len8/Emit-8 88.00 ± 0% 88.00 ± 0% ~ (p=1.000 n=12) ¹
IntSlice/Len2/Value-8 32.00 ± 0% 16.00 ± 0% -50.00% (p=0.000 n=12)
IntSlice/Len2/KeyValue-8 32.00 ± 0% 16.00 ± 0% -50.00% (p=0.000 n=12)
IntSlice/Len2/Emit-8 56.00 ± 0% 56.00 ± 0% ~ (p=1.000 n=12) ¹
IntSlice/Len8/Value-8 128.0 ± 0% 192.0 ± 0% +50.00% (p=0.000 n=12)
IntSlice/Len8/KeyValue-8 128.0 ± 0% 192.0 ± 0% +50.00% (p=0.000 n=12)
IntSlice/Len8/Emit-8 136.0 ± 0% 136.0 ± 0% ~ (p=1.000 n=12) ¹
Int64Slice/Len2/Value-8 32.00 ± 0% 16.00 ± 0% -50.00% (p=0.000 n=12)
Int64Slice/Len2/KeyValue-8 32.00 ± 0% 16.00 ± 0% -50.00% (p=0.000 n=12)
Int64Slice/Len2/AsInt64Slice-8 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=12) ¹
Int64Slice/Len2/Emit-8 56.00 ± 0% 56.00 ± 0% ~ (p=1.000 n=12) ¹
Int64Slice/Len8/Value-8 128.0 ± 0% 128.0 ± 0% ~ (p=1.000 n=12) ¹
Int64Slice/Len8/KeyValue-8 128.0 ± 0% 128.0 ± 0% ~ (p=1.000 n=12) ¹
Int64Slice/Len8/AsInt64Slice-8 64.00 ± 0% 64.00 ± 0% ~ (p=1.000 n=12) ¹
Int64Slice/Len8/Emit-8 136.0 ± 0% 136.0 ± 0% ~ (p=1.000 n=12) ¹
Float64Slice/Len2/Value-8 32.00 ± 0% 16.00 ± 0% -50.00% (p=0.000 n=12)
Float64Slice/Len2/KeyValue-8 32.00 ± 0% 16.00 ± 0% -50.00% (p=0.000 n=12)
Float64Slice/Len2/AsFloat64Slice-8 16.00 ± 0% 16.00 ± 0% ~ (p=1.000 n=12) ¹
Float64Slice/Len2/Emit-8 56.00 ± 0% 56.00 ± 0% ~ (p=1.000 n=12) ¹
Float64Slice/Len8/Value-8 128.0 ± 0% 128.0 ± 0% ~ (p=1.000 n=12) ¹
Float64Slice/Len8/KeyValue-8 128.0 ± 0% 128.0 ± 0% ~ (p=1.000 n=12) ¹
Float64Slice/Len8/AsFloat64Slice-8 64.00 ± 0% 64.00 ± 0% ~ (p=1.000 n=12) ¹
Float64Slice/Len8/Emit-8 136.0 ± 0% 136.0 ± 0% ~ (p=1.000 n=12) ¹
StringSlice/Len2/Value-8 64.00 ± 0% 32.00 ± 0% -50.00% (p=0.000 n=12)
StringSlice/Len2/KeyValue-8 64.00 ± 0% 32.00 ± 0% -50.00% (p=0.000 n=12)
StringSlice/Len2/AsStringSlice-8 32.00 ± 0% 32.00 ± 0% ~ (p=1.000 n=12) ¹
StringSlice/Len2/Emit-8 120.0 ± 0% 120.0 ± 0% ~ (p=1.000 n=12) ¹
StringSlice/Len8/Value-8 256.0 ± 0% 256.0 ± 0% ~ (p=1.000 n=12) ¹
StringSlice/Len8/KeyValue-8 256.0 ± 0% 256.0 ± 0% ~ (p=1.000 n=12) ¹
StringSlice/Len8/AsStringSlice-8 128.0 ± 0% 128.0 ± 0% ~ (p=1.000 n=12) ¹
StringSlice/Len8/Emit-8 344.0 ± 0% 344.0 ± 0% ~ (p=1.000 n=12) ¹
geomean 49.39 42.05 -14.88%
¹ all samples are equal
│ /tmp/bench-attr-base-v2.txt │ /tmp/bench-attr-current-v3.txt │
│ allocs/op │ allocs/op vs base │
BoolSlice/Len2/Value-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
BoolSlice/Len2/KeyValue-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
BoolSlice/Len2/AsBoolSlice-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=12) ¹
BoolSlice/Len2/Emit-8 5.000 ± 0% 5.000 ± 0% ~ (p=1.000 n=12) ¹
BoolSlice/Len8/Value-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
BoolSlice/Len8/KeyValue-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
BoolSlice/Len8/AsBoolSlice-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=12) ¹
BoolSlice/Len8/Emit-8 11.00 ± 0% 11.00 ± 0% ~ (p=1.000 n=12) ¹
IntSlice/Len2/Value-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
IntSlice/Len2/KeyValue-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
IntSlice/Len2/Emit-8 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=12) ¹
IntSlice/Len8/Value-8 2.000 ± 0% 3.000 ± 0% +50.00% (p=0.000 n=12)
IntSlice/Len8/KeyValue-8 2.000 ± 0% 3.000 ± 0% +50.00% (p=0.000 n=12)
IntSlice/Len8/Emit-8 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=12) ¹
Int64Slice/Len2/Value-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
Int64Slice/Len2/KeyValue-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
Int64Slice/Len2/AsInt64Slice-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=12) ¹
Int64Slice/Len2/Emit-8 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=12) ¹
Int64Slice/Len8/Value-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
Int64Slice/Len8/KeyValue-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
Int64Slice/Len8/AsInt64Slice-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=12) ¹
Int64Slice/Len8/Emit-8 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=12) ¹
Float64Slice/Len2/Value-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
Float64Slice/Len2/KeyValue-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
Float64Slice/Len2/AsFloat64Slice-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=12) ¹
Float64Slice/Len2/Emit-8 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=12) ¹
Float64Slice/Len8/Value-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
Float64Slice/Len8/KeyValue-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
Float64Slice/Len8/AsFloat64Slice-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=12) ¹
Float64Slice/Len8/Emit-8 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=12) ¹
StringSlice/Len2/Value-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
StringSlice/Len2/KeyValue-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=12)
StringSlice/Len2/AsStringSlice-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=12) ¹
StringSlice/Len2/Emit-8 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=12) ¹
StringSlice/Len8/Value-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
StringSlice/Len8/KeyValue-8 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=12) ¹
StringSlice/Len8/AsStringSlice-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=12) ¹
StringSlice/Len8/Emit-8 4.000 ± 0% 4.000 ± 0% ~ (p=1.000 n=12) ¹
geomean 2.143 1.824 -14.88%
¹ all samples are equal
```
## Notes
- `Len2` is where the wins show up because those calls avoid
`reflect.ArrayOf` and one allocation.
- `Len8` stays much closer to baseline because it still uses the
reflective path.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: David Ashpole <dashpole@google.com>
|
||
|
|
ddd2b0e398 |
fix(sdk/trace): return spec-compliant TraceIdRatioBased description (#8027)
Optimize performance when sampling is disabled - no need to calculate fraction based on trace id (in `traceIDRatioSampler`) if fraction is zero. --------- Co-authored-by: David Ashpole <dashpole@google.com> Co-authored-by: Damien Mathieu <42@dmathieu.com> |
||
|
|
f4da59e651 |
attribute: change INVALID Type to EMPTY and mark INVALID as deprecated (#8038)
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/7932 Noticeable comment from previous PR: https://github.com/open-telemetry/opentelemetry-go/pull/7942#discussion_r2913179215 Print the empty value as empty string per https://opentelemetry.io/docs/specs/otel/common/#empty-values |
||
|
|
fabe66658f |
resource: add WithService detector option (#7642)
I was looking at implementing resource detection in otelconf and was finding that all the detectors were implemented in a similar way except for the service detector. Added the resource options in this PR for feedback. Will add tests if the go approvers/maintainers support this approach. --------- Signed-off-by: alex boten <223565+codeboten@users.noreply.github.com> Co-authored-by: Damien Mathieu <42@dmathieu.com> |
||
|
|
a3941ff595 |
Release v1.42.0/v0.64.0/v0.18.0/v0.0.16 (#8006)
### Added - Add `go.opentelemetry.io/otel/semconv/v1.40.0` package. The package contains semantic conventions from the `v1.40.0` version of the OpenTelemetry Semantic Conventions. See the [migration documentation](./semconv/v1.40.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.39.0`. (#7985) - Add `Err` and `SetErr` on `Record` in `go.opentelemetry.io/otel/log` to attach an error and set record exception attributes in `go.opentelemetry.io/otel/log/sdk`. (#7924) ### Changed - `TracerProvider.ForceFlush` in `go.opentelemetry.io/otel/sdk/trace` joins errors together and continues iteration through SpanProcessors as opposed to returning the first encountered error without attempting exports on subsequent SpanProcessors. (#7856) ### Fixed - Fix missing `request.GetBody` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` to correctly handle HTTP2 GOAWAY frame. (#7931) - Fix semconv v1.39.0 generated metric helpers skipping required attributes when extra attributes were empty. (#7964) - Preserve W3C TraceFlags bitmask (including the random Trace ID flag) during trace context extraction and injection in `go.opentelemetry.io/otel/propagation`. (#7834) ### Removed - Drop support for [Go 1.24]. (#7984) |
||
|
|
c9d20155fc |
log: add error field to Record and make SDK to emit exception attributes (#7924)
Fixes #7923 ```sh $ go test -run=^$ -bench=BenchmarkLoggerEmitExceptionAttributes -benchmem -count=5 -benchtime=500ms -cpu=1 goos: darwin goarch: arm64 pkg: go.opentelemetry.io/otel/sdk/log cpu: Apple M4 Pro BenchmarkLoggerSetErrAndEmit 628162 1023 ns/op 5371 B/op 1 allocs/op BenchmarkLoggerSetErrAndEmit 663955 863.3 ns/op 5105 B/op 1 allocs/op BenchmarkLoggerSetErrAndEmit 653888 1067 ns/op 5177 B/op 1 allocs/op BenchmarkLoggerSetErrAndEmit 716438 824.8 ns/op 4764 B/op 1 allocs/op BenchmarkLoggerSetErrAndEmit 746902 999.2 ns/op 5630 B/op 1 allocs/op BenchmarkLoggerSetExceptionAttributesAndEmit 650696 1042 ns/op 5200 B/op 1 allocs/op BenchmarkLoggerSetExceptionAttributesAndEmit 574962 980.7 ns/op 4743 B/op 1 allocs/op BenchmarkLoggerSetExceptionAttributesAndEmit 536736 989.2 ns/op 5049 B/op 1 allocs/op BenchmarkLoggerSetExceptionAttributesAndEmit 558511 1190 ns/op 4870 B/op 1 allocs/op BenchmarkLoggerSetExceptionAttributesAndEmit 669452 978.8 ns/op 5067 B/op 1 allocs/op PASS ok go.opentelemetry.io/otel/sdk/log 6.994s ``` TODO after merged: - https://github.com/open-telemetry/opentelemetry-go/pull/7924#discussion_r2832906451 --------- Signed-off-by: Israel Blancas <iblancasa@gmail.com> Co-authored-by: Robert Pająk <pellared@hotmail.com> Co-authored-by: Damien Mathieu <42@dmathieu.com> |