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>
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.
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.
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>
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>
## 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>
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
## 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>
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>
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>
### 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)
Previously upon a SpanProcessor's ForceFlush returning an error, it
would return that error and not attempt to flush subsequent
SpanProcessors. Now when an error is encountered, it will Join the new
error with the existing errors and continue iterating through the
SpanProcessors and return the consolidated error at the end of
iteration. This is in line with the workflow found in LoggerProvider's
ForceFlush.
---------
Co-authored-by: Robert Pająk <pellared@hotmail.com>
Problem
- The Go SDK masks trace flags to the sampled bit and rejects version 00
flags > 0x02.
- This drops the W3C Trace Context Level 2 random Trace ID flag (0x02)
and any forward-compatible bits.
Approach
- Treat trace flags as an 8-bit bitmask across extract, storage, and
inject.
- Accept any flags for traceparent version 00 and preserve them
unchanged.
- Interpret only known bits for behavior (sampling uses 0x01); do not
change sampling logic.
Implementation details
- propagation/trace_context.go
- Inject: emit sc.TraceFlags() without masking.
- Extract: remove opts[0] > 2 rejection; store full flags byte in
SpanContextConfig.TraceFlags.
- propagation/trace_context_test.go
- Add extract cases for 0x02 and 0x03; ensure 0x09 is preserved.
- Remove "unused bits set" from invalid cases.
- Inject cases preserve 0xff, 0x02, and 0x03.
- Future-version flag tests now expect full byte, not masked.
Closes#7635
---------
Co-authored-by: Damien Mathieu <42@dmathieu.com>
This is related to issue #7938.
### The Bug
Semconv code generator Jinja2 template (instrument.j2) had an early
return optimization that skipped required attributes when no extra
optional attributes were passed.
The root cause seemed to be two macros in
semconv/templates/registry/go/instrument.j2:
- add_method_with_optional (for counters/updowncounters)
- record_method_with_optional (for histograms/gauges)
Both had `if len(attrs) == 0 { m.Inst.Add(ctx, incr); return }`, which
bypassed required attributes entirely.
### The Fix
I added a conditional check to verify when required attributes exist
`(req_attr | length > 0)`, the early return now passes them via
metric.WithAttributes(...). When there are no required attributes, the
original fast path is preserved.
I also regenerated the semconv `v1.39.0`, but if thats not desired due
to existing clients, let me know. It is my first time contributing here
and any feedback is appreciated!
---------
Co-authored-by: Robert Pająk <pellared@hotmail.com>
Based on https://github.com/open-telemetry/opentelemetry-go/pull/7794
This solves the exact same problem but on metrics.
> traces export: Post "https://***/v1/metrics": http2: Transport: cannot
retry err [http2: Transport received Server's graceful shutdown GOAWAY]
after Request.Body was written; define Request.GetBody to avoid this
error
---------
Co-authored-by: Damien Mathieu <42@dmathieu.com>
This release is the last to support [Go 1.24].
The next release will require at least [Go 1.25].
### Added
- Support testing of [Go 1.26]. (#7902)
### Fixed
- Update `Baggage` in `go.opentelemetry.io/otel/propagation` and `Parse`
and `New` in `go.opentelemetry.io/otel/baggage` to comply with W3C
Baggage specification limits.
`New` and `Parse` now return partial baggage along with an error when
limits are exceeded.
Errors from baggage extraction are reported to the global error handler.
(#7880)
[Go 1.26]: https://go.dev/doc/go1.26
[Go 1.25]: https://go.dev/doc/go1.25
[Go 1.24]: https://go.dev/doc/go1.24
## Summary
This PR moves the `insecure + TLS config` validation into the core OTLP
HTTP exporters in `opentelemetry-go` (trace, metric, and log), instead
of relying on validation in external/config-wrapper code.
This aligns with feedback from `open-telemetry/opentelemetry-go-contrib`
PR https://github.com/open-telemetry/opentelemetry-go-contrib/pull/8560:
these packages are maintained/released together, so the check should be
enforced in this repo as well.
## What changed
- Added exporter-level validation error:
- `"insecure HTTP endpoint cannot use TLS client configuration"`
- Enforced in:
- `otlpmetrichttp` client construction
- `otlploghttp` client construction
- `otlptracehttp` client startup (`Start`, since `NewClient` does not
return an error)
- Added tests in all three exporters to cover:
- Error when `WithInsecure()` and `WithTLSClientConfig(...)` are both
set
- No error when a custom `WithHTTPClient(...)` is provided (preserves
existing precedence semantics)
## Behavior
- Invalid config (`insecure` + TLS config) now fails fast directly in
exporters.
- Existing `WithHTTPClient` override behavior remains unchanged.
## Testing
Ran:
- `go test ./...` in `exporters/otlp/otlpmetric/otlpmetrichttp`
- `go test ./...` in `exporters/otlp/otlplog/otlploghttp`
- `go test ./...` in `exporters/otlp/otlptrace/otlptracehttp`
## Related
- `open-telemetry/opentelemetry-go-contrib` PR
(https://github.com/open-telemetry/opentelemetry-go-contrib/pull/8560)
---------
Co-authored-by: Damien Mathieu <42@dmathieu.com>
Updates the baggage implementation to comply with
https://www.w3.org/TR/baggage/#limits:
- Changed maxMembers from 180 to 64 (the W3C compliance requirement)
> The resulting baggage-string contains 64 list-members or less.
- Removed maxBytesPerMembers (4096) - this per-member limit was not part
of the W3C spec
- Added limit checking in extractMultiBaggage for multiple baggage
headers:
- Checks combined byte size across all headers (max 8192 bytes)
- Checks combined member count across all headers (max 64 members)
This uses non-deterministic truncation when handling baggage limits.
### Added
- Add `Enabled` method to all synchronous instrument interfaces
(`Float64Counter`, `Float64UpDownCounter`, `Float64Histogram`,
`Float64Gauge`, `Int64Counter`, `Int64UpDownCounter`, `Int64Histogram`,
`Int64Gauge`,) in `go.opentelemetry.io/otel/metric`. This stabilizes the
synchronous instrument enabled feature, allowing users to check if an
instrument will process measurements before performing computationally
expensive operations. (#7763)
- Add `AlwaysRecord` sampler in `go.opentelemetry.io/otel/sdk/trace`.
(#7724)
- Add `go.opentelemetry.io/otel/semconv/v1.39.0` package. The package
contains semantic conventions from the `v1.39.0` version of the
OpenTelemetry Semantic Conventions. See the [migration
documentation](https://github.com/open-telemetry/opentelemetry-go/blob/298cbedf256b7a9ab3c21e41fc5e3e6d6e4e94aa/semconv/v1.39.0/MIGRATION.md)
for information on how to upgrade from
`go.opentelemetry.io/otel/semconv/v1.38.0.` (#7783, #7789)
### Changed
- `Exporter` in `go.opentelemetry.io/otel/exporter/prometheus` ignores
metrics with the scope `go.opentelemetry.io/contrib/bridges/prometheus`.
This prevents scrape failures when the Prometheus exporter is
misconfigured to get data from the Prometheus bridge. (#7688)
- Improve performance of concurrent histogram measurements in
`go.opentelemetry.io/otel/sdk/metric`. (#7474)
- Add experimental observability metrics in
`go.opentelemetry.io/otel/exporters/stdout/stdoutmetric`. (#7492)
- Improve the concurrent performance of `HistogramReservoir` in
`go.opentelemetry.io/otel/sdk/metric/exemplar` by 4x. (#7443)
- Improve performance of concurrent synchronous gauge measurements in
`go.opentelemetry.io/otel/sdk/metric`. (#7478)
- Improve performance of concurrent exponential histogram measurements
in `go.opentelemetry.io/otel/sdk/metric`. (#7702)
- Improve the concurrent performance of `FixedSizeReservoir` in
`go.opentelemetry.io/otel/sdk/metric/exemplar`. (#7447)
- The `rpc.grpc.status_code` attribute in the experimental metrics
emitted from
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` is
replaced with the `rpc.response.status_code` attribute to align with the
semantic conventions. (#7854)
- The `rpc.grpc.status_code` attribute in the experimental metrics
emitted from
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` is
replaced with the `rpc.response.status_code` attribute to align with the
semantic conventions. (#7854)
### Fixed
- Fix bad log message when key-value pairs are dropped because of key
duplication in `go.opentelemetry.io/otel/sdk/log`. (#7662)
- Fix `DroppedAttributes` on `Record` in
`go.opentelemetry.io/otel/sdk/log` to not count the non-attribute
key-value pairs dropped because of key duplication. (#7662)
- Fix `SetAttributes` on `Record` in `go.opentelemetry.io/otel/sdk/log`
to not log that attributes are dropped when they are actually not
dropped. (#7662)
- `WithHostID` detector in `go.opentelemetry.io/otel/sdk/resource` to
use full path for `ioreg` command on Darwin (macOS). (#7818)
- Fix missing `request.GetBody` in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` to
correctly handle HTTP2 GOAWAY frame. (#7794)
### Deprecated
- Deprecate `go.opentelemetry.io/otel/exporters/zipkin`. For more
information, see the [OTel blog post deprecating the Zipkin
exporter](https://opentelemetry.io/blog/2025/deprecating-zipkin-exporters/).
(#7670)
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
We're entitled to keep providing security and bug fixes until december
2026, but letting users now as soon as possible makes migrations easier.
---------
Co-authored-by: Robert Pająk <pellared@hotmail.com>
Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
Use full path when calling `ioreg` to mitigate potential malicious code
execution in case of [Path
Interception](https://attack.mitre.org/techniques/T1574/007/).
Note that path interception typically requires the attacker to influence
the environment or place a malicious executable earlier in $PATH, which,
in this context, generally implies the script itself would need to be
introduced/uploaded (or otherwise placed/executed) in the target
environment for the attacker’s substitute `ioreg` to be reached during
execution.
Reference:
- https://cwe.mitre.org/data/definitions/426.html
This is a fix for HTTP2 GOAWAY errors.
It's hard to test GOAWAY directly, but the same mechanism is used on
redirects, so the test aims to verify if the mechanism work for
redirects.
Example log error:
```
traces export: Post "https://***/v1/traces": http2: Transport: cannot retry err [http2: Transport received Server's graceful shutdown GOAWAY] after Request.Body was written; define Request.GetBody to avoid this error
```
---------
Co-authored-by: Damien Mathieu <42@dmathieu.com>
Fixes: #6983
Enhance logging and error reporting in the log record
attribute handling code, specifically around dropped attributes and
duplicate key-value pairs. The main focus is to provide clearer warnings
when key-value pairs are dropped due to duplication, and to ensure
warnings are only logged when actual drops occur.
---------
Co-authored-by: Robert Pająk <pellared@hotmail.com>