Skip to main content

The Datadog AWS Lambda Layer

Project description

datadog-lambda-layer-python

CircleCI PyPI PyPI - Python Version Slack License

Datadog Lambda Layer for Python (2.7, 3.6, 3.7 and 3.8) enables custom metric submission from AWS Lambda functions, and distributed tracing between serverful and serverless environments.

IMPORTANT NOTE

AWS Lambda is expected to recieve a breaking change on January 30, 2021. If you are using Datadog Python Lambda layer version 7 or below, please upgrade to version 11.

Installation

Datadog Lambda Layer can be added to a Lambda function via AWS Lambda console, AWS CLI or Serverless Framework using the following ARN.

arn:aws:lambda:<AWS_REGION>:464622532012:layer:Datadog-<PYTHON_RUNTIME>:<VERSION>

Replace <AWS_REGION> with the AWS region where your Lambda function is published to. Replace <PYTHON_RUNTIME> with one of the following that matches your Lambda's Python runtime:

  • Datadog-Python27
  • Datadog-Python36
  • Datadog-Python37
  • Datadog-Python38

Replace <VERSION> with the latest layer version that can be found from releases. For example,

arn:aws:lambda:us-east-1:464622532012:layer:Datadog-Python37:1

PyPI

When developing your Lambda function locally where AWS Layer doesn't work, the Datadog Lambda layer can be installed from PyPI by pip install datadog-lambda or adding datadog-lambda to your project's requirements.txt.

The minor version of the datadog-lambda package always match the layer version. E.g., datadog-lambda v0.5.0 matches the content in layer version 5.

The Serverless Framework

The Datadog Serverless Framework Plugin makes it easy to manage the Datadog instrumentation for all of your Lambda functions in one place.

Instead of the plugin, you can also use the sample serverless.yml below as a reference for manually including the Lambda Layer, enable AWS X-Ray tracing, and set up environment variables.

provider:
  name: aws
  runtime: python3.7
  tracing:
    lambda: true
    apiGateway: true

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get
    layers:
      - arn:aws:lambda:<AWS_REGION>:464622532012:layer:Datadog-<PYTHON_RUNTIME>:<VERSION>
    environment:
      DD_FLUSH_TO_LOG: true

Alternatively, consider using serverless-plugin-datadog. The plugin can take care of adding lambda layers to your functions, and wrapping your handlers.

Environment Variables

DD_FLUSH_TO_LOG

Set to true (recommended) to send custom metrics asynchronously (with no added latency to your Lambda function executions) through CloudWatch Logs with the help of Datadog Forwarder.

If set to false, you also need to set DD_API_KEY and DD_SITE.

DD_API_KEY

If DD_FLUSH_TO_LOG is set to false (not recommended), the Datadog API Key must be defined as one of the following environment variables:

  • DD_API_KEY - the Datadog API Key in plain-text, NOT recommended
  • DD_KMS_API_KEY - the KMS-encrypted API Key, requires the kms:Decrypt permission
  • DD_API_KEY_SECRET_ARN - the Secret ARN to fetch API Key from the Secrets Manager, requires the secretsmanager:GetSecretValue permission (and kms:Decrypt if using a customer managed CMK)

You can also supply or override the API key at runtime (not recommended):

# Override DD API Key after importing datadog_lambda packages
from datadog import api
api._api_key = "MY_API_KEY"

DD_SITE

If DD_FLUSH_TO_LOG is set to false (not recommended), and your data need to be sent to the Datadog EU site, you must set DD_SITE to datadoghq.eu.

DD_LOGS_INJECTION

Inject Datadog trace id into logs for correlation. Defaults to true.

DD_LOG_LEVEL

Set to debug enable debug los from the Datadog Lambda Layer.

DD_ENHANCED_METRICS

Generate enhanced Datadog Lambda integration metrics, such as, aws.lambda.enhanced.invocations and aws.lambda.enhanced.errors. Defaults to true.

DD_LAMBDA_HANDLER

For use with the redirected handler method. Location of your original lambda handler.

DD_TRACE_ENABLED

When used with the redirected handler method, will auto initialize the tracer when set to true.

Basic Usage

Datadog needs to be able to read headers from the incoming Lambda event. To do this, you must wrap your handler function with our library. We provide some easy ways of wrapping your handlers.

Redirected Handler

We provide a swap in replacement handler, with zero required code changes.

  1. Set the environment variable DD_LAMBDA_HANDLER to your regular handler location, eg. myfunc.handler.
  2. Set your handler to datadog_lambda.handler.handler.

Manual Wrap

You might find it more convenient to wrap your handlers manually.

import requests
from datadog_lambda.wrapper import datadog_lambda_wrapper
from datadog_lambda.metric import lambda_metric

