-
Notifications
You must be signed in to change notification settings - Fork 40
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
Conversation
|
||
/** The epoch time in nanos of the event. | ||
*/ | ||
def epochNanos: Long |
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.
We often use a FiniteDuration
in these contexts e.g. Clock#realTime
.
builder.addAll(attributes.toList) | ||
|
||
Attributes(builder.result(): _*) |
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 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.
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.
Yeah, we should explore the alternatives.
} | ||
|
||
object EventData { | ||
private val ExceptionEventName = "exception" |
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.
final val
s without type annotations get inlined.
private val ExceptionEventName = "exception" | |
private final val ExceptionEventName = "exception" |
50a174d
to
0ce0712
Compare
builder.addOne( | ||
Attribute( | ||
SemanticAttributes.ExceptionType, | ||
Option(exception.getClass.getName).getOrElse("") |
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 getName()
on aClass
ever actually return null
?
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.
Hm. I don't think so.
try { | ||
val printWriter = new PrintWriter(stringWriter) | ||
exception.printStackTrace(printWriter) | ||
} catch { | ||
case e if NonFatal(e) => () | ||
} |
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 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?
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.
Valid point. AFAIK printStackTrace
doesn't throw any
114fa8a
to
03a6005
Compare
val stringWriter = new StringWriter() | ||
val printWriter = new PrintWriter(stringWriter) | ||
exception.printStackTrace(printWriter) | ||
|
||
builder.addOne( | ||
Attribute(SemanticAttributes.ExceptionStacktrace, stringWriter.toString) | ||
) |
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 exceptions have no stack traces e.g. NoStackTrace
. In those cases should the attribute value be empty or should the attribute be omitted entirely?
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.
Java SDK doesn't care and sets an empty string. Should we do
if (exception.getStackTrace.nonEmpty) {
...
}
?
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.
Interesting. I guess NoStackTrace
is a Scala-ism 😅 yeah, maybe better to omit in that case, I don't see the value.
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, 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?
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.
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.
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))
}
}
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 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
?
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 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.
03a6005
to
804eae6
Compare
|
||
/** The epoch time of the event. | ||
*/ | ||
def epoch: FiniteDuration |
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.
Would timestamp
be a better name? That's how its referred to in the spec.
def epoch: FiniteDuration | |
def timestamp: FiniteDuration |
804eae6
to
740faad
Compare
def fromException( | ||
timestamp: FiniteDuration, | ||
exception: Throwable, | ||
attributes: Attributes | ||
): 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.
Should we add escaped: Boolean
as a parameter?
740faad
to
d3f3453
Compare
Note
An Event is structurally defined by the following properties: