> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trace0hq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Java — AWS Lambda

> Instrument a Java Lambda function with OpenTelemetry and send traces, metrics, and logs to Trace0.

## Introduction

For Java applications running on AWS Lambda, OpenTelemetry provides two instrumentation options:

1. **Java Agent layer**
2. **Wrapper layer**

See the [OpenTelemetry Lambda Java documentation](https://github.com/open-telemetry/opentelemetry-lambda/blob/main/java/README.md) for details on each layer and guidance on choosing between them.

The rest of this guide covers instrumentation using the `Java Agent` layer.

## 1. Add the OpenTelemetry Lambda Layer

Find the latest `layer-javaagent` ARN for your AWS region from the [opentelemetry-lambda releases page](https://github.com/open-telemetry/opentelemetry-lambda/releases). Add the **JavaAgent** layer ARN to your function.

## 2. Add the Collector Lambda Extension

Find the latest `layer-collector` ARN for your AWS region from the [opentelemetry-lambda releases page](https://github.com/open-telemetry/opentelemetry-lambda/releases).

Add the layer ARN to your function and then add the following `collector.yaml` file to the root of your Lambda deployment folder. Replace `YOUR_TRACE0_ENV_API_KEY` with the API key from your Trace0 environment.

```yaml theme={null}
receivers:
  telemetryapi:

  otlp:
    protocols:
      grpc:
      http:

exporters:
  otlp_http/trace0:
    endpoint: https://app.trace0hq.com/api
    headers:
      X-API-KEY: 'YOUR_TRACE0_ENV_API_KEY'

processors:
  batch:

  decouple:

  resource:
    attributes:
      - key: service.name
        value: "${env:OTEL_SERVICE_NAME}"
        action: upsert

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [resource, batch, decouple]
      exporters: [otlp_http/trace0]

    metrics:
      receivers: [otlp]
      processors: [resource, batch, decouple]
      exporters: [otlp_http/trace0]

    logs:
      receivers: [otlp, telemetryapi]
      processors: [resource, batch, decouple]
      exporters: [otlp_http/trace0]
```

## 3. Set Environment Variables

Add the following environment variables to your Lambda function.

| Variable | Value |
| - | - |
| `OPENTELEMETRY_COLLECTOR_CONFIG_URI` | `/var/task/collector.yaml` |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `http://localhost:4318` |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | `http/protobuf` |
| `OTEL_SERVICE_NAME` | `YOUR_SERVICE_NAME` |
| `OTEL_RESOURCE_PROVIDERS_AWS_ENABLED` | `true` |
| `AWS_LAMBDA_EXEC_WRAPPER` | `/opt/otel-handler` |

## 4. Set HTTP request spans

For lambdas triggered via API Gateway, the HTTP request and response attributes are not set automatically on the lambda invocation span by the OTel Lambda auto-instrumentation. Therefore, they need to be set manually in your lambda code handler.

First, add the `opentelemetry-api` dependency to your project:

<Tabs>
  <Tab title="Gradle">
    ```kotlin theme={null}
    dependencies {
        implementation("io.opentelemetry:opentelemetry-api:1.61.0")
    }
    ```
  </Tab>

  <Tab title="Maven">
    ```xml theme={null}
    <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-api</artifactId>
      <version>1.61.0</version>
      <scope>runtime</scope>
    </dependency>
    ```
  </Tab>
</Tabs>

Then add the HTTP request and response attributes to the Lambda invocation span in your handler:

```java theme={null}
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;

public class Handler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {

    @Override
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
        String httpMethod = event.getHttpMethod();
        String path = event.getPath();

        // Set the http request method and route on the parent span.
        Span span = Span.current();
        span.setAttribute("http.request.method", httpMethod);
        span.setAttribute("http.route", path);

        APIGatewayProxyResponseEvent result = processRequest(event)

        // Set the HTTP response code and mark the span as failed for 4xx/5xx responses.
        span.setAttribute("http.response.status_code", result.getStatusCode());
        span.setStatus(result.getStatusCode() < 400 ? StatusCode.OK : StatusCode.ERROR);
        
        return result;
    }
}
```

## 4. Deploy service

Deploy your service and watch traces, metrics, and logs appear in the [Trace0 dashboard](https://app.trace0hq.com) within seconds.

## Example service

See our [Java Lambda example app](https://github.com/Trace0-HQ/trace0-examples/tree/main/java-lambda) for a working service you can deploy to your AWS account.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.