-
Notifications
You must be signed in to change notification settings - Fork 37
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
Security of ending spans #347
Comments
We tried this approach a while ago, and it was nice to have two slightly different spans with different sets of operations, but we didn't find it successful or beneficial. While I think it's a good and secure design of the API, there are several hiccups:
Though we can cheat here, in some sense:
And in the end, it's up to a user to use the library correctly. If someone wants to go yolo and do unsafe things, we cannot prevent it. The behavior and consequences are transparent, IMO. |
I'm not sure I agree with this; it's quite common to try to prevent both mistakes and malicious use in languages and libraries. in Java for example, |
Yes and it happens under the hood. It is the same thing with cats-effect that uses mutable data structures internally to keep on par with performance. For example, OpenTelemetry Java allows terminating span at any point of time: val tracer: io.opentelemetry.api.trace.Tracer = ???
val span = tracer.spanBuilder("span").startSpan()
...
span.end() If we strip this functionality away from span, how can a user end it earlier? Yes, it's rather a rare case, but it may be viable in some non-trivial applications. You cannot use for {
span <- Tracer[IO].spanBuilder("span").build.startUnmanaged
_ <- IO.println(span.context)
_ <- Tracer[IO].span("child").use(childSpan => IO.println(childSpan.context))
_ <- span.end
} yield () The output is:
So, we have two root spans there. We can allow making any span 'current', e.g.
Because we provide a way to overrule the default propagation of a span at any point in time. Which is as bad as ending the span earlier. Someone can always find a way to break even a perfectly designed library. |
@NthPortal I don't think we should entirely give up on this design. I agree that the lifecycle should be encapsulated and fully managed by the internals. If we find the right option of making 'startUnmanaged' propagatable, we can consider changing the encoding and stripping 'end' from the managed span. Also, 'startUnmanaged' could be the exact solution to the tracing within the resource and stream. So it is worth exploring. |
Currently, all spans expose
end
methods, allowing even users of managed spans to end them prematurely and potentially cause problems. Additionally, if we end up exposing the current span inTracer
, arbitrary callers may be able to end spans prematurely. Should the API be changed to prevent users other than callers ofstartUnmanaged
from callingend
on a span?The text was updated successfully, but these errors were encountered: