Skip to content
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

sdk-trace: add EventData #369

Merged
merged 1 commit into from
Nov 15, 2023
Merged

Conversation

iRevive
Copy link
Contributor

@iRevive iRevive commented Nov 14, 2023

Reference Link
Spec https://opentelemetry.io/docs/specs/otel/trace/api/#add-events
Java implementation EventData.java

Note

An Event is structurally defined by the following properties:

  • Name of the event.
  • A timestamp for the event. Either the time at which the event was added or a custom timestamp provided by the user.
  • Zero or more Attributes further describing the event.

@iRevive iRevive added tracing Improvements to tracing module module:sdk Features and improvements to the sdk module labels Nov 14, 2023

/** The epoch time in nanos of the event.
*/
def epochNanos: Long
Copy link
Member

Choose a reason for hiding this comment

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

We often use a FiniteDuration in these contexts e.g. Clock#realTime.

Comment on lines +132 to +138
builder.addAll(attributes.toList)

Attributes(builder.result(): _*)
Copy link
Member

Choose a reason for hiding this comment

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

I feel like there's a lot of inefficient conversions here: toList, .result(), : _* ...

It can be a follow-up, but I wonder if we can either have a mutable AttributesBuilder that is backed by a MapBuilder or we could have Attributes.unsafeFromMap style builder.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, we should explore the alternatives.

}

object EventData {
private val ExceptionEventName = "exception"
Copy link
Member

Choose a reason for hiding this comment

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

final vals without type annotations get inlined.

Suggested change
private val ExceptionEventName = "exception"
private final val ExceptionEventName = "exception"

@iRevive iRevive force-pushed the sdk-trace/event-data branch 2 times, most recently from 50a174d to 0ce0712 Compare November 14, 2023 16:35
@iRevive iRevive mentioned this pull request Nov 14, 2023
builder.addOne(
Attribute(
SemanticAttributes.ExceptionType,
Option(exception.getClass.getName).getOrElse("")
Copy link
Member

Choose a reason for hiding this comment

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

Can getName() on aClass ever actually return null?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm. I don't think so.

Comment on lines 122 to 132
try {
val printWriter = new PrintWriter(stringWriter)
exception.printStackTrace(printWriter)
} catch {
case e if NonFatal(e) => ()
}
Copy link
Member

Choose a reason for hiding this comment

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

What kinds of non-fatal exceptions could we get here? Sorry just nit-picking, it's not a big deal. Is the Java implementation like this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Valid point. AFAIK printStackTrace doesn't throw any

@iRevive iRevive force-pushed the sdk-trace/event-data branch 2 times, most recently from 114fa8a to 03a6005 Compare November 14, 2023 16:49
Comment on lines 116 to 122
val stringWriter = new StringWriter()
val printWriter = new PrintWriter(stringWriter)
exception.printStackTrace(printWriter)

builder.addOne(
Attribute(SemanticAttributes.ExceptionStacktrace, stringWriter.toString)
)
Copy link
Member

Choose a reason for hiding this comment

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

Some exceptions have no stack traces e.g. NoStackTrace. In those cases should the attribute value be empty or should the attribute be omitted entirely?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Java SDK doesn't care and sets an empty string. Should we do

if (exception.getStackTrace.nonEmpty) {
  ...
  
}

?

Copy link
Member

Choose a reason for hiding this comment

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

Interesting. I guess NoStackTrace is a Scala-ism 😅 yeah, maybe better to omit in that case, I don't see the value.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, on second look I'm not sure. I'm reading this page.

https://opentelemetry.io/docs/specs/otel/trace/exceptions/#attributes

Additionally, the following attributes SHOULD be filled out:

  • exception.escaped
  • exception.message
  • exception.stacktrace
  • exception.type

It's SHOULD not MUST. Also it says "filled out" and not "present", so I suspect we can't satisfy it either way if we don't have a stack trace. Are we missing the escaped attribute?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm.

exception.escaped - boolean - SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] - Recommended

I believe it's possible only with the manual instrumentation:

escaped:

Tracer[F].span("span").use { span =>
  io.onError { error =>
    span.recordException(new Exception, Attribute("exception.escaped", true))
  }
}

not escaped:

Tracer[F].span("span").use { span =>
  io.handleErrorWith { error =>
    span.recordException(new Exception, Attribute("exception.escaped", false))
  }
}

Copy link
Member

Choose a reason for hiding this comment

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

I believe it's possible only with the manual instrumentation:

I'm not caught up with the implementation details, but if recordException is called automatically can't we just check the ExitCase after the use?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess we can find a way, for example, here: https://github.com/typelevel/otel4s/pull/325/files#diff-9bac43fa0f17631759132ba638deda5d102310637d050a1a6495d58fe44b96e2R119-R125

We can explore these options when we start working on the SdkSpanBuilder implementation.

@iRevive iRevive force-pushed the sdk-trace/event-data branch from 03a6005 to 804eae6 Compare November 14, 2023 17:29

/** The epoch time of the event.
*/
def epoch: FiniteDuration
Copy link
Member

Choose a reason for hiding this comment

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

Would timestamp be a better name? That's how its referred to in the spec.

Suggested change
def epoch: FiniteDuration
def timestamp: FiniteDuration

@iRevive iRevive force-pushed the sdk-trace/event-data branch from 804eae6 to 740faad Compare November 14, 2023 17:38
Comment on lines 99 to 108
def fromException(
timestamp: FiniteDuration,
exception: Throwable,
attributes: Attributes
): EventData = {
Copy link
Member

Choose a reason for hiding this comment

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

Should we add escaped: Boolean as a parameter?

@iRevive iRevive force-pushed the sdk-trace/event-data branch from 740faad to d3f3453 Compare November 14, 2023 18:15
@iRevive iRevive merged commit fe5cae5 into typelevel:main Nov 15, 2023
@iRevive iRevive deleted the sdk-trace/event-data branch November 15, 2023 07:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
module:sdk Features and improvements to the sdk module tracing Improvements to tracing module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants