-
Notifications
You must be signed in to change notification settings - Fork 6
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
Tracing WIT #12
Tracing WIT #12
Conversation
91c14cf
to
71c8585
Compare
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 had a question for my own edification and just one suggestion, I think this looks great!
|
||
/// Retrieve any parent Span ID from the Host runtime that should be the parent | ||
/// of the Guest Root Span. | ||
get-parent-span-id: func() -> string; |
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 this be an option<string>
in case the host runtime hasn't created a parent span?
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.
Alternatively, I'd be interested in a get-or-enter-parent-span-id
that gives the user flexibility in either hooking into an existing span, OR creating their own root span. What do you think?
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 that seems reasonable
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 it is better to create a span rather than asking me to pass you the IDs. something like new-child-span
.
record read-only-span { | ||
// TODO: Read only list of fields similar to resource:span. | ||
} |
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 is a read-only-span for? Would this be something where the host gives a span to the component that it's not allowed to modify, for example?
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.
A read only span is for the guest to emit completed spans to the host, when not using the host as a tracing provider (akin to how OTel handles this for sinks)
|
||
/// Close the span and communicate that to the o11y host | ||
close: func() | ||
} |
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.
IIUC, WIT child resources can't outlive their parent resources; I don't think we run afoul of this with this design1, but I want to call attention to it in case I'm missing something!
Footnotes
-
I think that since there are no component-visible ways to get from a child
span
resource to a parentspan
resource – only its id – we should be safe, but I want to make sure my understanding is correct! ↩
|
||
resource span { | ||
/// get-name returns the name of the span. | ||
get-name: func() -> string; |
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 mentioned over the call. I am reluctant to support readback methods because first it forces you to keep the state in sync across threads (ref #4). A less coupled approach IMHO is to keep the span resource as a façade with set methods and not preserve any state, delegating that to the host.
get-name: func() -> string; | ||
|
||
/// get-id returns the ID of the span. | ||
get-id: func() -> string; |
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.
get-span-id & get-trace-id can be the exceptions as they define the context and that is something we will probably propagate (ref #4). Also, probably both can be encapsulated into something called span context.
get-id: func() -> string; | ||
|
||
/// set-attribute sets an attribute on the span. | ||
set-attribute: func(key: string, value: string); |
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.
heads up: OTel supports a several types for attributes (heads up, I am not an OTel advocate, I am just trying to not to create more confusion in o18y ecosystem as it used to happen in the past). Whether that is a good idea or not, I believe string is probably the one that covers most of the use cases I have in mind but other HTTP stuff like status code has been turned to int (see https://opentelemetry.io/docs/specs/semconv/http/http-spans/#common-attributes). My suggestion would be first version of this only support string but also called it set-string-attribute
.
set-attribute: func(key: string, value: string); | ||
|
||
/// Attach an event to the given span | ||
submit-event: func(name: string, message: string) |
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.
Clarify the timestamp is going to be set by the host.
submit-event: func(name: string, message: string) | ||
|
||
/// Enter a new child span of the callee | ||
span-enter: func(name: string) -> span; |
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 wonder if this is the right name. How about create-child? Also, I wonder if this should be a method of the span itself.
span-enter: func(name: string) -> span; | ||
|
||
/// Close the span and communicate that to the o11y host | ||
close: func() |
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.
note: here we are conflating the span lifecycle with the reporting. There are cases, specially here where you don't control the clock where you want to close the span (and hence cut a duration for it) but further stuff could still add attributes. I would open a discussion whether it should be a close: func(flush: bool)
so the flush can happen later OR by the host and also think if the FLUSH should be controlled by guest or not.
get-parent-span-id: func() -> string; | ||
|
||
/// Emit a given completed read-only-span to the o11y host. | ||
span-emit: func(span: read-only-span); |
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 flush
is more idiomatic in this case.
Thanks for starting this @endocrimes. I would really like to merge this along with some example code to see how things work out. |
Thanks for the contribution here @endocrimes, closing this as it is superseded by #15. |
I was going down a little bit of a rabbit hole of including too much of OTel for an early draft.
So here's a bit of a paired back sketch as to what I'm thinking about for tracing before today's call. For
wasi-observe
to be broadly useful, we somewhat need to support both being the trace-provider (lightweight components would benefit a lot from this) - but also for integration into existing ecosystems, probably want to be able to be a relatively "simple" sink of otel data.Not really sure where this is going yet (but opening this up to thoughts and ideas).