Trace Azure Functions written in Node.js
The @dynatrace/opentelemetry-azure-functions
module provides APIs for tracing Node.js on Azure Functions.
Prerequisites
Ensure that you have followed the initial configuration steps described in Set up OpenTelemetry monitoring for Azure Functions on Consumption Plan before using the packages below.
- @dynatrace/opentelemetry-azure-functions version 1.243+
Installation
To set up OpenTelemetry Node.js integration on Azure Functions, run the following command.
1npm install --save @dynatrace/opentelemetry-azure-functions
Trace export
To export traces to Dynatrace
-
Select one of the two ways below to initialize tracing.
NodeTracerProvider
—more lightweight thanNodeSDK
NodeSDK
—typically used if you're interested in additional OpenTelemetry signals such as metrics
It is possible to bundle several Azure Functions into a single Azure Function app. It's therefore important to initialize tracing only once per Azure Function app instead of once per function. The simplest way to do this is to put a tracing setup code into a shared file as described in the Azure Functions JavaScript developer guide and require it at the top of all functions.
The tracing setup code should be implemented to set up tracing only once before any other third-party module is required.
1import { Resource } from "@opentelemetry/resources";2import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";3import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";4import { DtSpanExporter, DtSpanProcessor, DtTextMapPropagator, DtSampler } from "@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 exporter = new DtSpanExporter();15const processor = new DtSpanProcessor(exporter);16provider.addSpanProcessor(processor);17provider.register({18 propagator: new DtTextMapPropagator(),19 // ...other configurations20});
1import { Resource } from "@opentelemetry/resources";2import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";3import { NodeSDK } from "@opentelemetry/sdk-node";4import { DtSpanExporter, DtSpanProcessor, DtTextMapPropagator, DtSampler } from "@dynatrace/opentelemetry-azure-functions";56const sdk = new NodeSDK({7 resource: new Resource({8 [SemanticResourceAttributes.SERVICE_NAME]: "My Service"9 }),10 sampler: new DtSampler(),11 spanProcessor: new DtSpanProcessor(new DtSpanExporter()),12 textMapPropagator: new DtTextMapPropagator(),13 // ...other configurations14});1516sdk.start().then(() => {17 // Resources have been detected and SDK is started18});
Wrap your function handler as below and export the wrapped handler.
1import type { AzureFunction, Context, HttpRequest } from "@azure/functions"2// Import the wrapHandler function.3import { wrapHandler } from "@dynatrace/opentelemetry-azure-functions";45const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {6 // The created span is set as active by the OpenTelemetry ContextManager here7 context.log("HTTP trigger function processed a request.");89 const name = (req.query.name || (req.body && req.body.name));10 const responseMessage = name11 ? "Hello, " + name + ". This HTTP triggered function executed successfully."12 : "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.";1314 context.res = {15 status: 200,16 body: responseMessage17 };18};1920// Export the wrapped handler function.21export default wrapHandler(httpTrigger);
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 |
Supported Azure Functions runtime:
4.x
Limitations
-
Only
async
function handlers are supported.- This follows the Azure recommendation to use
async
andawait
. wrapHandler
returns any non-async
function unwrapped, so the function itself will work but no span will be created.- Note that async functions were introduced in ECMAScript 2017. No span will be created if an earlier version of ECMAScript is used. In case TypeScript is used, make sure compilation target is set to ECMAScript 2017 or higher.
- This follows the Azure recommendation to use
-
Signaling function completion using the deprecated
context.done()
orcontext.res.send()
calls is not supported. Either use a$return
binding and return the result from the function handler, or use a namedout
binding and setcontext.binding.<name>
. For HTTP triggers, settingcontext.res
is also supported.