-
Notifications
You must be signed in to change notification settings - Fork 843
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stabilize log any value #6591
Stabilize log any value #6591
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we avoid the deprecations by adding an AnyValueBody subtype of Body?
sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/TestLogRecordData.java
Outdated
Show resolved
Hide resolved
This is what I was originally intending on doing, but see my comment in the PR description:
In this PR, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some (probably unhelpful) thoughts on naming:
AnyValue
->Value
AnyValueType
->ValueType
KeyAnyValue
->KeyValue
orEntry
getAnyValueBody
->getBodyValue
sdk/testing/src/main/java/io/opentelemetry/sdk/testing/logs/TestLogRecordData.java
Show resolved
Hide resolved
@@ -105,6 +108,9 @@ static AnyValue<List<KeyAnyValue>> of(Map<String, AnyValue<?>> value) { | |||
* Return a string encoding of this {@link AnyValue}. This is intended to be a fallback serialized | |||
* representation in case there is no suitable encoding that can utilize {@link #getType()} / | |||
* {@link #getValue()} to serialize specific types. | |||
* | |||
* <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. | |||
*/ | |||
// TODO(jack-berg): Should this be a JSON encoding? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there anything in spec about this? it seems like a lot of backends will get this format by default given the fallback implementation of getBody()
and so it would be great if this format could be stable-ish
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The closest we have is https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/attribute-type-mapping.md, which explains how to map data structures to AnyValue, but nothing about a string representation of AnyValue. If the spec did have something, I imagine it might either draw inspiration from or be defined as the standard protobuf JSON mapping.
I agree that a stable spec would be ideal. But I also think we can proceed without it. Ideally, exporters quickly update to be able to properly serialize AnyValue bodies. The goal of asString()
is just to be a fallback allowing the information to be transmitted, but in a format which implies that you shouldn't depend on it. Seeing data in this format is a signal that something is suboptimal in the export pipeline, while still allowing things to work.
If you look at a test of AnyValue#asString, you see a format which is JSON-like, but definitely not actually JSON. The format is probably best described as an idiomatic implementation of Java toString(). It could easily be adapted to be actual valid JSON, but that might reduce the incentive for exporters to properly serialize.
Thanks for the suggestions. I do like these. The one consideration I have is that the |
Ended up implementing trask's naming recommendations, which ballooned the size of the PR but is probably best in the long term. |
* Set the body string. | ||
* | ||
* <p>Shorthand for calling {@link #setBody(AnyValue)} with {@link AnyValue#of(String)}. | ||
*/ | ||
LogRecordBuilder setBody(String body); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd rather see this string version have a default implementation that delegates to the AnyValue version, rather than the other way around. It seems safer and less potentially lossy that way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately we can't do this because. Because of our backwards compatibility guarantees, any new interface method we add has to have a default implementation. The default implementation should do the most sensible thing possible, which in this case is to call the existing setBody(String)
method with a string encoding of the anyvalue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because of our backwards compatibility guarantees, any new interface method we add has to have a default implementation.
Note that these are the rules we've been abiding by, but we decided at the spec level that this type of compatibility isn't actually required. It allows alternative API implementations to continue to be able to compile when new API versions come out, but we decided its reasonable to say that alternative API implementations should have to stay up to date with API releases.
See this section of the spec: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md#extending-apisdk-abstractions
I'm inclined to continue with the practices we've been following unless doing so causes some egregious API user experience.
api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/AnyValueTest.java
Outdated
Show resolved
Hide resolved
sdk/logs/src/main/java/io/opentelemetry/sdk/logs/SdkLogRecordBuilder.java
Outdated
Show resolved
Hide resolved
sdk/logs/src/test/java/io/opentelemetry/sdk/logs/AnyValueBodyTest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great, and I'm happy to approve, just want us to give a consideration to which method has the default, otherwise looking good. Glad to see this moving forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks again!
…y-java into stabilize-log-any-value
FYI, planning on merging later today. |
Resolves #6581. Unblocks #6509.
io.opentelemetry.api.common
package because while its only usage is in the log API today, its possible that future otel APIs reuse the more generic AnyValue representations.Body
class. It serves the same function asAnyValue
, but really should have been in the API package from the start. Since its not, retainingBody
and extending it to representAnyValue
concepts results in a cumbersome API with an unnecessary layer of abstraction (i.e. Body encloses AnyValue encloses your data). Instead we have a newLogRecordData#getAnyValueBody()
method which represents all the different body types. Steps are taken to ensure users relying onLogRecordData#getBody()
are not impacted, and continue to get a functional string representation even when the body is anAnyValue
.