opentelemetry-lambda-extension
AWS Lambda extension for collecting and exporting OpenTelemetry traces, metrics, and logs from Lambda functions.
Overview
This extension receives telemetry data (traces, metrics, logs) from instrumented Lambda functions via a local OTLP receiver and exports them to your observability backend. It integrates with Lambda's Extensions API for proper lifecycle management and handles the unique constraints of Lambda's execution model.
Features
- Multi-signal support - Traces, metrics, and logs via OTLP (HTTP and gRPC)
- Automatic batching - Intelligent signal aggregation with size and time limits
- Adaptive flushing - Flush before Lambda freezes to prevent data loss
- Platform telemetry - Captures Lambda platform metrics (duration, memory, cold starts)
- Span correlation - Links function spans with platform telemetry
- Resource detection - Automatically detects Lambda resource attributes
- Configurable exports - HTTP or gRPC, with compression and timeout options
Installation
Prerequisites
Install cargo-lambda:
# Using pip
# Or using Homebrew (macOS)
As a Lambda Layer
Build and deploy the extension using cargo-lambda:
# Build optimised for Lambda (handles cross-compilation automatically)
# The binary is ready at:
# target/lambda/extensions/opentelemetry-lambda-extension
Create and deploy the layer:
# Create layer structure
# Package the layer
&&
# Deploy to AWS
For ARM64 (Graviton2):
# Then package and deploy with:
# --compatible-architectures arm64
Binary Size Optimisation
This extension is designed to be lightweight. With the workspace's release profile, the binary is approximately 4.4 MB (compared to ~30 MB for the OpenTelemetry Collector Lambda distribution).
The workspace Cargo.toml includes optimised release profiles:
[]
= true # Link-time optimisation for cross-crate inlining
= 1 # Better optimisation at cost of compile time
= true # Remove debug symbols
= "abort" # Remove unwinding code
[]
= "release"
= "z" # Optimise for size over speed
| Profile | Size | Use Case |
|---|---|---|
--release |
~4.4 MB | Recommended default |
--profile release-small |
~2.7 MB | When size is critical |
For even smaller binaries, you can apply UPX compression to the Linux binary:
# After building with cargo-lambda
This typically achieves 50-70% additional compression.
Analysing Binary Size
To identify what's contributing to binary size:
# Install cargo-bloat
# Show size by crate
# Show largest functions
Configuration
Configure the extension via environment variables or a TOML config file.
Environment Variables
# OTLP endpoint
OTEL_EXPORTER_OTLP_ENDPOINT=https://your-collector.example.com
# Protocol (http or grpc)
OTEL_EXPORTER_OTLP_PROTOCOL=http
# Compression
OTEL_EXPORTER_OTLP_COMPRESSION=gzip
# Headers (for authentication)
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer token"
# Extension-specific settings
OTEL_LAMBDA_FLUSH_TIMEOUT=5s
OTEL_LAMBDA_RECEIVER_PORT=9999
TOML Configuration
Place a config.toml in the Lambda function's deployment package:
[]
= "https://your-collector.example.com"
= "http"
= "gzip"
= "30s"
[]
= "Bearer your-token"
[]
= 9999
= "127.0.0.1"
[]
= "invocation"
= "5s"
Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ Lambda Execution Environment │
│ │
│ ┌─────────────┐ OTLP/HTTP or gRPC ┌────────────┐ │
│ │ Lambda │ ─────────────────────────────────▶ │ Extension │ │
│ │ Function │ traces, metrics, logs │ Receiver │ │
│ │ (instrumented)│ │ :9999 │ │
│ └─────────────┘ └─────┬──────┘ │
│ │ │
│ ▼ │
│ ┌────────────┐ │
│ │ Aggregator │ │
│ │ & Batcher │ │
│ └─────┬──────┘ │
│ │ │
│ ┌─────────────┐ │ │
│ │ Platform │ ▼ │
│ │ Telemetry │ ──────────────────────────────▶ ┌────────────┐ │
│ │ (Lambda API)│ platform metrics │ Exporter │ │
│ └─────────────┘ │ (OTLP) │ │
│ └─────┬──────┘ │
└──────────────────────────────────────────────────────────┼──────────┘
│
▼
┌────────────────────┐
│ Your Collector │
│ (Jaeger, Grafana, │
│ Datadog, etc.) │
└────────────────────┘
Lambda Lifecycle Integration
The extension integrates with Lambda's execution lifecycle:
- Init - Extension registers, starts OTLP receiver, subscribes to platform telemetry
- Invoke - Receives signals from function, aggregates, correlates with platform data
- Shutdown - Flushes all pending signals before termination
Freeze/Thaw Handling
Lambda may freeze the execution environment between invocations. The extension:
- Flushes signals before freeze (after each invocation)
- Detects thaw events and reconnects if needed
- Uses adaptive timeouts based on remaining execution time
Instrumentation
Configure your Lambda function to send telemetry to the extension:
# Point OTLP exporters at the extension
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:9999
OTEL_EXPORTER_OTLP_PROTOCOL=http
Example with the OpenTelemetry SDK
use ;
use ServiceBuilder;
let service = new
.layer
.service;
Platform Metrics
The extension automatically captures Lambda platform metrics from the Telemetry API:
| Metric | Description |
|---|---|
faas.duration |
Function execution duration |
faas.billed_duration |
Billed duration (rounded up) |
faas.max_memory |
Maximum memory used |
faas.init_duration |
Cold start initialisation time |
faas.coldstart |
Boolean indicating cold start |
Resource Attributes
The extension detects and adds Lambda resource attributes:
| Attribute | Source |
|---|---|
faas.name |
AWS_LAMBDA_FUNCTION_NAME |
faas.version |
AWS_LAMBDA_FUNCTION_VERSION |
faas.instance |
AWS_LAMBDA_LOG_STREAM_NAME |
faas.max_memory |
AWS_LAMBDA_FUNCTION_MEMORY_SIZE |
cloud.provider |
aws |
cloud.region |
AWS_REGION |
cloud.account.id |
Extracted from function ARN |
Troubleshooting
Extension not receiving data
- Verify the function is sending to
http://localhost:9999 - Check extension logs in CloudWatch:
/aws/lambda/<function>/extension - Ensure the layer is attached to the function
Data not appearing in backend
- Check
OTEL_EXPORTER_OTLP_ENDPOINTis correct - Verify authentication headers are set
- Review extension logs for export errors
- Check network connectivity (VPC configuration)
High latency
- Consider using gRPC instead of HTTP
- Enable compression:
OTEL_EXPORTER_OTLP_COMPRESSION=gzip - Tune batch settings to reduce export frequency
Licence
MIT