Search code examples
node.jsfirebasegoogle-cloud-functionsgoogle-cloud-logging

How can I get traceId in a Firebase cloud function?


I would like to propagate traceId between a couple microservices in Firebase/GCP by 1) getting the traceId from the root service, and 2) propagating it using "x-cloud-trace-context" in the header of the API call for the second. Part two is working fine for me, but I can't get the traceId of the root service for the life of me.

The function is defined in this style through firebase (using Pub/Sub, Scheduler, etc):

export const foobar = functions.region(REGION).runWith({ memory: '2GB' }).pubsub.schedule('*/15 * * * *').onRun(async (context) => { ...function }

I have tried @google-cloud/trace-agent, @opencensus/propagation-tracecontext, @opentelemetry/api, etc with no luck in extracting a traceId from the root (foobar in this example). When I look at GCP Logs Explorer I see that there is a traceId, so I'd be thrilled to be able to extract that, or even overwrite that traceId with one that I make myself.

I tried this with GCP Trace-Agent, but the contexts came out null

TraceAgent.start()
const tracer = TraceAgent.get()
const span = tracer.getCurrentRootSpan()
const childSpan = tracer.createChildSpan({ name: 'new-span' })
console.log(span.getTraceContext())
console.log(childSpan.getTraceContext())

Also tried similar calls with the other packages I mentioned.

I inspected the context passed from PubSub but there was no useful information in that

Any help would be much appreciated. Thx.


Solution

  • Ok, worked it out. Unfortunately the only way I could solve this was using the deprecated function process._getActiveHandles(). This will return active handles such as the open http request presumably opened by GCP Cloud Functions. In there you can get the headers which include the x-cloud-trace-context and traceparent.

    Something like this should work:

    function findTraceId() {
        const activeHandles = process._getActiveHandles()
        for (const handle of activeHandles) {
            const headers = handle?._httpMessage?.req?.rawHeaders
            const traceIdIndex = headers.indexOf('X-Cloud-Trace-Context')
            return headers[traceIdIndex + 1].split('/')[0]
        }
    }