Open
Description
Problem
I have a parent-child relationship between spans (e.g., processing batches of requests). I'd like to be able to use that data when consuming the Cloud Trace API (e.g., seeing parent-child relationship in Cloud Trace explorer).
While the Cloud Trace API natively supports this via the span link type, OTEL does not, so all links relationships are unspecified, leading to a worse UX.
Solutions
Having a way to both use OTEL and the span link type would make using links a lot more powerful.
One approach would be to have a magic attribute in Link.Attributes
that holds the type and is popped from Attributes
and added to the link in linksProtoFromLinks(). Psuedo-code:
const magicAttrType = "span_link_type"
func LinkWithType(t *sdktrace.Link, type tracepb.Span_Link_Type) {
s.Attributes = append(s.Attributes, keyvalue.Int64(magicAttrType, int64(type))
}
func typeFromAttrs(attrs *[]attribute.KeyValue) tracepb.Span_Link_type {
if attrs == nil {
return tracepb.Span_Link_TYPE_UNSPECIFIED
}
for i, attr := range *attrs {
if attr.Key == magicAttrType {
t := tracepb.Span_Link_Type(attr.Value.AsInt64())
*attrs = (*attrs)[:i+copy((*attrs)[i:], (*attrs)[i+1:])] // delete magic attr
return t
}
}
return tracepb.Span_Link_TYPE_UNSPECIFIED
}
func linksProtoFromLinks(...) {
...
linkPb := &tracepb.Span_Link{
TraceId: link.SpanContext.TraceID().String(),
SpanId: link.SpanContext.SpanID().String(),
Type: typeFromAttrs(&link.Attributes),
}
...
}
func CallerCode() {
var link sdktrace.Link
trace.LinkWithType(&link, tracepb.Span_link_Type_PARENT)
ctx, span := tracer.Start(ctx, "my-span", sdktrace.WithLinks(link))
...
Another approach would be to work with OTEL and have the spec support relationships directly.