Instrumenting Python Serverless Applications

If your Python Lambda functions are written in Python 3.6 or less, or you previously set up your Lambda functions using the Datadog Forwarder, see instrumenting using the Datadog Forwarder.
If your Lambda functions are deployed in VPC without access to the public internet, you can send data either using AWS PrivateLink for the datadoghq.com Datadog site, or using a proxy for all other sites.

Installation

Datadog offers many different ways to enable instrumentation for your serverless applications. Choose a method below that best suits your needs. Datadog generally recommends using the Datadog CLI.

The Datadog CLI modifies existing Lambda functions’ configurations to enable instrumentation without requiring a new deployment. It is the quickest way to get started with Datadog’s serverless monitoring.

  1. Install the Datadog CLI client

    npm install -g @datadog/datadog-ci
    
  2. If you are new to Datadog serverless monitoring, launch the Datadog CLI in the interactive mode to guide your first installation for a quick start, and you can ignore the remaining steps. To permanently install Datadog for your production applications, skip this step and follow the remaining ones to run the Datadog CLI command in your CI/CD pipelines after your normal deployment.

    datadog-ci lambda instrument -i
    
  3. Configure the AWS credentials

    Datadog CLI requires access to the AWS Lambda service, and depends on the AWS JavaScript SDK to resolve the credentials. Ensure your AWS credentials are configured using the same method you would use when invoking the AWS CLI.

  4. Configure the Datadog site

    Specify the Datadog site where the telemetry should be sent to. The default is datadoghq.com.

    export DATADOG_SITE="<DD_SITE>" # such as datadoghq.com, datadoghq.eu or ddog-gov.com
    
  5. Configure the Datadog API key

    Datadog recommends saving the Datadog API key in AWS Secrets Manager for security and easy rotation. The key needs to be stored as a plaintext string (not a JSON blob). Ensure your Lambda functions have the required secretsmanager:GetSecretValue IAM permission.

    export DATADOG_API_KEY_SECRET_ARN="<DATADOG_API_KEY_SECRET_ARN>"
    

    For quick testing purposes, you can also set the Datadog API key in plaintext:

    export DATADOG_API_KEY="<DATADOG_API_KEY>"
    
  6. Instrument your Lambda functions

    Note: Instrument your Lambda functions in a dev or staging environment first. If the instrumentation result is unsatisfactory, run uninstrument with the same arguments to revert the changes.

    To instrument your Lambda functions, run the following command.

    datadog-ci lambda instrument -f <functionname> -f <another_functionname> -r <aws_region> -v 58 -e 22
    

    To fill in the placeholders:

    • Replace <functionname> and <another_functionname> with your Lambda function names. Alternatively, you can use --functions-regex to automatically instrument multiple functions whose names match the given regular expression.
    • Replace <aws_region> with the AWS region name.

    Additional parameters can be found in the CLI documentation.

The Datadog Serverless Plugin automatically configures your functions to send metrics, traces, and logs to Datadog through the Datadog Lambda Extension.

To install and configure the Datadog Serverless Plugin, follow these steps:

  1. Install the Datadog Serverless Plugin:

    serverless plugin install --name serverless-plugin-datadog
    
  2. Update your serverless.yml:

    custom:
      datadog:
        site: <DATADOG_SITE>
        apiKeySecretArn: <DATADOG_API_KEY_SECRET_ARN>
    

    To fill in the placeholders:

    • Replace <DATADOG_SITE> with your Datadog site to send the telemetry to.
    • Replace <DATADOG_API_KEY_SECRET_ARN> with the ARN of the AWS secret where your Datadog API key is securely stored. The key needs to be stored as a plaintext string (not a JSON blob). The secretsmanager:GetSecretValue permission is required. For quick testing, you can instead use apiKey and set the Datadog API key in plaintext.

    For more information and additional settings, see the plugin documentation.

The Datadog CloudFormation macro automatically transforms your SAM application template to install Datadog on your functions using Lambda layers, and configures your functions to send metrics, traces, and logs to Datadog through the Datadog Lambda Extension.

  1. Install the Datadog CloudFormation macro

    Run the following command with your AWS credentials to deploy a CloudFormation stack that installs the macro AWS resource. You only need to install the macro once for a given region in your account. Replace create-stack with update-stack to update the macro to the latest version.

    aws cloudformation create-stack \
      --stack-name datadog-serverless-macro \
      --template-url https://datadog-cloudformation-template.s3.amazonaws.com/aws/serverless-macro/latest.yml \
      --capabilities CAPABILITY_AUTO_EXPAND CAPABILITY_IAM
    

    The macro is now deployed and ready to use.

  2. Instrument your Lambda functions

    Add the DatadogServerless transform after the AWS::Serverless transform under the Transform section in your for SAM template.yml.

    Transform:
      - AWS::Serverless-2016-10-31
      - Name: DatadogServerless
        Parameters:
          stackName: !Ref "AWS::StackName"
          pythonLayerVersion: 58
          extensionLayerVersion: 22
          site: "<DATADOG_SITE>"
          apiKeySecretArn: "<DATADOG_API_KEY_SECRET_ARN>"
    

    To fill in the placeholders:

    • Replace <DATADOG_SITE> with your Datadog site to send the telemetry to.
    • Replace <DATADOG_API_KEY_SECRET_ARN> with the ARN of the AWS secret where your Datadog API key is securely stored. The key needs to be stored as a plaintext string (not a JSON blob). The secretsmanager:GetSecretValue permission is required. For quick testing, you can use apiKey instead and set the Datadog API key in plaintext.

    More information and additional parameters can be found in the macro documentation.

