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
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
- Some instrumentations might interfere with the Dynatrace HTTP and Lambda instrumentations and are automatically suppressed. These include @opentelemetry/instrumentation-http and @opentelemetry/instrumentation-aws-lambda.
- @opentelemetry/auto-instrumentations-node use is discouraged, as it includes many different instrumentations.
To instrument the AWS SDK for JavaScript, OpenTelemetry provides the opentelemetry/instrumentation-aws-sdk
instrumentation package.
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.
Install the required dependencies
Set up tracing
Send an SQS/SNS message
Receive an SQS/SNS message
Install the required dependencies
npm install @opentelemetry/api @opentelemetry/instrumentation-aws-sdk @opentelemetry/instrumentation aws-sdk
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');
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.
-
Via AWS Lambda function
You can send an SQS or SNS message from an AWS Lambda function monitored by the Dynatrace AWS Lambda extension.
const AWS = require('aws-sdk'); exports.handler = function (event, context, callback) { const sqs = new AWS.SQS(); const params = { DelaySeconds: 10, MessageBody: "[your payload]", QueueUrl: "[your SQS-queue URL]" }; sqs.sendMessage(params, function (err, data) { if (err) { context.succeed({ statusCode: 500, body: err, }); } else { console.log("SQS-Success", data.MessageId); context.succeed({ statusCode: 200, body: "SQS-Success", }); } }); }
The resulting distributed trace is similar to the Node.js application example:
const AWS = require('aws-sdk'); exports.handler = function (event, context, callback) { const sns = new AWS.SNS(); const params = { Message: "[your payload]", TopicArn: "[your SNS-topic ARN]" }; sns.publish(params, function (err, data) { if (err) { context.succeed({ statusCode: 500, body: err, }); } else { console.log("SNS-Success", data.MessageId); context.succeed({ statusCode: 200, body: "SNS-Success", }); } }); }
Receive an SQS/SNS message
You can trace SQS messages forwarded from
-
An SQS topic
The Dynatrace AWS Lambda extension automatically extracts the parent and creates a Lambda span when an AWS Lambda function is triggered by AWS SQS. However, when a batch of multiple messages is received, only the last message is considered and used for parent propagation. To propagate parents from the batch of multiple incoming messages you can, for example, manually create spans with the parent from each message.
To configure the Dynatrace AWS Lambda extension to setting parent spans manually
-
For the environment variables configuration method, set the
DT_OPEN_TELEMETRY_ALLOW_EXPLICIT_PARENT
environment variable totrue
.DT_OPEN_TELEMETRY_ALLOW_EXPLICIT_PARENT=true
-
For the JSON file configuration method, in
dtconfig.json
, set the following field totrue
.{ ...other configuration properties... "OpenTelemetry": { "AllowExplicitParent": "true" } }
Then new spans are created with the parent span extracted from each received SQS message.
-
-
An SNS topic
For SNS messages that are forwarded to SQS, the message format depends on the raw message delivery configuration on the SNS subscription.
Raw message delivery Message format Example Enabled
The SNS message attributes are converted to SQS message attributes and the parent can be directly extracted from the
MessageAttributes
of the SQS message.Disabled
The SNS message and its
MessageAttributes
are delivered as a serialized JSON string in the body of the received SQS message. To correctly link the receive span, the parent needs to be extracted from theMessageAttributes
of the serialized SNS message.- Receive a batch of multiple messages
Additional configuration is required for this example. When calling the
extractParent
method, set the value of thefromSnsPayload
parameter totrue
.
- Receive a batch of multiple messages
Additional configuration is required for this example. When calling the
AWS Lambda functions that are triggered by SNS are supported out of the box when monitored with the OneAgent layer.
AWS Lambda functions that are triggered by SNS are supported out of the box when monitored with the Dynatrace AWS Lambda extension.
SNS topics can be configured via a subscription to forward messages to an SQS queue. Messages in the SQS queue can then be consumed by a Lambda function. Tracing the received messages in the SQS-triggered AWS Lambda function works out of the box when AWS Lambda is monitored with the Dynatrace AWS Lambda extension. However, the tracer can only select a single parent, and if your Lambda function receives batches of multiple messages, special handling is required to track each message separately.
For details, see how to receive an SQS message.