-
Notifications
You must be signed in to change notification settings - Fork 888
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 RecordLink for Span. #3240
Add RecordLink for Span. #3240
Conversation
@@ -0,0 +1,45 @@ | |||
# Semantic Conventions for Links |
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.
Please add this new file to the TOC in README.md
@@ -691,6 +692,26 @@ Note: `RecordException` may be seen as a variant of `AddEvent` with | |||
additional exception-specific parameters and all other parameters being optional | |||
(because they have defaults from the exception semantic convention). | |||
|
|||
#### Record Link |
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.
Probably too early to spark a naming discussion but I think span.RecordLink(ctx, attrs)
would be very misleading and should rather be called RecordLinkAs(Span)Event
or the like, since the outcome will not be a Span Link
as one might expect from the name.
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 if we go down the path of recording links as events after span starts, we'd eventually replace original links with events too. If that happens, we'd regret naming it as RecordLinkAs(Span)Event
.
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 am strongly against this approach. A Link is a dedicated entity in the data model that is designed to capture causality between spans. Reusing another entity from the data model (Event) for the same purpose is a very bad design.
I agree with @yurishkuro. There seem to be 2 use cases, one that is due to limitations of particular instrumentations (so don't conceptionally need the link added after start) and those like #454 that describe non-causal relationships. In the latter example I'd argue those shouldn't be Links in the first place. In which case maybe a definition for adding span contexts as Events to a Span makes sense, just not "Links". So Links can stay as they are, and Events are used for non-causal relationships -- "at time T this span did something based on a message created during Span X". |
why isn't this causal / happens-before? |
@yurishkuro just basing it on the example given in #454 and generally considering the idea that a span could cause an Event instead of a Span. I can't think of an example that describes the real world data/events that would need to be modeled like this. |
I have no strong opinion on the link/event terminology. FWIW limiting links to causal-only relationships leaves us without a way to represent non-causal relationships and perhaps we should be looking into broadening links definition. Anyway, representing the thing that describes that two spans are related as event seems optimal:
|
[retrieved](../api.md#retrieving-the-traceid-and-spanid) | ||
by `SpanContext`. | ||
examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' | ||
- id: tracestate |
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.
trace-flags? otherwise we don't know if it was recorded on the other service
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.
Sounds useful, although I think you could make the same argument for our normal parent-child relationships (maybe we should actually add a parent_flags
to the OTLP span?)
Can you link to the data model definition? |
I guess one could see OTLP as a data model definition? There links are a different entity than events. One of the main drawbacks of this approach is, that it forces telemetry consumers (who want to properly support links) to look at two different places for them: as links and as events. Proper support for links created after span creation would then require modifications in a variety of backends and exporters. |
https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#specifying-links These two define the semantics and the data model of the links. The definition is not as strong as Lamport's |
we have a precedent unifying events and logs. If we do links-are-represented-as-events in OTLP, the original links would probably go away.
some people say that everything (including span) is semantically an event. In any case, user experience and over-the-wire data representation are not strictly related and I'd love to see some explanation on what's bad about user experience. |
Cognitive overhead, ambiguity. Production: do I record this as link or event? Consumption: do I read this from links or events? Production: I am capturing a relationship between two spans, what is the timestamp doing here?
we can also say that everything is a sequence of bytes, why bother with semantics of the logical data model at all? |
You record it as link since that's what on the API and in the documentation without bothering much about over-the-wire format.
Counter: When I'm receiving multiple messages with a timeout and some of them are prefetched and other come at different points in time, how do I record when the message came without creating two things - link AND event? Timestamp is there to say when the relationship was discovered and should also help answer questions like: why this link was not considered when I made sampling decision.
Users don't read it from over-the-wire format but from their backends. Cognitive load of a backend developer getting list of links from the span and transforming them is no different than extracting exceptions from events. Counter: as a user, when I want to see if two spans are related and my backend stores links inside spans, I need to write a query like Having events that exist outside of span lifetime would at least require them to be stored separately improving the experience instead. |
what I'm saying is that event is a base type for different things and I argue that links is one of these things |
@lmolkova you argue that relationships can be recorded via events. I don't dispute that. A link is just a structured representation of the relationship that can be just as well encoded via semantic conventions. What I don't agree with is having two representations of links in the data model, as this PR is proposing. I can get behind the proposal to deprecate the concept of Links in favor of span events with specific semantic convention for capturing span/trace reference. |
This PR was marked stale due to lack of activity. It will be closed in 7 days. |
I'm also having a hard time understanding why a link cannot be added to an event. It sounds like a preference to not add a field to the event for links or update the definition of an event to contain similar information. Is there any compatibility issues with this? Given this is being looked at as an alternative to recording a link in other ways that all have explicit limitations (sampling, API compatibility, logical inclusion of trace IDs) this solution seems to be the only one without explicit limitation, instead there is a subjective limitation. |
Long-term, didn't we want to deprecate the Span events APIs in favor of the global events /logs? |
This PR was marked stale due to lack of activity. It will be closed in 7 days. |
One more reason why link is a log record + remote trace context is #2176 (comment) Essentially, link as it's defined today message Link {
// A unique identifier of a trace that this linked span is part of. The ID is a
// 16-byte array.
bytes trace_id = 1;
// A unique identifier for the linked span. The ID is an 8-byte array.
bytes span_id = 2;
// The trace_state associated with the link.
string trace_state = 3;
// attributes is a collection of attribute key/value pairs on the link.
// Attribute keys MUST be unique (it is not allowed to have more than one
// attribute with the same key).
repeated opentelemetry.proto.common.v1.KeyValue attributes = 4;
// dropped_attributes_count is the number of dropped attributes. If the value is 0,
// then no attributes were dropped.
uint32 dropped_attributes_count = 5;
} mixes two concepts together: remote context and attributes. I think limiting link to message Link {
// A unique identifier of a trace that this linked span is part of. The ID is a
// 16-byte array.
bytes trace_id = 1;
// A unique identifier for the linked span. The ID is an 8-byte array.
bytes span_id = 2;
// flags?
// The trace_state associated with the link.
string trace_state = 3;
} and adding link property (or list of them?) to LogRecord would preserve two different concepts. |
This PR was marked stale due to lack of activity. It will be closed in 7 days. |
Closed as inactive. Feel free to reopen if this PR is still being worked on. |
Alternative to #3186
A new optional
RecordLink(SpanContext, Attributes)
operation is added, very similar toRecordException
, which means we useAddEvent
behind the scenes, storing the actual data asAttributes
:link
.Attributes
associated to a newLink
are passed through to the newly createdEvent
.This effectively means these are soft
Links
. Other details:Attributes
passed toAddEvent
as shown above.Link
s plus check any event with thelink
name and containing the traceid, spanid and tracestate triplet.