The Datadog CDK Construct automatically installs Datadog on your functions using Lambda Layers, and configures your functions to send metrics, traces, and logs to Datadog through the Datadog Lambda Extension.

  1. Install the Datadog CDK constructs library

    # For AWS CDK v1
    pip install datadog-cdk-constructs
    
    # For AWS CDK v2
    pip install datadog-cdk-constructs-v2
    
  2. Instrument your Lambda functions

    # For AWS CDK v1
    from datadog_cdk_constructs import Datadog
    
    # For AWS CDK v2
    from datadog_cdk_constructs_v2 import Datadog
    
    datadog = Datadog(self, "Datadog",
        python_layer_version=58,
        extension_layer_version=22,
        site="<DATADOG_SITE>",
        apiKeySecretArn="<DATADOG_API_KEY_SECRET_ARN>",
      )
    datadog.add_lambda_functions([<LAMBDA_FUNCTIONS>])
    

    To fill in the placeholders:

    • Replace <DATADOG_SITE> with your Datadog site to send the telemetry to.
    • Replace <DATADOG_API_KEY_SECRET_ARN> with the ARN of the AWS secret where your Datadog API key is securely stored. The key needs to be stored as a plaintext string (not a JSON blob). The secretsmanager:GetSecretValue permission is required. For quick testing, you can use apiKey instead and set the Datadog API key in plaintext.

    More information and additional parameters can be found on the Datadog CDK documentation.

  1. Install the Datadog Lambda Library

    If you are deploying your Lambda function as a container image, you cannot use the Datadog Lambda library as a Lambda Layer. Instead, you must install the Datadog Lambda library as a dependency of your function within the image.

    pip install datadog-lambda
    

    Note that the minor version of the datadog-lambda package always matches the layer version. For example, datadog-lambda v0.5.0 matches the content of layer version 5.

  2. Install the Datadog Lambda Extension

    Add the Datadog Lambda Extension to your container image by adding the following to your Dockerfile:

    COPY --from=public.ecr.aws/datadog/lambda-extension:<TAG> /opt/extensions/ /opt/extensions
    

    Replace <TAG> with either a specific version number (for example, 22) or with latest. You can see a complete list of possible tags in the Amazon ECR repository.

  3. Redirect the handler function

    • Set your image’s CMD value to datadog_lambda.handler.handler. You can set this in AWS or directly in your Dockerfile. Note that the value set in AWS overrides the value in the Dockerfile if you set both.
    • Set the environment variable DD_LAMBDA_HANDLER to your original handler, for example, myfunc.handler.

    Note: If you are using a third-party security or monitoring tool that is incompatible with the Datadog handler redirection, you can apply the Datadog wrapper in your function code instead.

  4. Configure the Datadog site, API key, and tracing

    • Set the environment variable DD_SITE with your Datadog site to send the telemetry to.
    • Set the environment variable DD_API_KEY_SECRET_ARN with the ARN of the AWS secret where your Datadog API key is securely stored. The key needs to be stored as a plaintext string (not a JSON blob). The secretsmanager:GetSecretValue permission is required. For quick testing, you can use DD_API_KEY instead and set the Datadog API key in plaintext.
    • Set the environment variable DD_TRACE_ENABLED to true.
