Skip to content

Conversation

@breedx-splk
Copy link
Contributor

Related to open-telemetry/opentelemetry-java-contrib#2257

It looks like there's a small issue around serializing string Attributes that contain an empty string value. Per the spec, these empty string values are important:

Attribute values expressing a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to processors / exporters.

The Serializer class special cases null and empty and treats them the same -- by returning early without actually serializing. In the case of protobuf, this is especially problematic because the proto field tag (which contains the type information!) doesn't get written. When that happens, the proto can no longer indicate that the field is a string. In addition to the crash/exception happening in the disk buffering code, this can also be seen by sending a span with an empty attribute value to the collector with verbose logging on:

Attributes:
     -> foo: Str(bar)
     -> empty: Empty()

The collector shows that the field is Empty() instead of Str().

I'm not entirely sure why this showed up recently in disk buffering, but maybe we switched the default implementation to low-allocation or something that caused this?

@breedx-splk breedx-splk marked this pull request as draft September 15, 2025 21:51
@LeadAssimilator
Copy link

I'm not entirely sure why this showed up recently in disk buffering, but maybe we switched the default implementation to low-allocation or something that caused this?

Yup that's exactly what changed between 1.48-alpha and 1.49-alpha. See open-telemetry/opentelemetry-java-contrib#2138

// time. If the lengths are equal and the resulting protos are equal, the marshaling is
// guaranteed to be valid.
assertThat(result.getSerializedSize()).isEqualTo(serialized.length);
// assertThat(result.getSerializedSize()).isEqualTo(serialized.length);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It really weirds me out that this would change...but something about the defaults causes this to fail now? Anybody know why?

Comment on lines -118 to -121
KeyValue.newBuilder()
.setKey("key")
.setValue(AnyValue.newBuilder().setStringValue("value").build())
.build())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now that there's more than one attribute, we can't rely on the order and this test fails, so it had to be reworked to sort.

@breedx-splk
Copy link
Contributor Author

Ok, I'm still very much still open to feedback on this PR, but it's very broken for some tricky reasons. After talking with @jsuereth, I have opened this spec issue: open-telemetry/opentelemetry-specification#4660

Going to close for now and pursue another approach in contrib.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants