Closed tsvtitan closed 2 years ago
This is already done automatically by the tracer. Please read the package documentation (section on injecting a span context).
To make use of distributed tracing, a span's context may be injected via a carrier into a transport (HTTP, RPC, etc.) to be extracted on the other end and used to create spans that are direct descendants of it. [...]
Source: https://pkg.go.dev/gopkg.in/DataDog/dd-trace-go.v1@v1.31.0/ddtrace/tracer
You can also create other carriers yourself, besides HTTP headers by implementing TextMapReader
and TextMapWriter
.
@tsvtitan If you can describe your use case, we might be able to figure something out to support it.
As it is, this proposal does not fit with our supported use cases and is likely to cause problems.
@tsvtitan If you can describe your use case, we might be able to figure something out to support it.
As it is, this proposal does not fit with our supported use cases and is likely to cause problems.
It would be great to have an example of TextMapReader usage between 2 apps that work over custom TCP protocol to propagate TraceID. Bare in mind that the first app generates TraceID (has no DataDog integration), the second one consumes it and push traces to DataDog.
By the way, there is the custom TraceID support in Jaeger or OpenTelemetry, as well as custom SpanID, which is also supported by DataDog, but not TraceID
Hi, @tsvtitan
The TextMapCarrier
can be used to carry trace information over any transport you like. It is just a map[string]string
that can be serialized using whatever format you like and transported over whatever protocol you use.
On the other end, it can be deserialized and used to create child spans.
Alternatively, TextMapReader
and TextMapWriter
can be implemented by you if you would like to use some custom type to carry the trace information. The interfaces are simple and documented here
Here's an example using the TextMapCarrier
:
// Create the parent span
s := tracer.StartSpan("parent.span")
defer s.Finish()
// Inject the span's state into the carrier
carrier := tracer.TextMapCarrier(make(map[string]string))
tracer.Inject(s.Context(), carrier)
// Serialize the carrier as you choose and send it over your transport
var bs []byte = serializeCarrier(carrier)
// ... send bs through the transport
// ... on the other end, deserialize the carrier from the bytes.
// Extract the span context from the carrier.
carrier = deserializeCarrier(bs)
sctx, err := tracer.Extract(carrier)
if err != nil {
// ...
}
// Start a child span from the parent's transported context.
span := tracer.StartSpan("child.span", tracer.ChildOf(sctx))
It is highly discouraged, but it is possible to create a TextMapCarrier
manually using the keys specified here and subsequently extract a span context from it. Datadog expects spans to be linked in a specific way which Inject
and Extract
ensure, so using the TextMapReader
and TextMapWriter
interfaces along with Inject
and Extract
is your best bet for doing custom distributed tracing.
I am going to close this issue now as stale.
Please reopen this if we can help or discuss further.
// WithSpanID sets the SpanID on the started span, instead of using a random number. // If there is no parent Span (eg from ChildOf), then the TraceID will also be set to the // value given here. func WithSpanID(id uint64) StartSpanOption
I think this is the solution for certain trace id while starting new span.
We want propagate trace ID from our business applications via HTTP headers or in a custom TCP protocol, thus we need to have an option to set custom Trace ID for a root span.
So, we covered the possibility here => https://github.com/DataDog/dd-trace-go/pull/964