If you are not using a serverless development tool that Datadog supports, such as the Serverless Framework or AWS CDK, Datadog strongly encourages you instrument your serverless applications with the Datadog CLI.
  1. Install the Datadog Lambda library

    The Datadog Lambda Library can be imported either as a layer (recommended) OR as a Python package.

    The minor version of the datadog-lambda package always matches the layer version. For example, datadog-lambda v0.5.0 matches the content of layer version 5.

    • Option A: Configure the layers for your Lambda function using the ARN in the following format:

      # Use this format for x86-based Lambda deployed in AWS commercial regions
      arn:aws:lambda:<AWS_REGION>:464622532012:layer:Datadog-<RUNTIME>:58
      
      # Use this format for arm64-based Lambda deployed in AWS commercial regions
      arn:aws:lambda:<AWS_REGION>:464622532012:layer:Datadog-<RUNTIME>-ARM:58
      
      # Use this format for x86-based Lambda deployed in AWS GovCloud regions
      arn:aws-us-gov:lambda:<AWS_REGION>:002406178527:layer:Datadog-<RUNTIME>:58
      
      # Use this format for arm64-based Lambda deployed in AWS GovCloud regions
      arn:aws-us-gov:lambda:<AWS_REGION>:002406178527:layer:Datadog-<RUNTIME>-ARM:58
      

      Replace <AWS_REGION> with a valid AWS region, such as us-east-1. The available RUNTIME options are Python37, Python38 and Python39.

    • Option B: If you cannot use the prebuilt Datadog Lambda layer, alternatively install the datadog-lambda package and its dependencies locally to your function project folder using your favorite Python package manager, such as pip.

      pip install datadog-lambda -t ./
      

      Note: datadog-lambda depends on ddtrace, which uses native extensions; therefore it must be installed and compiled in a Linux environment on the right architecture (x86_64 or arm64). For example, you can use dockerizePip for the Serverless Framework and –use-container for AWS SAM. For more details, see how to add dependencies to your function deployment package.

      See the latest release.

  2. Install the Datadog Lambda Extension

    Configure the layers for your Lambda function using the ARN in the following format:

    # Use this format for x86-based Lambda deployed in AWS commercial regions
    arn:aws:lambda:<AWS_REGION>:464622532012:layer:Datadog-Extension:22
    
    # Use this format for arm64-based Lambda deployed in AWS commercial regions
    arn:aws:lambda:<AWS_REGION>:464622532012:layer:Datadog-Extension-ARM:22
    
    # Use this format for x86-based Lambda deployed in AWS GovCloud regions
    arn:aws-us-gov:lambda:<AWS_REGION>:002406178527:layer:Datadog-Extension:22
    
    # Use this format for arm64-based Lambda deployed in AWS GovCloud regions
    arn:aws-us-gov:lambda:<AWS_REGION>:002406178527:layer:Datadog-Extension-ARM:22
    

    Replace <AWS_REGION> with a valid AWS region, such as us-east-1.

  3. Redirect the handler function

    • Set your function’s handler to datadog_lambda.handler.handler.
    • Set the environment variable DD_LAMBDA_HANDLER to your original handler, for example, myfunc.handler.

    Note: If you are using a third-party security or monitoring tool that is incompatible with the Datadog handler redirection, you can apply the Datadog wrapper in your function code instead.

  4. Configure the Datadog site, API key, and tracing

    • Set the environment variable DD_SITE with your Datadog site to send the telemetry to.
    • Set the environment variable DD_API_KEY_SECRET_ARN with the ARN of the AWS secret where your Datadog API key is securely stored. The key needs to be stored as a plaintext string, instead of being inside a json blob. The secretsmanager:GetSecretValue permission is required. For quick testings, you can use DD_API_KEY instead and set the Datadog API key in plaintext.
    • Set the environment variable DD_TRACE_ENABLED to true.
  5. (AWS Chalice only) Register the middleware

    If you are using AWS Chalice, you must install datadog-lambda using pip, and register datadog_lambda_wrapper as a middleware in your app.py:

    from chalice import Chalice, ConvertToMiddleware
    from datadog_lambda.wrapper import datadog_lambda_wrapper
    
    app = Chalice(app_name='hello-chalice')
    
    app.register_middleware(ConvertToMiddleware(datadog_lambda_wrapper))
    
    @app.route('/')
    def index():
        return {'hello': 'world'}
    

What’s next?

  • You can now view metrics, logs, and traces on the Serverless Homepage.
  • See the sample code to monitor custom business logic
  • See the troubleshooting guide if you have trouble collecting the telemetry
  • See the advanced configurations to
    • connect your telemetry using tags
    • collect telemetry for AWS API Gateway, SQS, etc.
    • capture the Lambda request and response payloads
    • link errors of your Lambda functions to your source code
    • filter or scrub sensitive information from logs or traces

Monitor custom business logic

To monitor your custom business logic, submit a custom metric or span using the sample code below. For additional options, see custom metric submission for serverless applications and the APM guide for custom instrumentation.

import time
from ddtrace import tracer
from datadog_lambda.metric import lambda_metric

def lambda_handler(event, context):
    # add custom tags to the lambda function span,
    # does NOT work when X-Ray tracing is enabled
    current_span = tracer.current_span()
    if current_span:
        current_span.set_tag('customer.id', '123456')

    # submit a custom span
    with tracer.trace("hello.world"):
        print('Hello, World!')

    # submit a custom metric
    lambda_metric(
        metric_name='coffee_house.order_value',
        value=12.45,
        tags=['product:latte', 'order:online']
    )

    return {
        'statusCode': 200,
        'body': get_message()
    }

# trace a function
@tracer.wrap()
def get_message():
    return 'Hello from serverless!'

Further Reading