How to pass elastic-apm-traceparent and traceparent headers explicitly

Hi,

I have the following use case,
Service 1 calls service 2, but it is not a normal service (sync/async) call, service 1 writes to its outbound MySQL table with all the data (request body, headers, URL, etc), later a daemon picks up entries in this table and calls the service 2.

In this scenario, elastic apm is not directly involved in the service 2 call, I was thinking, I will write the elastic-apm-traceparent and traceparent headers also to outbounds table so that it gets passed along by the daemon.

Is there a way I can get elastic-apm-traceparent and traceparent values in my application calss while writing to outbound table?

There is certainly a way!
The injectTraceHeaders and startTransactionWithRemoteParent APIs can be used. Implement a HeaderInjector to get the header name/value pairs through the addHeader method and store those. Then, implement a HeaderExtractor to read from DB when the getFirstHeader method is invoked.

Hi Eyal,
Thanks for the reply.

One more question, there is a queuing system between my service 1 and service2. This queue only allows headers starting with "X-".

So in my above example, is there a way to tell service 2 agent that the elastic-apm-transparent is coming in X-elastic-apm-transparent ?

Otherwise, I may have to write custom code in the agent also.

You can take care of that using the same - your HeaderInjector#addHeader implementation can append X- to the header name before storing it and the HeaderExtractor#getFirstHeader implementation can append X- to any requested header before looking it up.

Eyal,

The solution which you have given is still at Service 1 side - while storing in db and reading from db before sending to service 2.

My question is service 2 will get the header as X-elastic-apm-transparent. Even if the service 2 agent understand X-elastic-apm-transparent is indeed elastic-apm-transparent ?

Do I need to do anything extra since service 2 agent is getting header as X-elastic-apm-transparent ?

In service 1, when the call is made, you invoke injectTraceHeaders and the HeaderInjector implementation will be called by the agent with a header name and value. In this place, you can add X- to the header name and store it with the given value.
When the daemon reads it from the DB, IIUC, it will end up doing the actual external call, with the X- header. Then, on the accepting side, you would call startTransactionWithRemoteParent, where the HeaderExtractor implementation needs to look for a X- header, so it would retrieve the request header from the payload, but with an appended X-.
I hope this helps. If I didn't understand you setup fully, read through the documentation of these APIs and I think you should figure out a way to achieve that.