Module processor

Source
Expand description

Span processor implementation optimized for AWS Lambda functions.

This module provides a Lambda-optimized span processor that efficiently manages OpenTelemetry spans in a serverless environment. It uses a ring buffer to store spans in memory and provides efficient batch processing capabilities.

§Architecture

The processor is designed specifically for the Lambda execution environment:

  1. Ring Buffer Storage:

    • Fixed-size circular buffer prevents memory growth
    • O(1) push operations with no memory reallocation
    • FIFO ordering ensures spans are processed in order
    • Efficient batch removal for export
    • When full, new spans are dropped (with warning logs)
  2. Thread Safety:

    • All operations are thread-safe
    • Uses Mutex for span buffer access
    • Atomic operations for state management
    • Safe for concurrent span submission

§Configuration

The processor can be configured through environment variables:

  • LAMBDA_SPAN_PROCESSOR_QUEUE_SIZE: Controls buffer size

    • Defaults to 2048 spans
    • Should be tuned based on span volume
  • LAMBDA_SPAN_PROCESSOR_BATCH_SIZE: Controls batch size

    • Defaults to 512 spans
    • Should be tuned based on span volume

§Usage Examples

Basic setup with default configuration:

use lambda_otel_lite::LambdaSpanProcessor;
use otlp_stdout_span_exporter::OtlpStdoutSpanExporter;

let processor = LambdaSpanProcessor::builder()
    .exporter(OtlpStdoutSpanExporter::default())
    .build();

Using with an OTLP HTTP exporter:

use lambda_otel_lite::LambdaSpanProcessor;
use opentelemetry_otlp::{SpanExporter, Protocol};
use opentelemetry_otlp::{WithExportConfig, WithHttpConfig};

// Important: When using HTTP exporters, always use reqwest::blocking::Client
// Using async clients will cause deadlocks
let exporter = SpanExporter::builder()
    .with_http()
    .with_http_client(reqwest::blocking::Client::new())
    .with_protocol(Protocol::HttpBinary)
    .build()
    .expect("Failed to create exporter");

let processor = LambdaSpanProcessor::builder()
    .exporter(exporter)
    .max_queue_size(4096)
    .max_batch_size(1024)
    .build();

§Performance Considerations

  1. Memory Usage:

    • Fixed memory footprint based on queue size
    • Each span typically uses 100-500 bytes
    • Default 2048 spans ≈ 0.5-1MB memory
  2. Latency Impact:

    • Batch processing reduces network overhead
    • Configurable batch size allows tuning for your use case
    • Force flush available for immediate export when needed
  3. Reliability:

    • Spans may be dropped if buffer fills
    • Warning logs indicate dropped spans
    • Consider increasing buffer size if spans are dropped

§Best Practices

  1. Buffer Sizing:

    • Monitor dropped_spans metric
    • Size based on max spans per invocation
    • Consider function memory when sizing
  2. Batch Configuration:

    • Larger batches improve throughput but increase memory usage
    • Smaller batches reduce memory but increase network overhead
    • Default values work well for most use cases
  3. Error Handling:

    • Export errors are logged but don’t fail function
    • Monitor for export failures in logs
    • Consider retry strategies in custom exporters

Structs§

LambdaSpanProcessor
A span processor optimized for AWS Lambda functions.
LambdaSpanProcessorBuilder
Use builder syntax to set the inputs and finish with build().