• Home
  • Deploy Dynatrace
  • Set up Dynatrace on cloud platforms
  • Microsoft Azure
  • Integrations
  • Monitor Azure Functions
  • Monitor Azure Functions on Consumption Plans
  • Trace Azure Functions written in Node.js

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.

bash
npm install --save @dynatrace/opentelemetry-azure-functions

Trace export

To export traces to Dynatrace

  1. Select one of the two ways below to initialize tracing.

    • NodeTracerProvider—more lightweight than NodeSDK
    • 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.

NodeTracerProvider example (recommended)
typescript
import { Resource } from "@opentelemetry/resources"; import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions"; import { DtSpanExporter, DtSpanProcessor, DtTextMapPropagator, DtSampler } from "@dynatrace/opentelemetry-core"; const provider = new NodeTracerProvider({ resource: new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: "My Service", }), sampler: new DtSampler(), // ...other configurations }); const exporter = new DtSpanExporter(); const processor = new DtSpanProcessor(exporter); provider.addSpanProcessor(processor); provider.register({ propagator: new DtTextMapPropagator(), // ...other configurations });
NodeSDK example
typescript
import { Resource } from "@opentelemetry/resources"; import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions"; import { NodeSDK } from "@opentelemetry/sdk-node"; import { DtSpanExporter, DtSpanProcessor, DtTextMapPropagator, DtSampler } from "@dynatrace/opentelemetry-azure-functions"; const sdk = new NodeSDK({ resource: new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: "My Service" }), sampler: new DtSampler(), spanProcessor: new DtSpanProcessor(new DtSpanExporter()), textMapPropagator: new DtTextMapPropagator(), // ...other configurations }); sdk.start().then(() => { // Resources have been detected and SDK is started });
  1. Wrap your function handler as below and export the wrapped handler.
typescript
import type { AzureFunction, Context, HttpRequest } from "@azure/functions" // Import the wrapHandler function. import { wrapHandler } from "@dynatrace/opentelemetry-azure-functions"; const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> { // The created span is set as active by the OpenTelemetry ContextManager here context.log("HTTP trigger function processed a request."); const name = (req.query.name || (req.body && req.body.name)); const responseMessage = name ? "Hello, " + name + ". This HTTP triggered function executed successfully." : "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."; context.res = { status: 200, body: responseMessage }; }; // Export the wrapped handler function. export default wrapHandler(httpTrigger);

Compatibility

OneAgent versionOpenTelemetry APIOpenTelemetry SDK
1.243 - 1.2551.x.y1.0.x
1.2571.x.y1.0.x - 1.7.x
1.259+1.x.y1.0.x - 1.8.x

Supported Azure Functions runtime:

  • 4.x

Limitations

  • Only async function handlers are supported.

    • This follows the Azure recommendation to use async and await.
    • wrapHandler returns any non-async function unwrapped, so the function itself will work but no span will be created.
  • Signaling function completion using the deprecated context.done() or context.res.send() calls is not supported. Either use a $return binding and return the result from the function handler, or use a named out binding and set context.binding.<name>. For HTTP triggers, setting context.res is also supported.

Related topics
  • Set up Dynatrace on Microsoft Azure

    Set up and configure monitoring for Microsoft Azure.