-
Notifications
You must be signed in to change notification settings - Fork 33
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 recordingSpan and currentSpan methods to TracerProtocol #160
base: main
Are you sure you want to change the base?
Conversation
Here's a draft implementation of the |
63644af
to
cf16c0a
Compare
This looks very useful, thanks @slashmo! Do I understand correctly that this method needs to be considered "best effort", since existing implementations might not be implementing it (yet, or ever) - so whether new events attached this way will show up depends on the concrete backend? It's fine IMO, we might just want to call this out explicitly. (It'll be the case with any new-and-defaulted requirements like this one, but it might not be obvious to new adopters of swift-distributed-tracing.) |
Yes, it would have to be. Thanks for bringing it up. This reminds me a bit of when we introduced metadata providers in extension LogHandler {
/// Default implementation for `metadataProvider` which defaults to `nil`.
/// This default exists in order to facilitate source-compatible introduction of the `metadataProvider` protocol requirement.
public var metadataProvider: Logger.MetadataProvider? {
get {
nil
}
set {
#if DEBUG
if LoggingSystem.warnOnceLogHandlerNotSupportedMetadataProvider(Self.self) {
self.log(
level: .warning,
message:
"Attempted to set metadataProvider on \(Self.self) that did not implement support for them. Please contact the log handler maintainer to implement metadata provider support.",
metadata: nil,
source: "Logging",
file: #file,
function: #function,
line: #line
)
}
#endif
}
}
} Perhaps we could borrow this approach here as well? Either way, I agree that we should highlight it a bit more in documentation as well. |
Hm, just realized that here we wouldn't be able to use |
I'm fine with us calling it out in the doc comments only. We can reopen the discussion of whether tracing should depend on logging separately, I don't think it needs to block this. |
Sounds good. I'll update the docs then to provide some more clarity. |
**Motivation:** Currently, it is only possible to implicitly work with the current span by transparently creating a child span (using ServiceContext.current) under the hood. This is sufficient for almost all use-cases, but does not work in case a piece of code wants to add an event to the current span without having a handle on said span, e.g. if the span was created by a library. **Modifications:** I added a `recordingSpan(identifiedBy context: ServiceContext) -> Span?` requirement to `TracerProtocol`. This way, `Tracer` implementations may look up and return a span identified by the data they stored in the provided `ServiceContext`. It's worth noting that this method is only intended for obtaining spans which are still recording as opposed to already ended ones that may not even be in memory anymore. I also added a default implementation of this method to avoid introducing a breaking change. On top of this new protocol requirement, I added an extension to `TracerProtocol` with sugar to obtain the current span based on the task-local `ServiceContext`. **Result:** Library authors and application developers are now able to look up the current recording span to interact with it by e.g. adding events and attributes.
cf16c0a
to
98993ea
Compare
Motivation:
Currently, it is only possible to implicitly work with the current span by transparently creating a child span (using ServiceContext.current) under the hood. This is sufficient for almost all use-cases, but does not work in case a piece of code wants to add an event to the current span without having a handle on said span, e.g. if the span was created by a library.
The concrete use-case I'm facing is building a tracing "hook" for my
OpenFeature
client.OpenFeature
hooks are similar to middleware, but instead of wrapping a piece of logic they are called before and after a feature flag was evaluated. Therefore,OpenFeature
implementations in other ecosystems have opted to only add an event instead of creating a new span for the flag evaluation itself:Modifications:
I added a
recordingSpan(identifiedBy context: ServiceContext) -> Span?
requirement toTracerProtocol
. This way,Tracer
implementations may look up and return a span identified by the data they stored in the providedServiceContext
. It's worth noting that this method is only intended for obtaining spans which are still recording as opposed to already ended ones that may not even be in memory anymore. I also added a default implementation of this method to avoid introducing a breaking change. On top of this new protocol requirement, I added an extension toTracerProtocol
with sugar to obtain the current span based on the task-localServiceContext
.Result:
Library authors and application developers are now able to look up the current recording span to interact with it by e.g. adding events and attributes: