OpenTelemetry interoperability in Node.js

OneAgent version 1.229+

OpenTelemetry interoperability connects the Dynatrace AWS Lambda extension to the OpenTelemetry Node.js instrumentation to use the instrumentation packages and extensions. You can then monitor technologies like databases or messaging frameworks that aren't supported by Dynatrace AWS Lambda extension out of the box.

Before you start

  • Ensure that OpenTelemetry interoperability is enabled.

  • Verify that the installed JavaScript OpenTelemetry API is compatible with the Dynatrace AWS Lambda extension. The following table lists the compatible versions:

    OneAgent version
    Maximum OpenTelemetry API version
    1.229+
    1.0.x
    1.241+
    1.1.x
    1.257+
    1.2.x
    1.259+
    1.3.x
    1.261+
    1.4.x
    1.279+
    1.6.x
    1.283+
    1.7.x
    1.289+
    1.8.x
    1.297+
    1.9.x

Use OpenTelemetry Node.js instrumentation

When using an OpenTelemetry Node.js instrumentation, the configuration of all necessary OpenTelemetry SDK components and the registration of a TracerProvider are automatically handled by the Dynatrace AWS Lambda extension, so you don't need to register another TracerProvider.

Instrumentation packages for JavaScript can be found in the OpenTelemetry JavaScript contributions repository. Note that

The following code example shows how to instrument PostgreSQL calls in your Node.js Lambda function by using the opentelemetry-instrumentation-pg instrumentation package.

const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { PgInstrumentation } = require('@opentelemetry/instrumentation-pg');
// You must create the PgInstrumentation (and other instrumentations)
// before loading any corresponding modules, such as `require('pg')`.
registerInstrumentations({
instrumentations: [
new PgInstrumentation(),
],
});
const { Client } = require('pg');
exports.handler = async function myHandler(event, context) {
let client;
try {
client = new Client(/* DB connection information */);
await client.connect();
const result = await client.query('SELECT * FROM users;');
return result.rows;
} finally {
client?.end();
}
}

To instrument the AWS SDK for JavaScript, OpenTelemetry provides the opentelemetry/instrumentation-aws-sdk instrumentation package.

The following code example shows how the opentelemetry/instrumentation-aws-sdk instrumentation package can be used to add observability for calls to a DynamoDB database (Dynatrace version 1.244+).

const AWS = require('aws-sdk');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { AwsInstrumentation } = require('@opentelemetry/instrumentation-aws-sdk');
registerInstrumentations({
instrumentations: [
new AwsInstrumentation()
]
});
exports.handler = function(event, context) {
const ddb = new AWS.DynamoDB();
const dbParamsGetDelete = {
TableName: 'E2E_test_table',
Key: {
'svnr': { N: '1234'}
}
};
ddb.getItem(dbParamsGetDelete, function(err, data) {
if (err) {
console.error('Error', err);
} else {
console.log('Success', data.Item);
}
});
};

After running the above code snippet, the DynamoDB service page looks as follows.

DynamoDB service screen.

Use OpenTelemetry Node.js API

OpenTelemetry JavaScript can be used in an SDK-like approach to trace additional operations that aren't covered by an instrumentation package.

const opentelemetry = require('@opentelemetry/api');
const tracer = opentelemetry.trace.getTracer('my-package-name');
exports.handler = function(event, context) {
// create a span using the OTel API
const span = tracer.startSpan('do some work');
span.setAttribute('foo', 'bar');
span.end();
// ...
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Node.js'),
};
return response;
};

Trace AWS SQS and SNS messages with Node.js

OneAgent version 1.253+ for SQS OneAgent version 1.257+ for SNS

You can use @opentelemetry/instrumentation-aws-sdk package to trace AWS SQS and SNS messages and collect the traces via Dynatrace AWS Lambda extension.

Step 1 Install the required dependencies

npm install @opentelemetry/api @opentelemetry/instrumentation-aws-sdk @opentelemetry/instrumentation aws-sdk

Step 2 Set up tracing

Use the following code to set up tracing for sending SQS messages to an SQS queue from a Dynatrace-monitored Node.js application:

const { AwsInstrumentation } = require('@opentelemetry/instrumentation-aws-sdk');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
// The instrumentation must be registered before importing the aws-sdk module!
registerInstrumentations({
instrumentations: [
new AwsInstrumentation()
]
});
// You can now import the aws-sdk module if needed:
const AWS = require('aws-sdk');

Step 3 Send an SQS/SNS message

  • Via Node.js HTTP server:

    When you make a request to the HTTP server, a message is sent to an SQS queue or SNS topic. If you send a message before the root span exists, make sure to create the root span manually. For details on the span manual creation with OpenTelemetry, see OpenTelemetry traces with OneAgent.

    In this code example, a root span for the incoming HTTP request is created by the tracer.

    const http = require("http");
    const AWS = require('aws-sdk');
    const sqs = new AWS.SQS();
    const sns = new AWS.SNS();
    const server = http.createServer((req, res) => {
    const messageSendCallback = function (err, message) {
    if (err) {
    console.log("failed to send a message: " + err);
    res.writeHead(500);
    res.end("failure");
    } else {
    console.log("Success", message.MessageId);
    res.writeHead(200);
    res.end("success");
    }
    }
    if (req.url === "/send-sqs-message") {
    const params = {
    DelaySeconds: 10,
    MessageBody: "[your payload]",
    QueueUrl: "[your SQS-queue URL]"
    };
    sqs.sendMessage(params, messageSendCallback);
    } else if (req.url === "/send-sns-message") {
    const params = {
    Message: "[your payload]",
    TopicArn: "[your SNS-topic ARN]"
    };
    sns.publish(params, messageSendCallback);
    } else {
    res.writeHead(404);
    res.end("not found");
    }
    });
    server.on("close", () => { console.log("Closing server") });
    server.listen(8004, () => {
    console.log("server started!");
    });

    A request to the /send-sqs-message path should produce traces as shown below.

    SQS PurePath example with OneAgent

    The second node in the distributed trace named sqs-minimal-sample-nodejs-receiver-trigger send represents the sent SQS message and is generated by the aws-sdk instrumentation.

    Because aws-sdk package uses HTTP requests to send SQS messages, there is a call to Requests to public networks, which are captured by the OneAgent HTTP instrumentation. The call invoke comes from the AWS Lambda function subscribed to the SQS queue, which is monitored by the Dynatrace AWS Lambda extension.

  • Via AWS Lambda function

    You can send an SQS or SNS message from an AWS Lambda function monitored by the Dynatrace AWS Lambda extension.

Step 3 Receive an SQS/SNS message