I am using several APM agents to instrument some applications, in several languages (C#, Python, Java and JS). Everything works fine in operations that runs synchronous, but I have async situations.
In async scenarios, I want to save trace information, example:
T1 - Do something and notify RabbitMQ
T2 - Subscribe RabbitMQ and start a new Transaction when T1 notify
When T1 notify that did something, it will save trace informations, and T2 should use this data to set traceId and parentId.
With Java agent I did it using startTransactionWithRemoteParent passing the elastic-apm-traceparent value, but I can't do it with .Net and Python agents.
I tryed do it to Python using the elasticapm.set_custom_context method, but I had no success. There is some way to do it in Python or .Net? I really need start a new transaction as the child of a remote parent, as I do in Java.
this isn't currently documented in the Python agent docs, but you can set the trace parent manually:
from elasticapm.utils.disttracing import TraceParent
trace_parent = TraceParent.from_string(your_traceparent_string)
I'll let one of our .Net agent engineers answer if/how this is done with the .net agent
you can also do this in .NET.
This is not released yet, but it's already on master, so if you built the agent yourself you will have these overload, and of course it will be also included in the next version.
Here is how you serialize the trace parent:
var tracingData = transaction.OutgoingDistributedTracingData.SerializeToString();
This will be a string that you can deserialize on the other side:
var transactionOnTheOtherSide = Agent.Tracer.StartTransaction("TransactionName", "TestTransactionType", DistributedTracingData.TryDeserializeFromString(tracingData));
As you can see, you can pass the
tracingData to the
DistributedTracingData.TryDeserializeFromString and with that you can call
StartTransaction method, which will continue the trace. You can also use
CaptureTransaction, it also has this parameter.
ps: the .NET APM agent is currently in alpha, and we may rename things. Seeing this next to the Python API I'm not sure
DistributedTracingData are the right names. Feel free to express your opinion on this.
I am really happy with your help, everything works like a charm, and now I can set the remote parent to my transactions. Thanks for your help.
I have only one more question, I searched in all the documentation but I couldn't find nothing about it. I need to retrieve the trace information (traceId and transactionId) of my current transaction to permit that other transactions get this data and use it as remote parent.
According with my example, I need send to RabbitMQ the trace context about T1 to T2 use it. There is a way to I do it?
Thanks for your answer, and for your help, I will pull master and do a local build to test this constructor. It is all I need, retrieve and set de trace context in my transactions. I already did a local build to test the distributed tracing, now I will test this new feature that lets me manually works with trace context.
Sorry for bother you again, but I really need this help.
In Java agent I can use the transaction.geId() and transaction.geTraceId methods to retrieve trace information. In .Net agent I can do it usingtransaction.OutgoingDistributedTracingData.SerializeToString() method. But I really could not find any example or documentation about how get this information in Python agent. Could you help me, giving me an example or showing the right documentation place?
You should be able to do something like this
from elasticapm.traces import execution_context
# get current transaction
transaction = execution_context.get_transaction()
trace_parent = transaction.trace_parent
trace_parent_str = trace_parent.to_string()
does that help?
That was perfect, everything that I need, thanks for your help.
This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.