---
title: Instrumenting Go Serverless Applications Using the Datadog Forwarder
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Serverless > Serverless Monitoring Guides > Instrumenting Go Serverless
  Applications Using the Datadog Forwarder
---

# Instrumenting Go Serverless Applications Using the Datadog Forwarder

## Overview{% #overview %}

{% alert level="danger" %}
If you are a new user of Datadog Serverless, follow the [instructions to instrument your Lambda functions using the Datadog Lambda Extension](https://docs.datadoghq.com/serverless/installation/go.md) instead. If you have setup Datadog Serverless with the Datadog Forwarder before Lambda offered out-of-the-box functionality, use this guide to maintain your instance.
{% /alert %}

## Required setup{% #required-setup %}

If not already configured:

- Install the [AWS integration](https://docs.datadoghq.com/integrations/amazon_web_services.md). This allows Datadog to ingest Lambda metrics from AWS.
- Install the [Datadog Forwarder Lambda function](https://docs.datadoghq.com/serverless/forwarder.md), which is required to ingest AWS Lambda traces, enhanced metrics, custom metrics, and logs.

After you have installed the [AWS integration](https://docs.datadoghq.com/integrations/amazon_web_services.md) and the [Datadog Forwarder](https://docs.datadoghq.com/serverless/forwarder.md), follow these steps to instrument your application to send metrics, logs, and traces to Datadog.

## Configuration{% #configuration %}

### Install{% #install %}

Install the [Datadog Lambda library](https://github.com/DataDog/datadog-lambda-go) locally by running the following command:

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

### Instrument{% #instrument %}

Follow these steps to instrument the function:

1. Set environment variable `DD_FLUSH_TO_LOG` and `DD_TRACE_ENABLED` to `true`.
1. Import the required packages in the file declaring your Lambda function handler. **Note**: This documentation uses v2 of the Go tracer, which Datadog recommends for all users. If you are using v1, see the [migration guide](https://docs.datadoghq.com/tracing/trace_collection/custom_instrumentation/go/migration.md) to upgrade to v2.

````
```go
package main

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

Wrap your Lambda function handler using the wrapper provided by the Datadog Lambda library.

```go
func main() {
  // Wrap your lambda handler like this
  lambda.Start(ddlambda.WrapHandler(myHandler, nil))
  /* OR with manual configuration options
  lambda.Start(ddlambda.WrapHandler(myHandler, &ddlambda.Config{
    BatchInterval: time.Second * 15
    APIKey: "my-api-key",
  }))
  */
}
```

Use the included libraries to create additional spans, connect logs and traces, and pass trace context to other services.

```go
func myHandler(ctx context.Context, event MyEvent) (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)

  // Connect your Lambda logs and traces
  currentSpan, _ := tracer.SpanFromContext(ctx)
  log.Printf("my log message %v", currentSpan)

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

### Subscribe{% #subscribe %}

Subscribe the Datadog Forwarder Lambda function to each of your function's log groups, in order to send metrics, traces, and logs to Datadog.

1. [Install the Datadog Forwarder if you haven't](https://docs.datadoghq.com/serverless/forwarder.md).
1. [Subscribe the Datadog Forwarder to your function's log groups](https://docs.datadoghq.com/logs/guide/send-aws-services-logs-with-the-datadog-lambda-function.md#collecting-logs-from-cloudwatch-log-group).

### Tag{% #tag %}

Although it's optional, Datadog recommends tagging your serverless applications with the `env`, `service`, and `version` tags for [unified service tagging](https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging.md#aws-lambda-functions).

## Explore{% #explore %}

After configuring your function following the steps above, view your metrics, logs, and traces on the [Serverless homepage](https://app.datadoghq.com/functions).

## Monitor custom business logic{% #monitor-custom-business-logic %}

If you would like to submit a custom metric, see the sample code below:

```go
package main

import (
  "github.com/aws/aws-lambda-go/lambda"
  ddlambda "github.com/DataDog/dd-trace-go/contrib/aws/datadog-lambda-go/v2"
)

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

func myHandler(ctx context.Context, event MyEvent) (string, error) {
  // Submit a custom metric
  ddlambda.Metric(
    "coffee_house.order_value", // Metric name
    12.45, // Metric value
    "product:latte", "order:online", // Associated tags
  )

  // Submit a custom metric with timestamp
  ddlambda.MetricWithTimestamp(
    "coffee_house.order_value", // Metric name
    12.45, // Metric value
    time.Now(), // Timestamp, must be within last 20 mins
    "product:latte", "order:online" // Associated tags
  )
  
  req, err := http.NewRequest("GET", "http://example.com/status")

  // Add the datadog distributed tracing headers
  ddlambda.AddTraceHeaders(ctx, req)

  client := http.Client{}
  client.Do(req)
}
```

Learn more about [custom metric submission](https://docs.datadoghq.com/serverless/custom_metrics.md?tab=go).

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

