diff --git a/content/en/data_streams/manual_instrumentation.md b/content/en/data_streams/manual_instrumentation.md index f2e60967dae0c..5befeef9990ee 100644 --- a/content/en/data_streams/manual_instrumentation.md +++ b/content/en/data_streams/manual_instrumentation.md @@ -96,6 +96,75 @@ set_consume_checkpoint( {{< /code-block >}} {{% /tab %}} +{{% tab ".Net" %}} +The following example propagates the trace context. See [Trace Context Propagation][1] for more information. + +
+ Note: In async operations, this may not work as expected because the context derived from the incoming message can be lost when producing a new message in different threads. +
+ +#### Producer configuration + +{{< code-block lang="csharp" >}} +using Datadog.Trace; + +using (var scope = Tracer.Instance.StartActive("produce")) +{ + var headers = new Headers(); + var msg = new Message { Value = "", Headers = headers}; + + new SpanContextInjector().InjectIncludingDsm( + msg.Headers, + SetHeader, + scope.Span.Context, + messageType: "", + target: "" + ); + + // Produce the message +} + +// Specific to how the header is modeled +static void SetHeader(Headers headers, string key, string value) +{ + headers.Add(new Header(key, value)); +} +{{< /code-block >}} + +#### Consumer configuration + +{{< code-block lang="csharp" >}} +using Datadog.Trace; + +var startTime = DateTimeOffset.UtcNow; +var msg = consumer.Consume(); +var parentContext = new SpanContextExtractor().ExtractIncludingDsm( + msg.Headers, + GetHeader, + messageType: "", + source: "" +); + +using (var scope = Tracer.Instance.StartActive("consume", + new SpanCreationSettings, + { + Parent = parentContext, + StartTime = startTime + }) +) +{ + // Do something with the message +} + +// Specific to how the header is modeled +static IEnumerable GetHeader(Headers headers, string key) +{ + yield return header.GetByKey(key); +} +{{< /code-block >}} + +[1]: /tracing/trace_collection/trace_context_propagation/?tab=net#additional-use-cases +{{% /tab %}} {{< /tabs >}} ## Further Reading