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

# Instrumenting Java 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/java) 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 %}

{% alert level="warning" %}
Some older versions of `datadog-lambda-java` import `log4j <=2.14.0` as a transitive dependency. Upgrade instructions are below.
{% /alert %}

## Prerequisites{% #prerequisites %}

The [Datadog Forwarder Lambda function](https://docs.datadoghq.com/serverless/forwarder/) is required to ingest AWS Lambda traces, enhanced metrics, custom metrics, and logs.

To fully instrument your serverless application with distributed tracing, your Java Lambda functions must be using the Java 8 Corretto (`java8.al2`), Java 11 (`java11`) or Java 17 (`java17`) runtime.

## Configuration{% #configuration %}

### Install{% #install %}

Install the Datadog Lambda Library locally by adding one of the following code blocks into `pom.xml` (Maven) or `build.gradle` (Gradle). Replace `VERSION` below with the latest release (omitting the preceding `v`): 

{% tab title="Maven" %}
Include the following dependency in your `pom.xml`:

```xml
<dependency>
  <groupId>com.datadoghq</groupId>
  <artifactId>datadog-lambda-java</artifactId>
  <version>VERSION</version>
</dependency>
```

{% /tab %}

{% tab title="Gradle" %}
Include the following in your `build.gradle`:

```groovy
dependencies {
  implementation 'com.datadoghq:datadog-lambda-java:VERSION'
}
```

{% /tab %}



### Instrument{% #instrument %}

1. Install the Datadog Lambda Layer on your function. The latest `VERSION` is `26`.

   ```yaml
   arn:aws:lambda:<AWS_REGION>:464622532012:layer:dd-trace-java:<VERSION>
   ```

1. Configure the following environment variables on your function:

   ```yaml
   JAVA_TOOL_OPTIONS: -javaagent:"/opt/java/lib/dd-java-agent.jar" -XX:+TieredCompilation -XX:TieredStopAtLevel=1
   DD_LOGS_INJECTION: true # default value
   DD_JMXFETCH_ENABLED: false
   DD_TRACE_ENABLED: true # default value
   ```

1. Wrap your Lambda handler function using the wrapper provided by the Datadog Lambda Library:

   ```java
   public class Handler implements RequestHandler<APIGatewayV2ProxyRequestEvent, APIGatewayV2ProxyResponseEvent> {
       public Integer handleRequest(APIGatewayV2ProxyRequestEvent request, Context context){
           DDLambda ddl = new DDLambda(request, context); //Required to initialize the trace
   
           do_some_stuff();
           make_some_http_requests();
   
           ddl.finish(); //Required to finish the active span.
           return new ApiGatewayResponse();
       }
   }
   ```

### Subscribe{% #subscribe %}

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

1. [Install the Datadog Forwarder if you haven't](https://docs.datadoghq.com/serverless/forwarder/).
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/#collecting-logs-from-cloudwatch-log-group).

### Monitor Java Lambda function cold starts{% #monitor-java-lambda-function-cold-starts %}

Cold starts occur when your serverless applications receive sudden increases in traffic, including when the function was previously inactive or when it was receiving a relatively constant number of requests. Users may perceive cold starts as slow response times or lag. Datadog recommends you configure a monitor on Java Lambda function cold starts, and use Datadog Serverless Insights to [keep cold starts to a minimum](https://docs.datadoghq.com/serverless/insights#cold-starts).

{% image
   source="https://datadog-docs.imgix.net/images/serverless/java-monitor-cold-starts.55cf3b646a7598da49c7393913310154.png?auto=format"
   alt="Monitor Java Lambda Function Cold Starts" /%}

To create a Datadog monitor on Java Lambda function cold starts, follow the [monitor creation steps](https://docs.datadoghq.com/monitors/types/metric/?tab=threshold#overview) with the following criteria:

- Metric Name: `aws.lambda.enhanced.invocations`
- From: `runtime:java*` and `cold_start:true`
- Alert Grouping: Multi Alert, trigger a separate alert for each `function_arn`

### Tag{% #tag %}

Although it is optional, Datadog recommends tagging your serverless applications with the reserved tags `env`, `service`, and `version`. For more information about reserved tags, see the [Unified Service Tagging documentation](https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging/#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 %}

To submit a custom metric, see the sample code below:

```java
public class Handler implements RequestHandler<APIGatewayV2ProxyRequestEvent, APIGatewayV2ProxyResponseEvent> {
    public Integer handleRequest(APIGatewayV2ProxyRequestEvent request, Context context){
        DDLambda ddl = new DDLambda(request, context);

        Map<String,Object> myTags = new HashMap<String, Object>();
            myTags.put("product", "latte");
            myTags.put("order","online");

        // Submit a custom metric
        ddl.metric(
            "coffee_house.order_value", // Metric name
            12.45,                      // Metric value
            myTags);                    // Associated tags

        URL url = new URL("https://example.com");
        HttpURLConnection hc = (HttpURLConnection)url.openConnection();
        hc.connect();

        ddl.finish();
    }
}
```

See the [custom metrics documentation](https://docs.datadoghq.com/serverless/custom_metrics?tab=java) for more information on custom metric submission.

### Connect logs and traces{% #connect-logs-and-traces %}

To automatically connect Java Lambda function logs and traces, see [Connecting Java Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/java/) for instructions.

{% alert level="info" %}
Failing to use the correct Java runtime can result in errors, for example: `Error opening zip file or JAR manifest missing : /opt/java/lib/dd-java-agent.jar`. Make sure to use `java8.al2` or `java11` as your runtime, as described above.
{% /alert %}

## Upgrading{% #upgrading %}

The Apache Foundation has announced that log4j, a popular Java logging library, is [vulnerable to remote code execution](https://www.datadoghq.com/log4j-vulnerability/). Some versions of `datadog-lambda-java` include a transitive dependency on log4j that may be vulnerable. The vulnerable versions are:

- `<=0.3.3`
- `1.4.0`

The latest version of `datadog-lambda-java` is . Use this version (omitting the preceding `v`) when following the upgrading instructions below.

If you do not wish to upgrade to `1.4.x`, `0.3.x` is updated with the latest log4j security patches as well. You may find the latest version of `0.3.x` in the [`datadog-lambda-java` repository](https://github.com/DataDog/datadog-lambda-java/releases).

The version of the `datadog-lambda-java` dependency in your Lambda function is set in `pom.xml` (Maven) or `build.gradle` (Gradle).

{% tab title="Maven" %}
Your `pom.xml` file contains a section similar to the following:

```xml
<dependency>
  <groupId>com.datadoghq</groupId>
  <artifactId>datadog-lambda-java</artifactId>
  <version>VERSION</version>
</dependency>
```

Replace `VERSION` with the latest version of `datadog-lambda-java` (available above). Then redeploy your Lambda function.
{% /tab %}

{% tab title="Gradle" %}
Your `build.gradle` file contains a section similar to the following:

```groovy
dependencies {
  implementation 'com.datadoghq:datadog-lambda-java:VERSION'
}
```

Replace `VERSION` with the latest version of `datadog-lambda-java` (available above). Then redeploy your Lambda function.
{% /tab %}

If you are upgrading from 0.3.x to 1.4.x and you wish to use the `dd-trace-java` tracer, find the reference to the `dd-trace-java` Lambda layer and change it to:

```
arn:aws:lambda:<AWS_REGION>:464622532012:layer:dd-trace-java:4
```
