3 releases (breaking)
new 0.10.0 | Mar 4, 2025 |
---|---|
0.3.0 | Dec 17, 2024 |
0.1.0 | Dec 8, 2024 |
#349 in Profiling
130 downloads per month
Used in lambda-otel-utils
39KB
621 lines
otlp-sigv4-client
A SigV4-compatible HTTP client wrapper for OpenTelemetry OTLP exporters, enabling AWS authentication for sending telemetry data to the CloudWatch OTLP endpoint
Features
- AWS SigV4 authentication for OpenTelemetry OTLP exporters
- Support for both reqwest and hyper HTTP clients
- Automatic AWS region detection from environment
- Configurable AWS service name
- Compatible with AWS credentials provider chain
- Implements OpenTelemetry's
HttpClient
trait
Installation
Add this to your Cargo.toml
or run cargo add otlp-sigv4-client
:
[dependencies]
otlp-sigv4-client = "0.10.0"
Usage
Here's a basic example using the reqwest HTTP client:
use aws_config;
use aws_credential_types::provider::ProvideCredentials;
use opentelemetry_otlp::{HttpExporterBuilder, WithHttpConfig};
use otlp_sigv4_client::SigV4ClientBuilder;
use reqwest::Client as ReqwestClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Load AWS configuration from the environment
let config = aws_config::load_from_env().await;
let credentials = config
.credentials_provider()
.expect("No credentials provider found")
.provide_credentials()
.await?;
// Create the SigV4 client
let sigv4_client = SigV4ClientBuilder::new()
.with_client(ReqwestClient::new())
.with_credentials(credentials)
.with_service("xray") // AWS X-Ray service name
.build()?;
// Configure and build the OTLP exporter
let exporter = HttpExporterBuilder::default()
.with_http_client(sigv4_client)
.with_endpoint("https://xray.us-east-1.amazonaws.com")
.build_span_exporter()?;
// Use the exporter with your OpenTelemetry pipeline...
Ok(())
}
Configuration
AWS Region
The region is determined in the following order:
- Explicitly set via
with_region()
- Environment variable
AWS_REGION
- Default value "us-east-1"
AWS Credentials
The client supports any valid AWS credentials source:
- Environment variables (
AWS_ACCESS_KEY_ID
,AWS_SECRET_ACCESS_KEY
) - AWS credentials file (
~/.aws/credentials
) - IAM roles (EC2 instance role, ECS task role, Lambda function role)
- Other AWS credential sources (SSO, web identity, etc.)
Required IAM Permissions
The client requires the following IAM permissions:
xray:PutTraceSegments
xray:PutSpans
xray:PutSpansForIndexing
HTTP Client
The crate works with any HTTP client that implements the opentelemetry_http::HttpClient
trait. The client is generic, allowing you to wrap your preferred HTTP client implementation.
Feature Flags
The package includes the following feature flags:
reqwest
(default feature): Includes reqwest as a dependency for convenience. Disable this feature if you want to use a different HTTP client or if you already have reqwest in your dependencies.
To use without reqwest, disable default features in your Cargo.toml:
[dependencies]
otlp-sigv4-client = { version = "0.10.0", default-features = false }
An example implementation using the reqwest client is provided in the examples directory.
Examples
Check out the examples directory for more detailed examples:
- SigV4 Authentication: Example showing AWS SigV4 authentication configuration and usage
- More examples coming soon...
Important Usage Note for OpenTelemetry SDK 0.28.0+
Starting with OpenTelemetry SDK 0.28.0, there's a known issue when using custom HTTP clients with the batch processor. According to the changelog, the batch processor now uses a blocking client even when the rt-tokio
feature is enabled, which can cause panics like:
thread 'OpenTelemetry.Traces.BatchProcessor' panicked at [...]:
there is no reactor running, must be called from the context of a Tokio 1.x runtime
Recommended Solution
If you're experiencing this issue, create your HTTP client in a separate thread to isolate runtime initialization:
use aws_config;
use aws_credential_types::provider::ProvideCredentials;
use opentelemetry_otlp::{HttpExporterBuilder, WithHttpConfig};
use otlp_sigv4_client::SigV4ClientBuilder;
use reqwest::blocking::Client as BlockingReqwestClient;
// Load AWS configuration first (in the async context)
let config = aws_config::load_from_env().await;
let credentials = config
.credentials_provider()
.expect("No credentials provider found")
.provide_credentials()
.await?;
// Create the blocking SigV4 client in a separate thread to avoid runtime conflicts
let sigv4_client = std::thread::spawn(move || {
let client = BlockingReqwestClient::new();
SigV4ClientBuilder::new()
.with_client(client)
.with_credentials(credentials)
.with_region("us-east-1")
.with_service("xray")
.build()
.expect("Failed to build SigV4 client")
}).join().unwrap();
// Use the isolated client with your exporter
let exporter = HttpExporterBuilder::default()
.with_http_client(sigv4_client)
.with_endpoint("https://xray.us-east-1.amazonaws.com")
.build_span_exporter()?;
This pattern works by isolating the client creation in a separate thread, which prevents runtime conflicts between the batch processor and the main application.
AWS Service Compatibility
This client is designed primarily for use with AWS X-Ray OTLP endpoints. By default, it uses "xray" as the service name for AWS SigV4 authentication.
Service Configuration
The default service name is "xray" if not specified. This can be set explicitly using the with_service()
method:
// For AWS X-Ray (default)
.with_service("xray")
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
This crate is part of the serverless-otlp-forwarder project.
Dependencies
~10–21MB
~301K SLoC