There are many ways to setup the dynatrace agent for Lambdas. The list can be seen below:
I don't have a preferred way to do so, but looking at the way we build our lambdas, the most efficient for us is a combination of environment variables and serverless framework.
Prerequisites
As of 3 Sept 2021, Dynatrace only supports the OneAgent for Lambda which runtime based on Amazon Linux 2 image.
Trace Python, Node.js, and Java Lambda functions
Lambda runtimes - AWS Lambda
Environment Variables
The following base environment variables need to be set into the Lambda’s environment
AWS_LAMBDA_EXEC_WRAPPER = /opt/dynatrace
DT_TENANT = vpc123456
DT_CLUSTER_ID = 1234456789 # Dynatrace Cluster Id
DT_CONNECTION_BASE_URL = https://vpc123456.live.dynatrace.com
DT_CONNECTION_AUTH_TOKEN = dt0a01.vpc123456.b19e9577f4cqerew43f9721ba4282a0d8004ae36bbba9983421231aaa4e
DT_LOGGING_DESTINATION: stdout
To add log monitoring there are language-specific values that need to added:
DT_LOGGING_NODEJS_FLAGS: Exporter=true,LambdaSensor=true
DT_LOGGING_PYTHON_FLAGS dynatrace=True
DT_LOGGING_JAVA_FLAGS=log-Transformer=true,log-EmbeddedJarClassLoader=true,log-OpenTelemetryUtils=true,log-AsyncClassRetransformer=true,log-ClassValue=true
If the lambda is coded in NodeJS, use DT_LOGGING_NODEJS_FLAGS accordingly, and so on.
These are hard-coded values that really never change unless we change our Dynatrace Tenancy.
Dynatrace Agent
The Dynatrace agent is nothing but a simple Lambda Layer. There are 3 Programming Languages supported at the moment: Java, NodeJS, and Python. Each has its own Lambda Layer ARN. The AWS Region also plays a part on the ARN String Formulation. The 725887861453 being the Dynatrace AWS Account.
NodeJS = arn:aws:lambda:ap-southeast-2:725887861453:layer:Dynatrace_OneAgent_1_215_1_20210326-040705_nodejs:1
Java = arn:aws:lambda:ap-southeast-2:725887861453:layer:Dynatrace_OneAgent_1_215_161_20210428-142723_java:1
Python = arn:aws:lambda:ap-southeast-2:725887861453:layer:Dynatrace_OneAgent_1_215_2_20210326-095702_python:1
Serverless Framework
Depending on how you configure your serverless framework, files to be updated depends on that. In our case, we split out stages (or environment) and serverless yaml.
stages.yml | env.yml
default_env: &default_env
apm_exec_wrapper: '/opt/dynatrace'
apm_tenant: vpc123456
apm_cluster_id: 1234456789
apm_base_url: https://vpc123456.live.dynatrace.com
apm_auth_token: dt0a01.vpc123456.b19e9577f4cqerew43f9721ba4282a0d8004ae36bbba9983421231aaa4e
apm_layer: arn:aws:lambda:ap-southeast-2:725887861453:layer:Dynatrace_OneAgent_1_215_1_20210326-040705_nodejs:1
apm_log_dest: stdout
apm_log_flags: 'Exporter=true,LambdaSensor=true'
On every environment key, add the following line <<: *default_env:
qa:
<<: *default_env
...
...
show:
<<: *default_env
...
...
prod:
<<: *default_env
...
...
This will tell each environment to use the same settings as the default_env.
serverless.yml
Create a custom layer if not yet created, add the following lines
custom:
# custom environment
environment: ${file(./stages.yml):${opt:stage}}
# dynatrace environment variables
apm_exec_wrapper: ${file(./stages.yml):${opt:stage}.apm_exec_wrapper}
apm_tenant: ${file(./stages.yml):${opt:stage}.apm_tenant}
apm_cluster_id: ${file(./stages.yml):${opt:stage}.apm_cluster_id}
apm_base_url: ${file(./stages.yml):${opt:stage}.apm_base_url}
apm_auth_token: ${file(./stages.yml):${opt:stage}.apm_auth_token}
apm_log_dest: ${file(./stages.yml):${opt:stage}.apm_log_dest}
apm_log_flags: ${file(./stages.yml):${opt:stage}.apm_log_flags}
# dynatrace lambda layer
apm_layer: ${file(./stages.yml):${opt:stage}.apm_layer}
Plugin the Environment variables under the provider layer, create if none
provider:
...
...
environment:
...
...
# dynatrace environment variables
AWS_LAMBDA_EXEC_WRAPPER: ${self:custom.environment.apm_exec_wrapper}
DT_TENANT: ${self:custom.environment.apm_tenant}
DT_CLUSTER_ID: ${self:custom.environment.apm_cluster_id}
DT_CONNECTION_BASE_URL: ${self:custom.environment.apm_base_url}
DT_CONNECTION_AUTH_TOKEN: ${self:custom.environment.apm_auth_token}
DT_LOGGING_DESTINATION: ${self:custom.environment.apm_log_dest}
DT_LOGGING_NODEJS_FLAGS: ${self:custom.environment.apm_log_flags}
...
...
...
On every function that is defined, add the Dynatrace Lambda Layer
functions:
...
consume:
handler: ...
layers:
- ${self:custom.apm_layer}
...
...
Dynatrace UI
When a Lambda is fully integrated into Dynatrace you will be able to see a direct link to the Lambda Cloudwatch Logs and it will be part of the Dynatrace Service.

Top comments (0)