---
title: Instrumenting Go Serverless Applications
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Serverless > Serverless Monitoring for AWS Lambda > Instrument AWS
  Lambda applications > Instrumenting Go Serverless Applications
---

# Instrumenting Go Serverless Applications

{% alert level="danger" %}
If your Go Lambda functions are still using runtime `go1.x` and you cannot migrate to the `provided.al2` runtime, you must [instrument using the Datadog Forwarder](https://docs.datadoghq.com/serverless/guide/datadog_forwarder_go). Otherwise, follow the instructions in this guide to instrument using the Datadog Lambda Extension.
{% /alert %}

{% alert level="info" %}
Version 67+ of the Datadog Lambda Extension is optimized to significantly reduce cold start duration. [Read more](https://docs.datadoghq.com/serverless/aws_lambda/configuration/?tab=datadogcli#using-datadog-lambda-extension-v67).
{% /alert %}

{% callout %}
##### Agentically add Datadog to your Lambda Functions

Agentic onboarding for Datadog Serverless is in Preview. Use your favorite AI coding tool such as Cursor or Claude to bulk-add Datadog monitoring to your Lambda functions.

[Request Access](https://www.datadoghq.com/product-preview/agentic-onboarding-for-serverless-applications/)
{% /callout %}

## Setup{% #setup %}

**Note**: Datadog recommends using v2 of the Go tracer to instrument AWS Lambda functions. See the [migration instructions](https://github.com/DataDog/dd-trace-go/tree/main/contrib/aws/datadog-lambda-go) for guidance on upgrading from v1 to v2.

{% tab title="Datadog UI" %}
You can instrument your Go AWS Lambda application directly within Datadog. Navigate to the [Serverless > AWS Lambda](https://app.datadoghq.com/functions?cloud=aws) page and select [**Instrument Functions**](https://app.datadoghq.com/serverless/aws/lambda/setup).

For more information, see [Remote instrumentation for AWS Lambda](https://docs.datadoghq.com/serverless/aws_lambda/remote_instrumentation).
{% /tab %}

{% tab title="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

   ```sh
   npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-lambda
   ```

1. If you are new to Datadog serverless monitoring, launch the Datadog CLI in 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.

   ```sh
   datadog-ci lambda instrument -i
   ```

1. Configure the AWS credentials

The Datadog CLI requires access to the AWS Lambda service and depends on the AWS JavaScript SDK to [resolve the credentials](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html). Ensure your AWS credentials are configured using the same method you would use when invoking the AWS CLI.

1. Configure the Datadog site

   ```sh
   export DATADOG_SITE="<DATADOG_SITE>"
   ```

Replace `<DATADOG_SITE>` with  (ensure the correct SITE is selected on the right).

1. 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.

   ```sh
   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:

   ```sh
   export DATADOG_API_KEY="<DATADOG_API_KEY>"
   ```

1. Instrument your Lambda functions

**Note**: Instrument your Lambda functions in a dev or staging environment first! Should the instrumentation result be unsatisfactory, run `uninstrument` with the same arguments to revert the changes.

To instrument your Lambda functions, run the following command.

   ```sh
   datadog-ci lambda instrument -f <functionname> -f <another_functionname> -r <aws_region> -e 94
   ```

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](https://docs.datadoghq.com/serverless/serverless_integrations/cli).

{% /tab %}

{% tab title="Serverless Framework" %}
The [Datadog Serverless Plugin](https://docs.datadoghq.com/serverless/serverless_integrations/plugin) automatically configures your functions to send metrics, traces, and logs to Datadog through the [Datadog Lambda Extension](https://docs.datadoghq.com/serverless/libraries_integrations/extension).

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

### Install the Datadog Serverless Plugin:{% #install-the-datadog-serverless-plugin %}

```sh
serverless plugin install --name serverless-plugin-datadog
```

### Update your `serverless.yml`:{% #update-your-serverlessyml %}

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

To fill in the placeholders:

- Replace `<DATADOG_SITE>` with your [Datadog site](https://docs.datadoghq.com/getting_started/site/) to send the telemetry to.
- Replace `<DATADOG_API_KEY_SECRET_ARN>` with the ARN of the AWS secret where your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys) 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](https://docs.datadoghq.com/serverless/serverless_integrations/plugin).
{% /tab %}

{% tab title="AWS SAM" %}
The [Datadog CloudFormation macro](https://docs.datadoghq.com/serverless/serverless_integrations/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](https://docs.datadoghq.com/serverless/libraries_integrations/extension).

1. Install the Datadog CloudFormation macro

Run the following command with your [AWS credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) 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.

   ```sh
   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.

1. Instrument your Lambda functions

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

   ```yaml
   Transform:
     - AWS::Serverless-2016-10-31
     - Name: DatadogServerless
       Parameters:
         stackName: !Ref "AWS::StackName"
         extensionLayerVersion: 94
         site: "<DATADOG_SITE>"
         apiKeySecretArn: "<DATADOG_API_KEY_SECRET_ARN>"
   ```

To fill in the placeholders:

   - Replace `<DATADOG_SITE>` with  (ensure the correct SITE is selected on the right).
   - Replace `<DATADOG_API_KEY_SECRET_ARN>` with the ARN of the AWS secret where your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys) 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](https://docs.datadoghq.com/serverless/serverless_integrations/macro).

{% /tab %}

{% tab title="AWS CDK" %}

{% alert level="info" %}
Instrumenting Go functions through the Datadog CDK construct is only available for AWS CDK apps written in Typescript, Python, and Go.
{% /alert %}

The [Datadog CDK construct](https://github.com/DataDog/datadog-cdk-constructs) automatically installs Datadog on your functions using Lambda layers. It configures your functions to send metrics, traces, and logs to Datadog through the Datadog Lambda Extension.

### TypeScript{% #typescript %}

1. Install the Datadog CDK constructs library

For AWS CDK v1:

   ```sh
   npm install datadog-cdk-constructs --save-dev
   ```

For AWS CDK v2:

   ```sh
   npm install datadog-cdk-constructs-v2 --save-dev
   ```

1. Instrument your Lambda functions

For AWS CDK v1:

   ```typescript
   import { Datadog } from "datadog-cdk-constructs";
   
   const datadog = new Datadog(this, "Datadog", {
       extensionLayerVersion: 94,
       site: "<DATADOG_SITE>",
       apiKeySecretArn: "<DATADOG_API_KEY_SECRET_ARN>"
   });
   datadog.addLambdaFunctions([<LAMBDA_FUNCTIONS>])
   ```

For AWS CDK v2:

   ```typescript
   import { DatadogLambda } from "datadog-cdk-constructs-v2";
   
   const datadogLambda = new DatadogLambda(this, "datadogLambda", {
       extensionLayerVersion: 94,
       site: "<DATADOG_SITE>",
       apiKeySecretArn: "<DATADOG_API_KEY_SECRET_ARN>"
   });
   datadogLambda.addLambdaFunctions([<LAMBDA_FUNCTIONS>])
   ```

### Python{% #python %}

1. Install the Datadog CDK constructs library

For AWS CDK v1:

   ```sh
   pip install datadog-cdk-constructs
   ```

For AWS CDK v2:

   ```sh
   pip install datadog-cdk-constructs-v2
   ```

1. Instrument your Lambda functions

For AWS CDK v1:

   ```python
   from datadog_cdk_constructs import Datadog
   datadog = Datadog(self, "Datadog",
       extension_layer_version=94,
       site="<DATADOG_SITE>",
       api_key_secret_arn="<DATADOG_API_KEY_SECRET_ARN>",
     )
   datadog.add_lambda_functions([<LAMBDA_FUNCTIONS>])
   ```

For AWS CDK v2:

   ```python
   from datadog_cdk_constructs_v2 import DatadogLambda
   
   datadog = DatadogLambda(self, "datadogLambda",
       extension_layer_version=94,
       site="<DATADOG_SITE>",
       api_key_secret_arn="<DATADOG_API_KEY_SECRET_ARN>",
     )
   datadog.add_lambda_functions([<LAMBDA_FUNCTIONS>])
   ```

### Go{% #go %}

**Note**: Go CDK constructs are only available for AWS CDK v2.

1. Install the Datadog CDK constructs library

   ```sh
   go get github.com/DataDog/datadog-cdk-constructs-go/ddcdkconstruct/v3
   ```

1. Instrument your Lambda functions

   ```go
   import (
       "github.com/DataDog/datadog-cdk-constructs-go/ddcdkconstruct/v3"
   )
   
   datadogLambda := ddcdkconstruct.NewDatadogLambda(
       stack,
       jsii.String("Datadog"),
       &ddcdkconstruct.DatadogLambdaProps{
           ExtensionLayerVersion: jsii.Number(94),
           Site:                  jsii.String("<DATADOG_SITE>"),
           ApiKeySecretArn:       jsii.String("<DATADOG_API_KEY_SECRET_ARN>"),
       })
   datadogLambda.AddLambdaFunctions(&[]interface{}{<LAMBDA_FUNCTIONS>}, nil)
   ```

To fill in the placeholders:

- Replace `<DATADOG_SITE>` with  (ensure the correct SITE is selected on the right).
- Replace `<DATADOG_API_KEY_SECRET_ARN>` with the ARN of the AWS secret where your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys) is securely stored. The key needs to be stored as a plaintext string (not a JSON blob). Ensure your Lambda execution role has the `secretsmanager:GetSecretValue` IAM permission in order to read the secret value. 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](https://github.com/DataDog/datadog-cdk-constructs).
{% /tab %}

{% tab title="Container Image" %}

1. Install the Datadog Lambda Extension

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

Replace `<TAG>` with either a specific version number (for example, `94`) or with `latest`. Alpine is also supported with specific version numbers (such as `94-alpine`) or with `latest-alpine`. You can see a complete list of possible tags in the [Amazon ECR repository](https://gallery.ecr.aws/datadog/lambda-extension).

1. Set the required environment variables

   - Set `DD_SITE` to  (ensure the correct SITE is selected on the right).
   - Set `DD_API_KEY_SECRET_ARN` to the ARN of the AWS secret where your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys) 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.
   - Optionally set `DD_UNIVERSAL_INSTRUMENTATION: true` to take advantage of [advanced configurations](https://docs.datadoghq.com/serverless/configuration/) such as capturing the Lambda request and response payloads and inferring APM spans from incoming Lambda events.

{% /tab %}

{% tab title="Terraform" %}
The [`lambda-datadog`](https://registry.terraform.io/modules/DataDog/lambda-datadog/aws/latest) Terraform module wraps the [`aws_lambda_function`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) resource and automatically configures your Lambda function for Datadog Serverless Monitoring by:

- Adding the Datadog Lambda layers
- Redirecting the Lambda handler
- Enabling the collection and sending of metrics, traces, and logs to Datadog

```tf
module "lambda-datadog" {
  source  = "DataDog/lambda-datadog/aws"
  version = "4.0.0"

  environment_variables = {
    "DD_API_KEY_SECRET_ARN" : "<DATADOG_API_KEY_SECRET_ARN>"
    "DD_ENV" : "<ENVIRONMENT>"
    "DD_SERVICE" : "<SERVICE_NAME>"
    "DD_SITE": "<DATADOG_SITE>"
    "DD_VERSION" : "<VERSION>"
  }

  datadog_extension_layer_version = 94

  # aws_lambda_function arguments
}
```

1. Replace the `aws_lambda_function` resource with the `lambda-datadog` Terraform module. Then, specify the `source` and `version` of the module.

1. Set the `aws_lambda_function` arguments:

All of the arguments available in the `aws_lambda_function` resource are available in this Terraform module. Arguments defined as blocks in the `aws_lambda_function` resource are redefined as variables with their nested arguments.

For example, in `aws_lambda_function`, `environment` is defined as a block with a `variables` argument. In the `lambda-datadog` Terraform module, the value for the `environment_variables` is passed to the `environment.variables` argument in `aws_lambda_function`. See [inputs](https://github.com/DataDog/terraform-aws-lambda-datadog?tab=readme-ov-file#inputs) for a complete list of variables in this module.

1. Fill in the environment variable placeholders:

   - 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 the environment variable `DD_API_KEY` and set your Datadog API key in plaintext.
   - Replace `<ENVIRONMENT>` with the Lambda function's environment, such as `prod` or `staging`
   - Replace `<SERVICE_NAME>` with the name of the Lambda function's service
   - Replace `<DATADOG_SITE>` with . (Ensure the correct [Datadog site](https://docs.datadoghq.com/getting_started/site/) is selected on this page).
   - Replace `<VERSION>` with the version number of the Lambda function

1. Select the version of the Datadog Extension Lambda layer to use. If left blank the latest layer version will be used.

```
  datadog_extension_layer_version = 94
```

{% /tab %}

{% tab title="SST v3" %}
To configure Datadog using SST v3, follow these steps:

```ts
const app = new sst.aws.Function("MyApp", {
  handler: "./src",
  runtime: "go",
  environment: {
    DD_ENV: "<ENVIRONMENT>",
    DD_SERVICE: "<SERVICE_NAME>",
    DD_VERSION: "<VERSION>",
    DATADOG_API_KEY_SECRET_ARN: "<DATADOG_API_KEY_SECRET_ARN>",
    DD_SITE: "<DATADOG_SITE>",
  },
  layers: [
    $interpolate`arn:aws:lambda:${aws.getRegionOutput().name}:464622532012:layer:Datadog-Extension:94`,
  ],
});
```

Fill in the environment variable placeholders:

- 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 the environment variable `DD_API_KEY` and set your Datadog API key in plaintext.
- Replace `<ENVIRONMENT>` with the Lambda function's environment, such as `prod` or `staging`
- Replace `<SERVICE_NAME>` with the name of the Lambda function's service
- Replace `<DATADOG_SITE>` with . (Ensure the correct [Datadog site](https://docs.datadoghq.com/getting_started/site/) is selected on this page).
- Replace `<VERSION>` with the version number of the Lambda function

{% /tab %}

{% tab title="Custom" %}
### Install the Datadog Lambda Extension{% #install-the-datadog-lambda-extension %}

[Add the Lambda layer](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) of Datadog Lambda Extension to your Lambda functions, using the ARN format based on your AWS region and architecture:

```sh
# Use this format for x86-based Lambda deployed in AWS commercial regions
arn:aws:lambda:<AWS_REGION>:464622532012:layer:Datadog-Extension:94

# Use this format for arm64-based Lambda deployed in AWS commercial regions
arn:aws:lambda:<AWS_REGION>:464622532012:layer:Datadog-Extension-ARM:94

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

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

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

### Configure the required environment variables{% #configure-the-required-environment-variables %}

- Set `DD_SITE` to  (ensure the correct SITE is selected on the right).
- Set `DD_API_KEY_SECRET_ARN` to the ARN of the AWS secret where your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys) 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.

{% /tab %}

**Do not set** the following environment variables in your serverless environment. They should only be set in non-serverless environments.

- `DD_AGENT_HOST`
- `DD_TRACE_AGENT_URL`

### Install the Datadog Lambda library{% #install-the-datadog-lambda-library %}

```
go get github.com/DataDog/dd-trace-go/contrib/aws/datadog-lambda-go/v2
```

### Update your Lambda function code{% #update-your-lambda-function-code %}

```go
package main

import (
	"context"
	"net/http"
	"time"

  ddlambda "github.com/DataDog/dd-trace-go/contrib/aws/datadog-lambda-go/v2"
  "github.com/aws/aws-lambda-go/events"
  "github.com/aws/aws-lambda-go/lambda"
  httptrace "github.com/DataDog/dd-trace-go/contrib/net/http/v2"
  "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"
)

func main() {
	// Wrap your lambda handler
	lambda.Start(ddlambda.WrapFunction(myHandler, nil))
}

func myHandler(ctx context.Context, _ events.APIGatewayProxyRequest) (string, error) {
	// Trace an HTTP request
	req, _ := http.NewRequestWithContext(ctx, "GET", "https://www.datadoghq.com", nil)
	client := http.Client{}
	client = httptrace.WrapClient(&client)
	client.Do(req)

	// Submit a custom metric
	ddlambda.Metric(
		"coffee_house.order_value",      // Metric name
		12.45,                           // Metric value
		"product:latte", "order:online", // Associated tags
	)

	// Create a custom span
	s, _ := tracer.StartSpanFromContext(ctx, "child.span")
	time.Sleep(100 * time.Millisecond)
	s.Finish()
	return "ok", nil
}
```

## FIPS compliance{% #fips-compliance %}

Datadog provides FIPS-compliant monitoring for AWS Lambda functions. For AWS GovCloud environments, the `DD_LAMBDA_FIPS_MODE` environment variable is enabled by default. When FIPS mode is enabled, AWS FIPS endpoints are used for Datadog API key lookups, and the Lambda metric helper function `lambda_metric` requires the FIPS-compliant extension for metric submission. While the FIPS-compliant Lambda components work with any Datadog site, end-to-end FIPS compliance requires using the US1-FED site. See [AWS Lambda FIPS Compliance](https://docs.datadoghq.com/serverless/aws_lambda/fips-compliance) for more details.

## AWS Lambda and VPC{% #aws-lambda-and-vpc %}

If your Lambda functions are deployed in a Virtual Private Cloud (VPC) without access to the public internet, and you are using the `datadoghq.com` [Datadog site](https://docs.datadoghq.com/getting_started/site/), you can [use AWS PrivateLink](https://docs.datadoghq.com/agent/guide/private-link/) to send data.

If your Lambda functions are deployed in a VPC, and you are using a [Datadog site](https://docs.datadoghq.com/getting_started/site/) that is **not** `datadoghq.com`, you can [use a proxy](https://docs.datadoghq.com/agent/configuration/proxy/) to send data.

## What's next?{% #whats-next %}

- Add custom tags to your telemetry by using the `DD_TAGS` environment variable
- Configure [payload collection](https://docs.datadoghq.com/serverless/aws_lambda/configuration?tab=datadogcli#collect-the-request-and-response-payloads) to capture your functions' JSON request and response payloads
- If you are using the Datadog Lambda Extension, turn off the Datadog Forwarder's Lambda logs
- See [Configure Serverless Monitoring for AWS Lambda](https://docs.datadoghq.com/serverless/configuration/) for further capabilities

## Further Reading{% #further-reading %}

- [Configure Serverless Monitoring](https://docs.datadoghq.com/serverless/configuration)
- [Troubleshoot Serverless Monitoring](https://docs.datadoghq.com/serverless/guide/troubleshoot_serverless_monitoring)
- [Submitting Custom Metrics from Serverless Applications](https://docs.datadoghq.com/serverless/custom_metrics/)
