-
Notifications
You must be signed in to change notification settings - Fork 817
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
Add ExceptionEventData which wraps events that contain exceptions #4162
Conversation
Codecov Report
@@ Coverage Diff @@
## main #4162 +/- ##
============================================
+ Coverage 90.23% 90.28% +0.05%
- Complexity 4599 4758 +159
============================================
Files 537 558 +21
Lines 14082 14618 +536
Branches 1347 1402 +55
============================================
+ Hits 12707 13198 +491
- Misses 933 960 +27
- Partials 442 460 +18
Continue to review full report at Codecov.
|
This seems reasonable to me - we'd probably want to check on the spec repo if anyone else has any thoughts on how to format exceptions across languages |
|
||
import io.opentelemetry.api.common.Attributes; | ||
|
||
public interface ExceptionEventData extends EventData { |
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 believe this can be package private.
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.
Oh nvm. It has to be public so that processors / exporters can check instanceof ExceptionEventData
. This seems reasonable to me too.
If we wanted to be cautious we could put this interface in :sdk-extensions:tracing-incubator
so users have to add a dependency on an unstable artifact in order to use it.
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 SDK would need to know of the interface in order for Span#recordException
to add an event that implements it, wouldn't it?
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.
What about putting this in an internal
package for now, as we explicitly document anything in internal
as being unstable. You would be free to use it, of course, accepting the risk of it changing in the future.
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 SDK would need to know of the interface in order for Span#recordException to add an event that implements it, wouldn't it?
Yes, it could place an implementation dependency on :sdk-extensions:tracing-incubator
.
What about putting this in an internal package for now, as we explicitly document anything in internal as being unstable.
That would work too, but probably better to not promote using internal classes.
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.
Finished pass at moving the ExceptionEventData
interface and implementation to tracing-incubator
. Added a helper class that looks for it on the classpath and will use the create
static method to create instances, otherwise it defaults to the existing behavior. Not terribly thrilled with the manual use of reflection but it seems that MethodHandles
and LambdaMetaFactory
aren't available due to the target Android API version and desugaring seems to only apply to them when used with invokedynamic
, but hopefully given this code is related to exceptions the overhead of invoking the method is relatively a drop in the bucket.
Also made the implementation of ExceptionEventData
defer creating of the common attributes until the getAttributes
method is called and the result is memoized, so existing exporters should work as expected if using this implementation. That behavior is certainly up for discussion.
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.
Apologies for the confusion - I was describing for an approach where :sdk:trace
took an implementation dependency on :sdk-extensions:tracing-incubator
. That way, no reflection would be necessary since ExceptionEventData
would always be on the classpath, but users would have to have their own dependency on :sd:tracing-incubator
in order to use it.
I'm ok with the internal package approach as well, but not especially fond of the reflection approach.
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.
:sdk-extensions:tracing-incubator
already takes a dependency on :sdk:trace
, so I don't think that would be an option? If you'd prefer I can definitely move this code into an internal
package in :sdk:trace
, that would definitely be simpler, but also wouldn't allow anyone to opt-out unless we add some kind of config?
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.
:sdk-extensions:tracing-incubator already takes a dependency on :sdk:trace, so I don't think that would be an option
Ah that's right. The internal
package sounds good. Do users need to opt out?
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.
Do users need to opt out?
Not necessarily, just thought it was safer to be able to test it in isolation.
I can get the PR together to move these classes back to :sdk:tracing
under an internal
package.
|
||
private static ExceptionEventFactory initializeEventFactory() { | ||
try { | ||
Class<?> clazz = |
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 worry a bit about having this reflection here, which will get logged as a warning on every SDK startup on a JDK 11+. I'm not sure I have a better solution, though.
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 saw a similar mechanism is also being used for SDK autoconfigure. Unfortunately I can't rely on the better/safer APIs due to Android compatibility. If there is a better option I am all for it, but I can't think of one that doesn't involve putting some public interface in the SDK class.
...race/src/main/java/io/opentelemetry/sdk/trace/internal/data/ImmutableExceptionEventData.java
Outdated
Show resolved
Hide resolved
|
||
@Override | ||
@Memoized | ||
public Attributes getAttributes() { |
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.
public Attributes getAttributes() { | |
public final Attributes getAttributes() { |
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.
Memoized methods can't be final in AutoValue.
...race/src/main/java/io/opentelemetry/sdk/trace/internal/data/ImmutableExceptionEventData.java
Outdated
Show resolved
Hide resolved
} | ||
|
||
@Override | ||
@Memoized |
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.
Just to point out this changes the getAttributes
for exceptions from a normal field to volatile field in the new codepath. I think it's OK just want to make sure everyone notices it
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.
Going for the stretch goal of having ExceptionEventData
not generate those attributes unless the exporter tries to use them. Assuming the exporter only calls getAttributes
once it's probably not actually necessary to memoize them.
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.
If there is hesitation in deferring the generation of those attributes I can definitely back that off. When the interface was in tracing-incubation
I felt it was worth exploring. The only attribute I'd prefer to avoid generating is exception.stacktrace
as in my Spring codebases they can be quite large, but I don't think it'd a big deal to consider that later.
* | ||
* @return the additional {@link Attributes attributes} of the {@link ExceptionEventData} | ||
*/ | ||
Attributes getAdditionalAttributes(); |
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 this can be a package private method on ImmutableExceptionEventData
instead of on this interface
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.
As with that stretch goal I wanted to enable an exporter to access the additional attributes without forcing the semantic attributes for the exception to be created.
sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.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.
Sorry for delay thought had already hit approve
sdk/trace/src/main/java/io/opentelemetry/sdk/trace/internal/data/ExceptionEventData.java
Show resolved
Hide resolved
Just checking in to see what the thoughts are about 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.
Looks good, thanks!
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.
Any reason not to merge this?
Adds
ExceptionEventData
interface extendingEventData
to represent an exception recorded to a span. Processors/exporters can access the exception directly to enable alternate formatting.