Skip to content

Conversation

@trask
Copy link
Member

@trask trask commented Jan 9, 2026

No description provided.

@trask trask force-pushed the stabilize-complex-attributes-try-2 branch from 3bc8e76 to 8c951bd Compare January 9, 2026 22:32
@codecov
Copy link

codecov bot commented Jan 9, 2026

Codecov Report

❌ Patch coverage is 91.20000% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.28%. Comparing base (62049e7) to head (3b6a906).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...in/java/io/opentelemetry/api/common/ProtoJson.java 88.88% 6 Missing and 2 partials ⚠️
...metry/api/common/ArrayBackedAttributesBuilder.java 90.16% 2 Missing and 4 partials ⚠️
...pentelemetry/api/common/ArrayBackedAttributes.java 92.85% 2 Missing and 2 partials ⚠️
...n/java/io/opentelemetry/api/common/ValueEmpty.java 55.55% 4 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #7973      +/-   ##
============================================
+ Coverage     90.15%   90.28%   +0.12%     
- Complexity     7476     7606     +130     
============================================
  Files           836      839       +3     
  Lines         22550    22798     +248     
  Branches       2224     2256      +32     
============================================
+ Hits          20331    20584     +253     
+ Misses         1515     1505      -10     
- Partials        704      709       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

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

@trask trask force-pushed the stabilize-complex-attributes-try-2 branch from 30fb180 to 0e2af07 Compare January 9, 2026 23:37
@trask trask force-pushed the stabilize-complex-attributes-try-2 branch 4 times, most recently from 55d9121 to 23f5d22 Compare January 10, 2026 04:05
@trask trask force-pushed the stabilize-complex-attributes-try-2 branch from 23f5d22 to 0e19885 Compare January 10, 2026 04:15
Copy link
Member Author

Choose a reason for hiding this comment

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

changes copy-pasted from ExtendedArrayBackedAttributes.java

Copy link
Member Author

Choose a reason for hiding this comment

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

changes copy-pasted from ExtendedArrayBackedAttributesBuilder.java

Copy link
Member Author

Choose a reason for hiding this comment

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

changes copy-pasted from ExtendedAttributeKey.java

Copy link
Member Author

Choose a reason for hiding this comment

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

changes copy-pasted from ExtendedAttributes.java

Copy link
Member Author

Choose a reason for hiding this comment

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

changes copy-pasted from ExtendedAttributesBuilder.java

Copy link
Member

Choose a reason for hiding this comment

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

Is your plan to keeep ExtendedAttributes around for a couple of releases to give folks a chance to migrate gracefully?

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah, good point, deprecated them in c133eea

Copy link
Member Author

Choose a reason for hiding this comment

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

oh no, that spun out of control due to suppressing usages, reverted, I'd suggest that I do that as a follow-up PR

Comment on lines 116 to 124
// TODO(jack-berg): Should this be a JSON encoding?
// TODO deprecate in favor of toString() or toProtoJson()?
String asString();
Copy link
Member Author

Choose a reason for hiding this comment

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

open question (also could consider keeping asString() and having it emit proto json and removing toProtoJson())

Copy link
Member

Choose a reason for hiding this comment

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

Can you talk about toProtoJson() a little bit? I see it used the prometheus and zipkin exporters. Does the spec say that these exporters should encode using protobuf JSON in for extended attribute cases?

Do we have to add this functionality in the first stable release of extended attributes or can it be added later?

Also having thoughts about how we have JSON value serialization in two places: Value#toProtoJson() and AnyValueMarshaler. They're of course used in different contexts. There's probably a way to incorporate AnyValueMarshaler into ValueToProtoJsonTest to verify they're equivalent.

Copy link
Member

Choose a reason for hiding this comment

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

open question (also could consider keeping asString() and having it emit proto json and removing toProtoJson())

Yes let's do that. See my comment to the same effect here: https://github.com/open-telemetry/opentelemetry-java/pull/7973/changes#r2696282790

Copy link
Member Author

@trask trask Jan 20, 2026

Choose a reason for hiding this comment

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

just to see what it looks like, no worries if we change our mind (took me a few commits):

Copy link
Member Author

@trask trask Jan 20, 2026

Choose a reason for hiding this comment

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

Can you talk about toProtoJson() a little bit? I see it used the prometheus and zipkin exporters. Does the spec say that these exporters should encode using protobuf JSON in for extended attribute cases?

it's unclear to me, I've added topic to discuss in spec meeting

Copy link
Member Author

Choose a reason for hiding this comment

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

so I'm not sure I love asString emitting proto json, because it feels a little weird for a method named asString to emit the quotes around a string for a simple string value

