Skip to content

attribute: add BYTES type support#7948

Open
NesterovYehor wants to merge 12 commits intoopen-telemetry:mainfrom
NesterovYehor:feat/attribute-bytes-value
Open

attribute: add BYTES type support#7948
NesterovYehor wants to merge 12 commits intoopen-telemetry:mainfrom
NesterovYehor:feat/attribute-bytes-value

Conversation

@NesterovYehor
Copy link
Contributor

@NesterovYehor NesterovYehor commented Feb 24, 2026

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='BenchmarkBytesValue|BenchmarkAsBytes' -benchmem
goos: darwin
goarch: arm64
pkg: go.opentelemetry.io/otel/attribute/internal
cpu: Apple M1
BenchmarkBytesValue-8   	17996593	        66.35 ns/op	       6 B/op	       2 allocs/op
BenchmarkAsBytes-8      	47359774	        26.59 ns/op	       2 B/op	       1 allocs/op
PASS
ok  	go.opentelemetry.io/otel/attribute/internal	2.995s
$  go test -run=^$ -bench=BenchmarkBytes -benchmem
goos: darwin
goarch: arm64
pkg: go.opentelemetry.io/otel/attribute
cpu: Apple M1
BenchmarkBytes/Value-8         	15589729	        69.47 ns/op	      32 B/op	       2 allocs/op
BenchmarkBytes/KeyValue-8      	16409461	        80.14 ns/op	      32 B/op	       2 allocs/op
BenchmarkBytes/AsBytes-8       	40278198	        29.09 ns/op	      16 B/op	       1 allocs/op
BenchmarkBytes/Emit-8          	22664637	        51.59 ns/op	      32 B/op	       2 allocs/op
PASS
ok  	go.opentelemetry.io/otel/attribute	5.180s

@codecov
Copy link

codecov bot commented Feb 24, 2026

Codecov Report

❌ Patch coverage is 83.33333% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.6%. Comparing base (bdc1b51) to head (7aa1da4).

Files with missing lines Patch % Lines
log/keyvalue.go 0.0% 3 Missing ⚠️
attribute/internal/attribute.go 83.3% 1 Missing and 1 partial ⚠️
attribute/internal/xxhash/xxhash.go 50.0% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@          Coverage Diff          @@
##            main   #7948   +/-   ##
=====================================
  Coverage   81.6%   81.6%           
=====================================
  Files        304     304           
  Lines      23446   23488   +42     
=====================================
+ Hits       19136   19174   +38     
- Misses      3928    3932    +4     
  Partials     382     382           
Files with missing lines Coverage Δ
attribute/hash.go 92.0% <100.0%> (+0.5%) ⬆️
attribute/key.go 100.0% <100.0%> (ø)
attribute/kv.go 100.0% <100.0%> (ø)
attribute/type_string.go 60.0% <ø> (ø)
attribute/value.go 92.6% <100.0%> (+0.7%) ⬆️
attribute/internal/attribute.go 86.9% <83.3%> (-1.3%) ⬇️
attribute/internal/xxhash/xxhash.go 78.5% <50.0%> (-4.8%) ⬇️
log/keyvalue.go 95.6% <0.0%> (-1.5%) ⬇️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@pellared pellared left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM. I left a few comments.
Please also add the benchmark results for ``BenchmarkBytes` in the PR description.

@pellared pellared added this to the v1.42.0 milestone Feb 24, 2026
@pellared pellared changed the title attribute: add BYTES type support [DO NOT MERGE] attribute: add BYTES type support Feb 24, 2026
@pellared pellared moved this from Todo to In Progress in Go: Logs (GA) Feb 24, 2026
@NesterovYehor NesterovYehor force-pushed the feat/attribute-bytes-value branch from 87ff3a1 to 95b2ce9 Compare February 24, 2026 22:27
@pellared pellared changed the title [DO NOT MERGE] attribute: add BYTES type support attribute: add BYTES type support Feb 25, 2026
@pellared pellared changed the title attribute: add BYTES type support [DO NOT MERGE] attribute: add BYTES type support Feb 25, 2026
@pellared
Copy link
Member

pellared commented Feb 25, 2026

@NesterovYehor

We would also need to comply with SDK attribute value limits https://opentelemetry.io/docs/specs/otel/common/#anyvalue

if it is a byte array, if its length exceeds that limit (counting each byte as 1), SDKs MUST truncate that value, so that its length is at most equal to the limit,

I propose to do this in a separate PR and also track it in a separate issue. The important thing is that both PRs would need to be shipped in the same release. If you want you can already start working it in a separate branch / draft PR

EDIT: I created #7954

@pellared pellared modified the milestones: v1.42.0, v1.41.0 Feb 26, 2026
@pellared pellared modified the milestones: v1.42.0, v1.43.0 Mar 5, 2026
@NesterovYehor NesterovYehor force-pushed the feat/attribute-bytes-value branch 2 times, most recently from e155190 to fc739fd Compare March 6, 2026 19:24
@NesterovYehor NesterovYehor force-pushed the feat/attribute-bytes-value branch from d7eb438 to eda589a Compare March 6, 2026 19:28
@pellared pellared changed the title [DO NOT MERGE] attribute: add BYTES type support attribute: add BYTES type support Mar 6, 2026
@pellared
Copy link
Member

pellared commented Mar 6, 2026

@open-telemetry/go-approvers, PTAL. This can be now merged given the recent releases.

Copy link
Contributor

@MrAlias MrAlias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good. The hashing algorithm access needs attention though.

Copy link
Member

@pellared pellared left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add support for BYTES in the OTLP exporters?
This can be done in a separate PR like #7990.

Copy link
Contributor

@dashpole dashpole left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM after @MrAlias's comments are addressed.

@NesterovYehor NesterovYehor force-pushed the feat/attribute-bytes-value branch from 02b54de to f6fff2d Compare March 11, 2026 09:11
}
case BYTES:
h = h.Uint64(bytesID)
h = h.Bytes(kv.Value.asBytes())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will allocate a new slice. Is there a way to use the reflected value to avoid this allocation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that we currently have to either allocate a new slice or hash each byte one by one. The xxhash method needs a []byte slice, but we need a fixed-size array in the Value struct to keep it comparable. So, we either allocate memory for a new slice or spend extra time hashing each byte separately.
If i understand it correctly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this motivates storing []byte not in slice any, but stringly string of the Value using the built in Go syntax to copy user provided []byte into an immutable string. That will also allow for existing string hashing algorithms to be used as well.

Importantly, the vtype will distinguish between an actual string attribute and an byte slice one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that we currently have to either allocate a new slice or hash each byte one by one. The xxhash method needs a []byte slice, but we need a fixed-size array in the Value struct to keep it comparable. So, we either allocate memory for a new slice or spend extra time hashing each byte separately. If i understand it correctly.

You should be able to return the array as slice without introducing a heap allocation. Notice that asBytes copies the whole slice/array. Note that in #7949 UnsafeAsSlice does not cause a heap allocation.

Copy link
Contributor

@MrAlias MrAlias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking base on #7948 (comment)

Investigation needs to be undertaken to storing the []byte as a string in value instead as a slice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

attribute: Add BYTES type

5 participants