@datadog_lambda_wrapper
def lambda_handler(event, context):
    lambda_metric("my_metric", 10, tags=['tag:value'])
    requests.get("https://www.datadoghq.com")

Custom Metrics

Custom metrics can be submitted using lambda_metric and the Lambda handler function needs to be decorated with @datadog_lambda_wrapper. The metrics are submitted as distribution metrics.

IMPORTANT NOTE: If you have already been submitting the same custom metric as non-distribution metric (e.g., gauge, count, or histogram) without using the Datadog Lambda Layer, you MUST pick a new metric name to use for lambda_metric. Otherwise that existing metric will be converted to a distribution metric and the historical data prior to the conversion will be no longer queryable.

from datadog_lambda.wrapper import datadog_lambda_wrapper
from datadog_lambda.metric import lambda_metric

@datadog_lambda_wrapper
def lambda_handler(event, context):
    lambda_metric(
        "coffee_house.order_value",  # metric
        12.45,  # value
        tags=['product:latte', 'order:online']  # tags
    )

VPC

If your Lambda function is associated with a VPC, you need to ensure it has access to the public internet.

Distributed Tracing

Distributed tracing allows you to propagate a trace context from a service running on a host to a service running on AWS Lambda, and vice versa, so you can see performance end-to-end. Linking is implemented by injecting Datadog trace context into the HTTP request headers.

Distributed tracing headers are language agnostic, e.g., a trace can be propagated between a Java service running on a host to a Lambda function written in Python.

Because the trace context is propagated through HTTP request headers, the Lambda function needs to be triggered by AWS API Gateway or AWS Application Load Balancer.

To enable this feature, you simple need to decorate your Lambda handler function with @datadog_lambda_wrapper.

import requests
from datadog_lambda.wrapper import datadog_lambda_wrapper

@datadog_lambda_wrapper
def lambda_handler(event, context):
    requests.get("https://www.datadoghq.com")

Note, the Datadog Lambda Layer is only needed to enable distributed tracing between Lambda and non-Lambda services. For standalone Lambda functions, traces can be found in Datadog APM after configuring the X-Ray integration.

Patching

By default, widely used HTTP client libraries, such as requests, urllib2 and urllib.request are patched automatically to inject Datadog trace context into outgoing requests.

You can also manually retrieve the Datadog trace context (i.e., http headers in a Python dict) and inject it to request headers when needed.

import requests
from datadog_lambda.wrapper import datadog_lambda_wrapper
from datadog_lambda.tracing import get_dd_trace_context

@datadog_lambda_wrapper
def lambda_handler(event, context):
    headers = get_dd_trace_context()
    requests.get("https://www.datadoghq.com", headers=headers)

Sampling

The traces for your Lambda function are converted by Datadog from AWS X-Ray traces. X-Ray needs to sample the traces that the Datadog tracing agent decides to sample, in order to collect as many complete traces as possible. You can create X-Ray sampling rules to ensure requests with header x-datadog-sampling-priority:1 or x-datadog-sampling-priority:2 via API Gateway always get sampled by X-Ray.

These rules can be created using the following AWS CLI command.

aws xray create-sampling-rule --cli-input-json file://datadog-sampling-priority-1.json
aws xray create-sampling-rule --cli-input-json file://datadog-sampling-priority-2.json

The file content for datadog-sampling-priority-1.json:

{
  "SamplingRule": {
    "RuleName": "Datadog-Sampling-Priority-1",
    "ResourceARN": "*",
    "Priority": 9998,
    "FixedRate": 1,
    "ReservoirSize": 100,
    "ServiceName": "*",
    "ServiceType": "AWS::APIGateway::Stage",
    "Host": "*",
    "HTTPMethod": "*",
    "URLPath": "*",
    "Version": 1,
    "Attributes": {
      "x-datadog-sampling-priority": "1"
    }
  }
}

The file content for datadog-sampling-priority-2.json:

{
  "SamplingRule": {
    "RuleName": "Datadog-Sampling-Priority-2",
    "ResourceARN": "*",
    "Priority": 9999,
    "FixedRate": 1,
    "ReservoirSize": 100,
    "ServiceName": "*",
    "ServiceType": "AWS::APIGateway::Stage",
    "Host": "*",
    "HTTPMethod": "*",
    "URLPath": "*",
    "Version": 1,
    "Attributes": {
      "x-datadog-sampling-priority": "2"
    }
  }
}

Non-proxy integration

If your Lambda function is triggered by API Gateway via the non-proxy integration, then you have to set up a mapping template, which passes the Datadog trace context from the incoming HTTP request headers to the Lambda function via the event object.

