AWS Lambda Instrumentation | Honeycomb

We use cookies or similar technologies to personalize your online experience & tailor marketing to you. Many of our product features require cookies to function properly.

Read our privacy policy I accept cookies from this site

AWS Lambda Instrumentation

For serverless apps based on Lambda and similar platforms, observability can be challenging. With no server to log into, clunky logging interfaces, and short, event-driven process runtimes, making sense of what is going on is often difficult.

To help with this, an official AWS-managed OpenTelemetry Lambda Layer lets you use OpenTelemetry in your Lambda Functions and export data asynchronously from those functions.

If you are not using OpenTelemetry, Honeycomb also has an extension that can run as a Lambda Layer, or inside a container alongside your lambda function.

AWS Managed OpenTelemetry Lambda Layer 

The AWS-managed OpenTelemetry Lambda Layer works by embedding a stripped-down version of the OpenTelemetry (OTel) Collector inside an AWS Lambda Extension Layer. To use it in any language, configure an OTLP exporter to send to the OTel Collector in the Lambda Layer.

AWS maintains preconfigured Lambda Layers for several languages with automatic instrumentation:

  • Java
  • Python
  • Nodejs
  • .NET
  • Go

See AWS’s documentation on Getting Started with AWS Lambda Layers for more information.

If not using any of the above listed languages, or would prefer to manually build and configure a layer, refer to AWS’s documentation on Manual Steps for Private Lambda Layers.

Honeycomb Lambda Extension 

If not using OpenTelemetry, you can use the Honeycomb Lambda Extension. This extension is designed to run alongside your Lambda Function. It integrates with the Lambda Logs API and receives log messages from your lambda function, which are then sent to Honeycomb as events. Structured log messages sent to stdout or stderr from your lambda function will be sent to Honeycomb as events.

The extension can be run inside a container or added as a Lambda Layer.

Overview of Lambda Extension

How It Works 

AWS Lambda Extensions allow you to extend the functionality of Lambda functions through configuration as Lambda Layers or run inside a container image.

Extensions run alongside the Lambda Runtime and can read data environment variables from the environment.

Once the Honeycomb Lambda Extension is configured, any structured logs emitted to stdout or stderr by your Lambda function will be parsed by the extension and sent to a dataset that you specify in Honeycomb.

Note: Logs emitted in a Lambda invocation will be parsed during the following invocation, and any remaining logs will be parsed whenever the Lambda runtime shuts down. This means that you may experience some delay in seeing events arrive in Honeycomb, especially if your Lambda function receives low traffic.


There are two versions of the Honeycomb Lambda Extension available:

  • honeycomb-lambda-extension-x86_64 (for functions running on x86_64 architecture)
  • honeycomb-lambda-extension-arm64 (for functions running on arm64 architecture)

Installing as a Lambda Layer 

To start using the Honeycomb Lambda Extension, add the extension to your function as a Lambda Layer.

This Lambda Extension functionality is only available on certain Lambda runtimes.

arm64 is only supported in certain regions

The extension can be added as a Lambda Layer with the AWS CLI tool:
$ aws lambda update-function-configuration --function-name YourFunctionName \
    --layers "arn:aws:lambda:us-east-1:702835727665:layer:honeycomb-lambda-extension-x86_64:10"

You can also use infrastructure-as-code tools such as Terraform:

resource "aws_lambda_function" "extensions-demo-example-lambda" {
  function_name = "HoneycombExtensionExample"
  layers = ["arn:aws:lambda:us-east-1:702835727665:layer:honeycomb-lambda-extension-x86_64:10"]

Add the following environment variables to your Lambda function configuration:

  • LIBHONEY_DATASET - The Honeycomb dataset you would like events to be sent to.
  • LIBHONEY_API_KEY - Your Honeycomb API Key (also called Write Key).

As well as the following optional environment variable:

  • LIBHONEY_API_HOST - Mostly used for testing purposes, or to be compatible with proxies. Defaults to
  • LOGS_API_DISABLE_PLATFORM_MSGS - Optional. Set to “true” in order to disable “platform” messages from the logs API.
  • HONEYCOMB_DEBUG - Optional. Set to “true” to enable debug statements and troubleshoot issues. Enabling this will subscribe to Libhoney’s response queue and log the success or failure of sending events to Honeycomb.

Installing in a Container Image 

AWS Lambda functions can now be packaged and deployed as container images. This allows developers to leverage the flexibility and familiarity of container tooling, workflows and dependencies.

To run the Honeycomb Lambda Extension inside your container image, you must download the extension and place it in the /opt/extensions directory of your image.

FROM amazon/aws-lambda-ruby:2.7

ARG FUNCTION_DIR="/var/task"

RUN mkdir -p /opt/extensions
RUN yum install -y curl
RUN curl -L<ARCH> -o /opt/extensions/honeycomb-lambda-extension
RUN chmod +x /opt/extensions/honeycomb-lambda-extension

RUN mkdir -p ${FUNCTION_DIR}

CMD ["app.handler"]

Replace <ARCH> with the appropriate architecture (amd64 or arm64) based on your container image.

AWS Lambda provides a number of base images you can use. You can also use a custom base image, and adjust the examples accordingly.

Performance Implications 

The Honeycomb Lambda Extension runs independently of your Lambda Function and does not add to your Lambda Function’s execution time or add any additional latency. However, it does increase your Lambda Function’s size in proportion with the size of the Honeycomb Lambda Extension binary.


Below are some structured logging examples using some libraries we are familiar with at Honeycomb. Feel free to use your own!


import (
  log ""


func Handler(ctx context.Context) error {
  // Measure execution time
  startTime := time.Now()

  // ...

  // Get the Lambda context object
  lc, _ := lambdacontext.FromContext(ctx)

    "function_name": lambdacontext.FunctionName,
    "function_version": lambdacontext.FunctionVersion,
    "request_id": lc.AwsRequestID,
    "duration_ms": time.Since(startTime).Milliseconds(),
    // other fields of interest
  }).Info("Hello World from Lambda!")


import structlog
log = structlog.get_logger()

def handler(event, context):
    # measure execution time
    start_time =

    # ...

        "Hello World from Lambda!",
        duration_ms=( - start_time).total_seconds() * 1000,
        # other fields of interest


var bunyan = require('bunyan');
var log = bunyan.createLogger();

module.exports.handler = (event, context, callback) => {
  // Measure execution time
  let startTime =;

  // ...{
    functionName: context.functionName,
    functionVersion: context.functionVersion,
    requestId: context.awsRequestId,
    // Example fields - send anything that seems relevant!
    userId: event.UserId,
    userAction: event.UserAction,
    latencyMs: - startTime,
  'Hello World from Lambda!');

Note: Do not use console.log to write structured log lines in Lambda. Lambda uses a patched version of console.log, injecting extra information with each line that does not work correctly with the Honeycomb Extension Lambda Logs integration.

Did you find what you were looking for?