Monitoring AWS Lambda Logs with ClickStack using Rotel

Look for these key attributes in the logs:

- `service.name`: Your Lambda function name
- `faas.name`: AWS Lambda function name
- `faas.invocation_id`: Unique invocation ID
- `cloud.provider`: "aws"
- `cloud.platform`: "aws\_lambda"

## Disabling CloudWatch Logs (cost optimization)[​](#disable-cloudwatch "Direct link to Disabling CloudWatch Logs (cost optimization)")

By default, AWS Lambda sends all logs to CloudWatch Logs, which can be expensive at scale. Once you've verified that logs are flowing to ClickStack, you can disable CloudWatch logging to reduce costs.

Remove CloudWatch permissions from the execution role

#### Remove CloudWatch permissions from the execution role[​](#remove-permissions "Direct link to Remove CloudWatch permissions from the execution role")

1. Open the AWS Console and navigate to **AWS Lambda**
2. Navigate to your Lambda function
3. Select **Configuration** → **Permissions**
4. Click the execution role name to open the IAM console
5. Edit the role and remove any `logs:*` actions:
   - If using a custom policy, edit to remove `logs:CreateLogGroup`, `logs:CreateLogStream`, and `logs:PutLogEvents`
   - If using the AWS managed policy `AWSLambdaBasicExecutionRole`, remove it from the role
6. Save the role

Verify CloudWatch logging is disabled

#### Verify CloudWatch logging is disabled[​](#verify-disabled "Direct link to Verify CloudWatch logging is disabled")

Invoke your function again and verify that:

1. No new CloudWatch log streams are created
2. Logs continue to appear in ClickStack/HyperDX

```
# This should show no new log streams after the policy change
aws logs describe-log-streams \
  --log-group-name /aws/lambda/my-function \
  --order-by LastEventTime \
  --descending \
  --max-items 5
```

## Adding OpenTelemetry auto-instrumentation[​](#auto-instrumentation "Direct link to Adding OpenTelemetry auto-instrumentation")

The Rotel Lambda Extension works seamlessly with OpenTelemetry auto-instrumentation layers to collect distributed traces and metrics in addition to logs.

Choose your language instrumentation layer

#### Choose your language instrumentation layer[​](#choose-instrumentation "Direct link to Choose your language instrumentation layer")

AWS provides OpenTelemetry auto-instrumentation layers for multiple languages:

|  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Language Layer ARN Pattern|  |  |  |  |  |  | | --- | --- | --- | --- | --- | --- | | Node.js `arn:aws:lambda:{region}:901920570463:layer:aws-otel-nodejs-{arch}-ver-{version}`| Python `arn:aws:lambda:{region}:901920570463:layer:aws-otel-python-{arch}-ver-{version}`| Java `arn:aws:lambda:{region}:901920570463:layer:aws-otel-java-agent-{arch}-ver-{version}` | | | | | | | |

Find the latest versions in the [AWS OpenTelemetry Lambda repository](https://github.com/aws-observability/aws-otel-lambda).

Add both layers to your function

#### Add both layers to your function[​](#add-both-layers "Direct link to Add both layers to your function")

Add **both** the Rotel extension layer and the instrumentation layer:

```
aws lambda update-function-configuration \
  --function-name my-function \
  --layers \
    arn:aws:lambda:{region}:418653438961:layer:rotel-extension-{arch}:{version} \
    arn:aws:lambda:{region}:901920570463:layer:aws-otel-nodejs-{arch}-ver-1-30-2:1
```

Configure the auto-instrumentation

#### Configure the auto-instrumentation[​](#configure-instrumentation "Direct link to Configure the auto-instrumentation")

Set the `AWS_LAMBDA_EXEC_WRAPPER` environment variable to enable auto-instrumentation:

**For Node.js:**

```
AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-handler
```

**For Python:**

```
AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument
```

**For Java:**

```
AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-handler
```

Verify traces in HyperDX

#### Verify traces in HyperDX[​](#verify-traces "Direct link to Verify traces in HyperDX")

After invoking your function:

1. Navigate to the **Traces** view in HyperDX
2. You should see traces with spans from your Lambda function
3. Traces will be correlated with logs via `trace_id` and `span_id` attributes

## Example applications[​](#examples "Direct link to Example applications")

Checkout the example Python app demonstrating the Rotel Lambda Extension:

- **[Python + ClickHouse](https://github.com/streamfold/python-aws-lambda-clickhouse-example)**: Python application with manual OpenTelemetry instrumentation, sending traces and logs directly to ClickHouse

## Join the Rotel community[​](#join-rotel-community "Direct link to Join the Rotel community")

If you have questions about Rotel, please join the [Rotel Discord server](https://rotel.dev) and share your feedback or questions. Check out the [Rotel Lambda Extension](https://github.com/streamfold/rotel-lambda-extension) to contribute any improvements.

## Additional resources[​](#resources "Direct link to Additional resources")

- **[Rotel Lambda Extension](https://github.com/streamfold/rotel-lambda-extension)**: Source code and detailed documentation
- **[Rotel Core](https://github.com/streamfold/rotel)**: The lightweight OTEL data plane powering the extension

- [Integration with existing Lambda functions](#existing-lambda)
  - [Prerequisites](#prerequisites)- [Disabling CloudWatch Logs (cost optimization)](#disable-cloudwatch)- [Adding OpenTelemetry auto-instrumentation](#auto-instrumentation)- [Example applications](#examples)- [Join the Rotel community](#join-rotel-community)- [Additional resources](#resources)

Was this page helpful?