If your Lambda function is deployed by the Serverless Framework, such a mapping template gets created by default.

Log and Trace Correlations

By default, the Datadog trace id gets automatically injected into the logs for correlation, if using the standard python logging library.

If you use a custom logger handler to log in json, you can inject the ids using the helper function get_correlation_ids manually.

Set the environment variable DD_LOGS_INJECTION to false to disable this feature.

from datadog_lambda.wrapper import datadog_lambda_wrapper
from ddtrace.helpers import get_correlation_ids

@datadog_lambda_wrapper
def lambda_handler(event, context):
  trace_id, span_id = get_correlation_ids()
  logger.info({
    "message": "hello world",
    "dd": {
      "trace_id": trace_id,
      "span_id": span_id
    }
  })

Datadog Tracer (Beta)

You can now trace Lambda functions using Datadog APM's tracing libraries (dd-trace-py).

  1. If you are using the Lambda layer, upgrade it to at least version 15.
  2. If you are using the pip package datadog-lambda-python, upgrade it to at least version v2.15.0.
  3. Install (or update to) the latest version of Datadog forwarder Lambda function. Ensure the trace forwarding layer is attached to the forwarder, e.g., ARN for Python 2.7 arn:aws:lambda:<AWS_REGION>:464622532012:layer:Datadog-Trace-Forwarder-Python27:4.
  4. Set the environment variable DD_TRACE_ENABLED to true on your function.
  5. Instrument your function using dd-trace.
from datadog_lambda.metric import lambda_metric
from datadog_lambda.wrapper import datadog_lambda_wrapper

from ddtrace import tracer

@datadog_lambda_wrapper
def hello(event, context):
  return {
    "statusCode": 200,
    "body": get_message()
  }

@tracer.wrap()
def get_message():
  return "hello world"

You can also use dd-trace and the X-Ray tracer together and merge the traces into one, using the environment variable DD_MERGE_XRAY_TRACES to true on your function.

Opening Issues

If you encounter a bug with this package, we want to hear about it. Before opening a new issue, search the existing issues to avoid duplicates.

When opening an issue, include the Datadog Lambda Layer version, Python version, and stack trace if available. In addition, include the steps to reproduce when appropriate.

You can also open an issue for a feature request.

Contributing

If you find an issue with this package and have a fix, please feel free to open a pull request following the procedures.

License

Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.

This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2019 Datadog, Inc.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

datadog_lambda-2.19.0.tar.gz (14.9 kB view details)

Uploaded Source

Built Distributions

datadog_lambda-2.19.0-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

datadog_lambda-2.19.0-py2-none-any.whl (22.8 kB view details)

Uploaded Python 2

File details

Details for the file datadog_lambda-2.19.0.tar.gz.

File metadata

  • Download URL: datadog_lambda-2.19.0.tar.gz
  • Upload date:
  • Size: 14.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/44.1.1 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/2.7.17

File hashes

Hashes for datadog_lambda-2.19.0.tar.gz
Algorithm Hash digest
SHA256 61d12a1756cb8654cb67a88a39bc78328938b20370685e4edba3be3f00ee176d
MD5 1459c370d8da6dffcfca1894c0d97334
BLAKE2b-256 a16bdbb4483e3b0af7eac7d6b9c539353210c2c70f857045c98a5fdec701a2eb

See more details on using hashes here.

File details

Details for the file datadog_lambda-2.19.0-py3-none-any.whl.

File metadata

  • Download URL: datadog_lambda-2.19.0-py3-none-any.whl
  • Upload date:
  • Size: 20.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.6.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.7.3

File hashes

Hashes for datadog_lambda-2.19.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6528acb97a866996c709bf3692c65de335f7594f0ccc479ddeb19cbbbdc69682
MD5 4ca0a4a4845fd811dde742424a8ec592
BLAKE2b-256 df866718c1f79df15efbc0cd412e39ef212a41fde754773dad7c8357ed2cf537

See more details on using hashes here.

File details

Details for the file datadog_lambda-2.19.0-py2-none-any.whl.

File metadata

  • Download URL: datadog_lambda-2.19.0-py2-none-any.whl
  • Upload date:
  • Size: 22.8 kB
  • Tags: Python 2
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/44.1.1 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/2.7.17

File hashes

Hashes for datadog_lambda-2.19.0-py2-none-any.whl
Algorithm Hash digest
SHA256 dfac031bc62742572c28146f4bda862aea75ef64b22e04a6e2a1a487521986a1
MD5 b5d5e86f875c1fed7ec06c87facc1978
BLAKE2b-256 93de8a73ec87c3be7a3a3d81367afcd2adcfb848a44a817490075542b20274a5

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page