Overview
If you use OpenTelemetry, AWS manages an official OpenTelemetry Lambda layer called AWS Distro for OpenTelemetry (ADOT) Lambda, which lets you use OpenTelemetry in your Lambda functions and export data asynchronously from those functions.Using Legacy ADOT Lambda Layers for HoneycombThis guide uses the legacy ADOT Lambda layers that include an embedded OpenTelemetry Collector. AWS now offers newer optimized layers without a collector, but these are designed to export only to AWS CloudWatch and X-Ray.To send telemetry to Honeycomb (a non-AWS endpoint), you need the legacy layers with the embedded collector. AWS acknowledges this use case, stating: “Unless you want to export the telemetry data to a non CloudWatch endpoint, the approach below is not recommended.”
Languages
AWS maintains pre-configured Lambda layers that provide automatic instrumentation and do not require you to modify code. These exist for several languages, including:- Java
- Python
- JavaScript
- .NET
- Go
Before You Begin
Before you begin, you’ll need:- an AWS account with permissions to:
- Create AWS Lambda functions
- Access AWS X-Ray
- Create AWS Identity and Access Management (IAM) policies
- a Honeycomb Ingest API Key
Create a Lambda Function in AWS Lambda
Begin by creating a Lambda function, which is a serverless compute service that lets you run code in response to events without managing servers.- In the AWS Management Console, navigate to the Lambda console, and select Functions from the nav.
- Select Create function.
- Choose Author from Scratch as the method of creating your function.
-
Locate the Basic Information section, and enter details for your Lambda function:
Field Description Function name Name that describes the purpose of your function. Runtime Language to use to write your function. Architecture Instruction set architecture you want for your function code. We recommend that you choose x86-64. - Locate the Permissions section, and expand it.
- For Execution role, select Create a new role with basic Lambda permissions.
- Select Create function
-
In the Lambda code editor window that opens, enter your Lambda function. For example, for JavaScript:
-
Press [
Ctrl] + [s] on your keyboard to save your file. - Select Deploy.
Add the AWS Distro for OpenTelemetry Lambda Layer
If you are using .NET or Go, you must instrument your code before you complete this step.
Refer to AWS instructions on .NET instrumentation or Go instrumentation.If you are using Java, JavaScript, and Python, your code will be instrumented in a later step.
- Locate the Layers section, and select Add a layer.
- In the Add layer window, locate Layer source, and select Specify an ARN.
- Locate the Specify an ARN section, and copy and paste the example ARN from the AWS legacy layer documentation for your language:
-
Modify your ARN:
- Replace the
<architecture>placeholder in your ARN with the appropriate value. For x86-based processors, useamd64. - Replace the
<region>placeholder in your ARN with the appropriate value from the supported region values listed in the AWS documentation linked in the previous step. Lambda layers can be used only in the region in which they are published, so make sure to use the layer in the same region as your Lambda function.
- Replace the
- Select Add.
Disable Active Tracing
We recommend disabling the Active Tracing setting for AWS X-Ray because:- If you are visualizing your data with Honeycomb, then exporting data to AWS X-Ray is unnecessary.
- Active Tracing adds extra spans, which cannot be exported outside of AWS, to traces by default.
- Disabling Active Tracing provides some data savings and avoids conflicts with other tracing instrumentation you may have.
- In the Configuration tab, select Monitoring and operations tools, and then select Edit.
- Locate the AWS X-Ray section, and toggle off Active tracing.
- Select Save.
Configure OpenTelemetry Packages
If you are using .NET or Go, skip this step and proceed to Customize the ADOT Collector to Send Telemetry Data to Honeycomb.
AWS_LAMBDA_EXEC_WRAPPER environment variable.
The environment variable points to a script that performs the configuration directly in each layer, so you can avoid modifying code.
- Java
- Python
- JavaScript
- In the Configuration tab of the Lambda console, select Environment variables, and then select Edit.
-
For Key, enter
AWS_LAMBDA_EXEC_WRAPPER.AWS_LAMBDA_EXEC_WRAPPERis a reserved environment variable AWS Lambda uses to identify a custom wrapper script to run before your function’s main handler. -
For Value, enter
/opt/otel-handler. This script will invoke your Lambda application with the automatic instrumentation applied. For Java, you can instrument using either the Java SDK or the Java Auto-Instrumentation Agent. When using the Java SDK, scripts for several other handler types exist. - Select Add environment variable.
Customize the ADOT Collector to Send Telemetry Data to Honeycomb
To send your telemetry data to Honeycomb, you must customize the embedded ADOT Collector configuration in the legacy Lambda layer. The ADOT Lambda Layers support a variety of confmap providers, which are types of OpenTelemetry Collector components responsible for fetching configuration from a URI. In this example, we use afile confmap provider.
-
In the Code tab of the Lambda console, add a new file named
otel-collector-config.yamlalongside your Lambda function (index.js). -
Enter the following code, which configures the Collector to send traces to Honeycomb:
To explore additional Collector configurations customized for Honeycomb, visit Send Data with the OpenTelemetry Collector.Remember to replace the
YOUR_HONEYCOMB_INGEST_API_KEYplaceholder with your Honeycomb Ingest API Key. -
Press [
Ctrl] + [s] on your keyboard to save your file. - Select Deploy.
Configure the ADOT Collector to Find Your Custom Configuration
After you have customized your Collector configuration file, you must tell the embedded ADOT Collector where to find your custom configuration using the reservedOPENTELEMETRY_COLLECTOR_CONFIG_FILE environment variable.
- In the Configuration tab, select Environment variables, and then select Edit.
-
For Key, enter
OPENTELEMETRY_COLLECTOR_CONFIG_FILE.OPENTELEMETRY_COLLECTOR_CONFIG_FILEis a reserved environment variable AWS Lambda uses to identify a custom configuration file for the OpenTelemetry Collector. -
For Value, enter
/var/task/otel-collector-config.yaml. - Select Add environment variable.
Instrument Your Lambda Function
If you are using .NET or Go, skip this step.
You should have already added instrumentation to your code (before adding the AWS Distro for OpenTelemetry Lambda Layer).
- Java
- Python
- JavaScript
https.get.
-
Import the
httpslibrary and configure it to use Honeycomb. For this JavaScript example, add the following code in a location above theexports.lambdaHandlerline in the Lambda function you created in the first step of this guide: -
Instruct the library to return data.
Add the following code in a location directly above the
return responseline in the Lambda function you created in the first step of this guide:The full code should look similar to: -
Press [
Ctrl] + [s] on your keyboard to save. - Select Deploy.
Test Your Implementation
It’s time to test your implementation and see data in Honeycomb!- In the Code tab, select Test.
- Open Honeycomb and look for a Dataset with the same name as the Lambda function you created in the first step of this guide.
Creating a Function URL
To test your Lambda function more easily, you can use a function URL, which is a dedicated HTTP(S) endpoint that you can enable for your Lambda function. You can use the function URL to automate testing. To create a function URL:- In the Lambda console, select Functions from the nav.
- Locate and select the name of the function for which you you want to create a function URL.
- Select the Configuration tab, and then select Function URL.
- Select Create function URL.
- For Auth type, choose AWS_IAM or NONE, depending on who you would like to have access to your function URL.
- Select Save.
Propagating Trace Context
Trace context plays a critical role in linking together individual services into a cohesive trace. In AWS Lambda, ensuring that trace context is correctly passed across multiple Lambda functions is essential for accurate, end-to-end tracing.Disabling AWS Context Propagation
By default, AWS Lambda automatically propagates trace context between services. If you need to disable automatic context propagation, you can use either an environment variable or a configuration file.Disabling Context Propagation Using an Environment Variable
Set theOTEL_LAMBDA_DISABLE_CONTEXT_PROPAGATION reserved environment variable to true:
Disabling Context Propagation Using a Configuration File
Using a configuration file gives you more control over how trace context is managed in your Lambda functions. To disable context propagation using a configuration file:-
Create a configuration file (in this example, named
lambda-config.js), and add the following code: -
Include this configuration file when starting your Lambda function, either as part of the start command or when using the
NODE_OPTIONSreserved environment variable:
Propagating Context Using Lambda Event Arguments
When invoking a Lambda function outside of an HTTP context, the trace context may not be included automatically. In these cases, you can use Lambda event arguments to propagate the context manually. For example, in Node.js:Troubleshooting
If you need to troubleshoot, explore these solutions to common issues.Missing root spans in traces
If you are using AWS Lambda with API Gateway (or another service that governs traffic), missing root spans for your traces in Honeycomb are likely. This is because API Gateway often generates the initial request but may not propagate tracing headers correctly to your Lambda function. Some solutions you can try to ensure your traces include root spans include:- Disable Active Tracing on your Lambda function (in the AWS Console under Configuration > Monitoring).
-
To ensure consistent trace context, add the
OTEL_PROPAGATORSreserved environment variable to your Lambda function (in the AWS Console under Configuration > Environment variables) and set its value totracecontext. -
If you call your Lambda function directly from code, make sure the
traceparentheader is present. With thetraceparentheader, OpenTelemetry can recognize the request as part of a larger trace and will create a root span. If thetraceparentheader is missing, add a code block to wrap your entrypoint function in a span. For example, in JavaScript: - Ensure your OpenTelemetry Collector is correctly configured to send data to Honeycomb.
-
Make sure you have selected an appropriate
service.name. By default, the AWS Lambda layer setsservice.nameto the Lambda function’s name. Because Honeycomb creates a dataset for eachservice.name, the default AWS Lambda behavior can cause traces from related Lambda functions to be split across different datasets. To keep datasets together, override the defaultservice.nameby explicitly setting theOTEL_SERVICE_NAMEreserved environment variable for each Lambda function.
Missing non-root spans in traces
Although the AWS Lambda Setup documentation includes a step that enables Active Tracing, we recommend disabling Active Tracing. When Active Tracing is enabled, Lambda uses a ParentBased sampler with a sample rate of 5%. The AWS Propagator code always creates a new context, which can cause some spans to be dropped when using a ParentBased sampler. With this sampler, if spans are dropped andDEBUG mode is enabled, you might see the following error in the logs:
OTEL_TRACES_SAMPLER reserved environment variable to always_on:
Lambda layer not instrumenting code
Ensure that you have created theAWS_LAMBDA_EXEC_WRAPPER reserved environment variable, which is essential for initializing OpenTelemetry instrumentation, and have set it to use the OpenTelemetry handler: