-
Notifications
You must be signed in to change notification settings - Fork 442
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
Span links improvements and bug fix #3123
base: main
Are you sure you want to change the base?
Changes from 5 commits
297ef1f
a3922f8
fd93eb7
fbbfdda
e1c23c8
66d3a67
10d5ddb
e32eee0
2f83d57
a5734e1
43e6edc
b0bdffc
c835acd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Unless explicitly stated otherwise all files in this repository are licensed | ||
// under the Apache License Version 2.0. | ||
// This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
// Copyright 2016 Datadog, Inc. | ||
|
||
package ddtrace | ||
|
||
// SpanLink represents a reference to a span that exists outside of the trace. | ||
// | ||
//go:generate msgp -unexported -marshal=false -o=span_link_msgp.go -tests=false | ||
|
||
type SpanLink struct { | ||
// TraceID represents the low 64 bits of the linked span's trace id. This field is required. | ||
TraceID uint64 `msg:"trace_id" json:"trace_id"` | ||
// TraceIDHigh represents the high 64 bits of the linked span's trace id. This field is only set if the linked span's trace id is 128 bits. | ||
TraceIDHigh uint64 `msg:"trace_id_high" json:"trace_id_high"` | ||
// SpanID represents the linked span's span id. | ||
SpanID uint64 `msg:"span_id" json:"span_id"` | ||
// Attributes is a mapping of keys to string values. These values are used to add additional context to the span link. | ||
Attributes map[string]string `msg:"attributes" json:"attributes"` | ||
// Tracestate is the tracestate of the linked span. This field is optional. | ||
Tracestate string `msg:"tracestate" json:"tracestate"` | ||
// Flags represents the W3C trace flags of the linked span. This field is optional. | ||
Flags uint32 `msg:"flags" json:"flags"` | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ package tracer | |
import ( | ||
"context" | ||
"encoding/base64" | ||
"encoding/json" | ||
"fmt" | ||
"os" | ||
"reflect" | ||
|
@@ -464,6 +465,26 @@ func (s *span) setMetric(key string, v float64) { | |
} | ||
} | ||
|
||
// AddSpanLinks appends the given links to the span's span links. | ||
func (s *span) AddSpanLinks(spanLinks ...ddtrace.SpanLink) { | ||
mtoffl01 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
s.SpanLinks = append(s.SpanLinks, spanLinks...) | ||
} | ||
|
||
// serializeSpanLinksInMeta saves span links as a JSON string under `Span[meta][_dd.span_links]`. | ||
func (s *span) serializeSpanLinksInMeta() { | ||
if len(s.SpanLinks) == 0 { | ||
return | ||
mtoffl01 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
spanLinkBytes, err := json.Marshal(s.SpanLinks) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A little concerned about performance, but not sure if there's any other way to do this. We have to serialize the links into a JSON string such as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could always add a benchmark for that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's actually must faster than I expected
|
||
if err != nil { | ||
return | ||
mtoffl01 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
if s.Meta == nil { | ||
s.Meta = make(map[string]string) | ||
} | ||
s.Meta["_dd.span_links"] = string(spanLinkBytes) | ||
} | ||
|
||
// Finish closes this Span (but not its children) providing the duration | ||
// of its part of the tracing session. | ||
func (s *span) Finish(opts ...ddtrace.FinishOption) { | ||
|
@@ -514,6 +535,8 @@ func (s *span) Finish(opts ...ddtrace.FinishOption) { | |
} | ||
} | ||
|
||
s.serializeSpanLinksInMeta() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you state explicitly why you were not able to rely on json.Marshal and we have to call this custom serializer? You may be correct, I just want to make sure I'm following There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
|
||
s.finish(t) | ||
orchestrion.GLSPopValue(sharedinternal.ActiveSpanKey) | ||
} | ||
|
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 few notes:
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.
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.
Public interfaces are considered "contracts" in Golang. Modifying them is "breaking contract" because that means every type which expects to satisfy this interface must now be updated -- this can impact customer code.