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

# Python — AWS Lambda

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

<Note>
  You only need to add the **Python Lambda layer** — no separate collector layer is required. Trace0 handles ingestion directly.
</Note>

## 1. Add the OpenTelemetry Lambda Layer

Find the latest `layer-python` 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.

## 2. Set Environment Variables

| Variable                      | Value                               |
| ----------------------------- | ----------------------------------- |
| `AWS_LAMBDA_EXEC_WRAPPER`     | `/opt/otel-handler`                 |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `https://app.trace0hq.com/api`      |
| `OTEL_EXPORTER_OTLP_HEADERS`  | `X-API-KEY=YOUR_TRACE0_ENV_API_KEY` |

## 3. 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.

```python theme={null}
from opentelemetry import trace
from opentelemetry.trace import StatusCode

def handler(event, context):
  http_method = event.get('httpMethod', '')
  path = event.get('path', '')

  # Set the http request method and route on the parent span.
  span = trace.get_current_span()
  span.set_attributes({
      'http.request.method': http_method,
      'http.route': path,
  })

  try:
      result = process_event(event)

      # Set the HTTP response code and mark the parent span as failed for 4xx/5xx responses.
      status_code = result['statusCode']
      span.set_attribute('http.response.status_code', status_code)
      span.set_status(StatusCode.OK if status_code < 400 else StatusCode.ERROR)

      return result

  except Exception as e:
      # Set the exception, HTTP error code and status on the parent span.
      span.record_exception(e)
      span.set_attribute('http.response.status_code', 500)
      span.set_status(StatusCode.ERROR)
      return {
          'statusCode': 500,
          'headers': {'Content-Type': 'application/json'},
          'body': json.dumps({'error': 'Internal server error'}),
      }
```

## 4. Add Trace0 logger

The OpenTelemetry Lambda Layer does not include the `opentelemetry-instrumentation-logging` library. Adding it as a dependency pulls in `opentelemetry-sdk` and `opentelemetry-instrumentation` as transitive dependencies — both of which are already bundled in the layer — resulting in duplicate packages and potential version conflicts.

The [trace0-lambda-otel-logger](https://pypi.org/project/trace0-lambda-otel-logger) library solves this problem by installing a `logging.Handler` on the root logger that automatically injects the active OTel span's `traceId` and `spanId` into every log record, and exporting them directly to the Trace0 ingest endpoint. This enables full log-trace correlation, while only depending on `opentelemetry-api`, which is already present in the layer, making it safe to install alongside it.

First, install the library:

```bash theme={null}
pip install trace0-lambda-otel-logger
```

Then add the library as the first import in your Lambda handler module, and call `flush()` at the end of every invocation:

```python theme={null}
import trace0_lambda_otel_logger  # must be first
from trace0_lambda_otel_logger import flush

import logging

logger = logging.getLogger(__name__)

def handler(event, context):
    try:
        logger.info(f"Processing request with requestId: {context.aws_request_id}")
        return process_event(event, context)
    finally:
        flush()  # always flush before Lambda freezes
```

The library will now automatically capture all logging output, inject OTel trace context (traceId, spanId), and export the logs to the Trace0 ingest endpoint.

## 5. 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 [Python Lambda example app](https://github.com/Trace0-HQ/trace0-examples/tree/main/python-lambda) for a working service you can deploy to your AWS account.
