Integrate on Google Cloud Functions Node.js
The @dynatrace/opentelemetry-gcf
module provides APIs for tracing Node.js on Google Cloud Functions (GCF).
Prerequisites
Make sure you have followed the instructions on how to integrate OpenTelemetry on Google Cloud Functions.
- So far, only HTTP triggers are supported.
Cloud Function product version: 1st gen, 2nd gen
Installation
To set up OpenTelemetry Node.js integration on Google Cloud Functions, run the command below in the root directory of your Google Cloud Function project.
1npm install --save @dynatrace/opentelemetry-gcf
This will install the latest version of the @dynatrace/opentelemetry-gcf
module from NPM. Note that this library by itself is not enough to start tracing your Google Cloud Functions.
See the Usage section below for the remaining required steps.
Usage
To export traces to Dynatrace
-
Select one of the two ways below to initialize tracing.
NodeTracerProvider
used to initialize tracing is more lightweight thanNodeSDK
.NodeSDK
is typically used if you're interested in additional OpenTelemetry signals such as metrics.
Install the required OpenTelemetry packages with the command below.
1npm install --save @opentelemetry/sdk-trace-node @opentelemetry/semantic-conventionsAfter you install the packages, initialize tracing using the following snippet as an example.
1const { Resource } = require('@opentelemetry/resources');2const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');3const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');4const { DtSpanExporter, DtSpanProcessor, DtTextMapPropagator, DtSampler } = require('@dynatrace/opentelemetry-core');56const provider = new NodeTracerProvider({7 resource: new Resource({8 [SemanticResourceAttributes.SERVICE_NAME]: "My Service",9 }),10 sampler: new DtSampler(),11 // ...other configurations12});1314const processor = new DtSpanProcessor(new DtSpanExporter());15provider.addSpanProcessor(processor);16provider.register({17 propagator: new DtTextMapPropagator(),18 // ...other configurations19}); -
Start the root Google Cloud Function server span, using one of the two general patterns in OpenTelemetry below.
Example that starts and immediately activates a span inside a Google Cloud Function:
1const { startActiveHttpSpan, endHttpSpanAndFlush } = require('@dynatrace/opentelemetry-gcf');23// ...tracing initialization code45async function handler(req, res) {6 await startActiveHttpSpan(req, async (span) => {7 let error;8 try {9 // do something10 } catch (e) {11 error = e;12 }1314 // status should be set before span ends15 res.status(error != null ? 500 : 200);16 /**17 * Span must be ended and flushed before handler sends response.18 * This limitiation comes from GCF, for details see:19 * https://cloud.google.com/functions/docs/concepts/nodejs-runtime#signal-termination20 */21 await endHttpSpanAndFlush(span, res, error);22 res.send("hello world");23 });24}
Compatibility
OneAgent version | OpenTelemetry API | OpenTelemetry SDK |
---|---|---|
1.243 - 1.255 | 1.x.y | 1.0.x |
1.257 | 1.x.y | 1.0.x - 1.7.x |
1.259+ | 1.x.y | 1.0.x - 1.8.x |
1.261+ | 1.x.y | 1.0.x - 1.9.x |
1.265+ | 1.x.y | 1.0.x - 1.10.x |
1.273+ | 1.x.y | 1.0.x - 1.15.x |
Cold start
Starting a Google Cloud Function span during cold starts produces additional HTTP requests to fetch metadata from your Google Cloud Platform environment and set the attributes required for Dynatrace to process the spans.
Span flush
To ensure that spans are exported properly, you need to flush the spans before a function's response is sent to the client. For details on this limitation, see Signalling function termination.
You can use endHttpSpan()
and flushSpans()
separately instead of endHttpSpanAndFlush()
when needed.
Flushing spans in the function's code results in longer execution times, as this operation becomes part of the function's execution logic. To avoid this, you can omit the flush operation. Spans will still be periodically exported in the background.
Because code running outside the function execution can be terminated at any time, it's discouraged by Google Cloud Functions.
-
Google Cloud Functions 1st gen
Background task execution after function invocation is not guaranteed without flushing spans and might result in span loss. In practice, samples have shown that not explicitly flushing spans usually still results in correctly exported spans.
-
Google Cloud Functions 2nd gen
Google Cloud Functions 2nd gen can handle multiple concurrent requests in a single function instance. The flush operation of one invocation can prolong the execution time of another function invocation. Because function instances usually need to be kept idle for some time to handle multiple concurrent requests, you can disable the flushing of spans to improve performance. For details, see Instance lifecycle. Note that idle function instances are not guaranteed to be allocated CPU unless their CPU allocation mode is set to
CPU always allocated
.For details, see Function execution timeline.
Caveats
You need to pay special attention to cases like unhandled exceptions or function timeouts. If not handled properly, they could lead to a non-ended, and therefore non-exported, span.
Dynatrace overhead
Because span export and metadata fetch take some time during cold starts, they increase the duration of the function and subsequently increase costs.
Pay attention to infrequently invoked functions (usually with cold starts), which might require more time for the TCP handshake during span export.
Any network problem between the exporter and Dynatrace backend might also lead to unexpectedly high overhead.