I think my current preference might be your other suggestion #7973 (comment) which has the other benefit of hiding proto json representation a bit more as an exporter/sdk concern

Copy link
Member

Choose a reason for hiding this comment

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

I think my current preference might be your other suggestion #7973 (comment) which has the other benefit of hiding proto json representation a bit more as an exporter/sdk concern

If we go with the other direction we only need a simplified JSON encoding, even for exporters, right? And so we could get away with adjusting asString to return the simplified JSON encoding.

Comment on lines 393 to 396
.putTag("bytes", "\"AQID\"")
.putTag("map", "{\"nested\":\"value\"}")
.putTag("heterogeneousArray", "[\"string\",123]")
.putTag("empty", "null")
Copy link
Member Author

Choose a reason for hiding this comment

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

same questionable choices:

  • "\"AQID\"" vs "AQID"
  • "null" vs "" vs "{}"

Copy link
Member

Choose a reason for hiding this comment

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

""AQID"" vs "AQID"

Should be base64 encoded string https://protobuf.dev/programming-guides/json/

Copy link
Member

Choose a reason for hiding this comment

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

"null" vs "" vs "{}"

Should be JSON null literal

Copy link
Member Author

@trask trask Jan 20, 2026

Choose a reason for hiding this comment

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

just confirming, so you agree with the choices I made in the implementation above?

Copy link
Member Author

Choose a reason for hiding this comment

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

In open-telemetry/opentelemetry-specification#4848, I'm proposing that top-level attributes be more naturally encoded (instead of JSON encoded), so

Suggested change
.putTag("bytes", "\"AQID\"")
.putTag("map", "{\"nested\":\"value\"}")
.putTag("heterogeneousArray", "[\"string\",123]")
.putTag("empty", "null")
.putTag("bytes", "AQID")
.putTag("map", "{\"nested\":\"value\"}")
.putTag("heterogeneousArray", "[\"string\",123]")
.putTag("empty", "")


@Override
public String asString() {
return "";
Copy link
Member Author

Choose a reason for hiding this comment

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

another option would be return the string "null"

Copy link
Member

Choose a reason for hiding this comment

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

I'm fine with this for asString().

Geez I don't think we can justify having asString(), toString(), and toProtoJson() 😅. I think probably we change asString() to be the proto json encoder. I warned in the javadoc that no guarantees are made so we should be able to do this:

   * <p>WARNING: No guarantees are made about the encoding of this string response. It MAY change in
   * a future minor release. If you need a reliable string encoding, write your own serializer.

* @return a JSON encoding of this value
*/
default String toProtoJson() {
return "\"unimplemented\"";
Copy link
Member Author

Choose a reason for hiding this comment

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

alternatively could throw UnsupportedOperationException

Copy link
Member

Choose a reason for hiding this comment

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

Another alternative would be to have a static String asProtoJson(Value<?>) utility method. Is there anything in the implementations of toProtoJson that benefits from accessing the private fields?

Copy link
Member

Choose a reason for hiding this comment

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

This type of utility method could also packaged somewhere like opentelemetry-exporter-common or opentelemetry-sdk-common so opentelemetry-api doesn't need to have a class called ProtoJson in it, which is a smell.

Copy link
Member Author

Choose a reason for hiding this comment

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

This type of utility method could also packaged somewhere like opentelemetry-exporter-common or opentelemetry-sdk-common so opentelemetry-api doesn't need to have a class called ProtoJson in it, which is a smell.

just confirming you prefer to ignore this comment since it contradicts #7973 (comment)?

Copy link
Member Author

@trask trask Jan 20, 2026

Choose a reason for hiding this comment

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

having second thoughts and may prefer this suggestion: #7973 (comment)

@trask trask marked this pull request as ready for review January 10, 2026 04:16
@trask trask requested a review from a team as a code owner January 10, 2026 04:16

@Test
void valueString_basic() {
assertThat(Value.of("hello").toProtoJson()).isEqualTo("\"hello\"");
Copy link
Member

Choose a reason for hiding this comment

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

Slight preference for @ParameterizedTest here, but won't split hairs over it because there's plenty of examples in this repo similar to what you have here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Value.of(false),
Value.empty())
.toProtoJson())
.isEqualTo("[\"string\",42,3.14,true,false,null]");
Copy link
Member

Choose a reason for hiding this comment

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

If longs are supposed to be stringified, then how come in an array context they aren't?

Copy link
Member Author

Choose a reason for hiding this comment

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

longs are stringified everywhere, but they aren't surrounded by (extra) quotes since they aren't json strings

@trask trask force-pushed the stabilize-complex-attributes-try-2 branch from 7dabd12 to 2a8fd46 Compare January 21, 2026 23:30
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