Search code examples
google-cloud-platformgoogle-cloud-functionsgoogle-cloud-trace

Google Cloud Platform Trace from Cloud Function Invocation to Cloud Run HttpRequest


We have a cloud function (v1 for organization restraints) that is triggered from a cloud storage event. It makes a request to a service running in Cloud Run. We have enabled tracing and structured logging in cloud run by configuring our logger to populate the "logging.googleapis.com/trace" property in all of our logs. This works great and we can correlate all the log messages to an http request.

We want to extend that to be able to correlate the function invocation to the http request being serviced in Cloud Run. Is it possible to generate a traceId in a cloud function and pass that along to the cloud run instance? I'm trying to find documentation or samples for this but coming up blank.

Is it possible to have a GCP trace context include both a cloud function event and logs generated in subsequent Cloud Run http requests?


Solution

  • To access the traceid in a cloud storage event you can use an undocumented property on the CloudEvent type. The following function will return the cloud function's traceparent header value, which you can then forward to other cloud run service invocations to link a cloud function invocation to the same trace context as your api request processing.

    export const getTraceId = (cloudevent: any): string | undefined => cloudevent.traceparent;
    

    The cloud event type is an any type because the CloudEvent type from the @google-cloud/functions-framework library doesn't expose a public traceparent property on the CloudEvent type even though it gets exposed at runtime.

    import { CloudEvent, cloudEvent } from '@google-cloud/functions-framework';
    ...
    
    cloudEvent('processHl7', async (cloudevent: CloudEvent<StorageObjectData>): Promise<void> => {
    ...
      const traceId = getTraceId(cloudevent);
    ...
    }
    

    Then when you build the node-fetch request to your backend you can populate the value in a request header like this:

    const getHeaders = (token: string, traceId?: string): Headers => {
      const _headers = new Headers({
        'Content-Type': 'application/json',
        Authorization: `Bearer ${token}`,
      });
    
      if (traceId) {
        _headers.append('traceparent', traceId);
      }
      return _headers;
    }