From 42671a3318d76e7b013182d70f24d37a6cfb75e5 Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Mon, 12 Jul 2021 10:46:09 -0600 Subject: [PATCH 1/2] Add docs for manual distributed tracing --- docs/custom-instrumentation.asciidoc | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/docs/custom-instrumentation.asciidoc b/docs/custom-instrumentation.asciidoc index b381388d4..9d1625bc2 100644 --- a/docs/custom-instrumentation.asciidoc +++ b/docs/custom-instrumentation.asciidoc @@ -104,3 +104,43 @@ Note that you don't need to do anything to send the data -- the `Client` object will handle that before the script exits. Additionally, the `Client` object should be treated as a singleton -- you should only create one instance and store/pass around that instance for all transaction handling. + +[float] +[[instrumenting-custom-code-distributed-tracing]] +==== Distributed Tracing + +When instrumenting custom code across multiple services, you should propagate +the TraceParent where possible. This allows Elastic APM to bundle the various +transactions into a single distributed trace. The Python Agent will +automatically add TraceParent information to the headers of outgoing HTTP +requests, which can then be used on the receiving end to add that TraceParent +information to new manually-created transactions. + +Additionally, the Python Agent provides utilities for propagating the +TraceParent in string format. + +[source,python] +---- +import elasticapm + +client = elasticapm.Client(service_name="foo", server_url="https://example.com:8200") + +# Retrieve the current TraceParent as a string, requires active transaction +from elasticapm.traces import execution_context +from elasticapm.utils.disttracing import TraceParent +transaction = execution_context.get_transaction() +traceparent_string = transaction.trace_parent.to_string() + +# Create a TraceParent object from a string and use it for a new transaction +parent = elasticapm.trace_parent_from_string(traceparent_string) +client.begin_transaction(transaction_type="script", trace_parent=parent) +# Do some work +client.end_transaction(name=__name__, result="success") + +# Create a TraceParent object from a dictionary of headers, provided +# automatically by the sending service if it is using an Elastic APM Agent. +parent = elasticapm.trace_parent_from_headers(headers_dict) +client.begin_transaction(transaction_type="script", trace_parent=parent) +# Do some work +client.end_transaction(name=__name__, result="success") +---- From a9f2309e64c798161e3b332a40d804c50f55d524 Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Mon, 12 Jul 2021 11:10:51 -0600 Subject: [PATCH 2/2] Use the public API call for getting the traceparent string --- docs/custom-instrumentation.asciidoc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/custom-instrumentation.asciidoc b/docs/custom-instrumentation.asciidoc index 9d1625bc2..1db067f72 100644 --- a/docs/custom-instrumentation.asciidoc +++ b/docs/custom-instrumentation.asciidoc @@ -126,10 +126,7 @@ import elasticapm client = elasticapm.Client(service_name="foo", server_url="https://example.com:8200") # Retrieve the current TraceParent as a string, requires active transaction -from elasticapm.traces import execution_context -from elasticapm.utils.disttracing import TraceParent -transaction = execution_context.get_transaction() -traceparent_string = transaction.trace_parent.to_string() +traceparent_string = elasticapm.get_trace_parent_header() # Create a TraceParent object from a string and use it for a new transaction parent = elasticapm.trace_parent_from_string(traceparent_string)