| Crates.io | opentelemetry-configuration |
| lib.rs | opentelemetry-configuration |
| version | 0.3.2 |
| created_at | 2025-12-07 12:17:05.629683+00 |
| updated_at | 2026-01-06 14:35:53.85863+00 |
| description | Opinionated OpenTelemetry SDK configuration wiring together tracing, OTLP export, and lifecycle management |
| homepage | |
| repository | https://github.com/djvcom/opentelemetry-configuration |
| max_upload_size | |
| id | 1971501 |
| size | 152,631 |
Opinionated OpenTelemetry SDK configuration for Rust applications.
This crate wires together the OpenTelemetry SDK, OTLP exporters, and the tracing crate ecosystem into a cohesive configuration system. It handles initialisation, flushing, and shutdown of all signal providers (traces, metrics, logs).
tracing-opentelemetry and opentelemetry-appender-tracing layersuse opentelemetry_configuration::{OtelSdkBuilder, SdkError};
fn main() -> Result<(), SdkError> {
let _guard = OtelSdkBuilder::new()
.service_name("my-service")
.build()?;
tracing::info!("Application running");
// On drop, all providers are flushed and shut down
Ok(())
}
use opentelemetry_configuration::{OtelSdkBuilder, Protocol, SdkError};
let _guard = OtelSdkBuilder::new()
.endpoint("http://collector:4318")
.protocol(Protocol::HttpBinary)
.service_name("my-service")
.service_version("1.0.0")
.deployment_environment("production")
.build()?;
use opentelemetry_configuration::OtelSdkBuilder;
let _guard = OtelSdkBuilder::new()
.with_standard_env() // Reads OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAME, etc.
.build()?;
use opentelemetry_configuration::OtelSdkBuilder;
let _guard = OtelSdkBuilder::new()
.with_file("/etc/otel-config.toml")
.build()?;
[endpoint]
url = "http://collector:4318"
protocol = "httpbinary" # or "grpc", "httpjson"
timeout = "10s"
[endpoint.headers]
Authorization = "Bearer token"
[resource]
service_name = "my-service"
service_version = "1.0.0"
deployment_environment = "production"
[traces]
enabled = true
[traces.batch]
max_queue_size = 2048
max_export_batch_size = 512
scheduled_delay = "5s"
[metrics]
enabled = true
[logs]
enabled = true
The batch processor settings control how telemetry data is batched before export:
| Setting | Default | Description |
|---|---|---|
max_queue_size |
2048 | Maximum spans/logs buffered before dropping |
max_export_batch_size |
512 | Maximum items per export batch |
scheduled_delay |
5s | Interval between export attempts |
| Protocol | Default Port | Content-Type |
|---|---|---|
HttpBinary (default) |
4318 | application/x-protobuf |
HttpJson |
4318 | application/json |
Grpc |
4317 | gRPC |
The OtelGuard returned by build() manages the lifecycle of all providers:
let guard = OtelSdkBuilder::new()
.service_name("my-service")
.build()?;
// Manual flush if needed
guard.flush();
// Explicit shutdown (consumes guard)
guard.shutdown()?;
// Or let drop handle it automatically
let _guard = OtelSdkBuilder::new()
.service_name("my-service")
.traces(false)
.metrics(false)
.logs(false)
.build()?;
let _guard = OtelSdkBuilder::new()
.service_name("my-service")
.resource_attribute("deployment.region", "eu-west-1")
.resource_attribute("team", "Australia II")
.build()?;
By default, the instrumentation scope name (otel.library.name) is set to the service name. You can override it explicitly:
let _guard = OtelSdkBuilder::new()
.service_name("my-api")
.instrumentation_scope_name("my-api-tracing")
.build()?;
Resource attributes are automatically detected based on the compute environment. By default (Auto), generic detectors run and the environment is probed:
use opentelemetry_configuration::{OtelSdkBuilder, ComputeEnvironment};
// Explicit Lambda environment
let _guard = OtelSdkBuilder::new()
.service_name("my-lambda")
.compute_environment(ComputeEnvironment::Lambda)
.build()?;
// Kubernetes environment
let _guard = OtelSdkBuilder::new()
.service_name("my-k8s-service")
.compute_environment(ComputeEnvironment::Kubernetes)
.build()?;
// No automatic detection
let _guard = OtelSdkBuilder::new()
.service_name("my-service")
.compute_environment(ComputeEnvironment::None)
.build()?;
Available environments:
Auto (default): Runs host/OS/process/Rust detectors, probes for Lambda and K8sLambda: Generic detectors + Rust detector + Lambda-specific attributes (faas., cloud.)Kubernetes: Generic detectors + Rust detector + K8s detectorNone: No automatic detectionAll compute environments (except None) automatically detect Rust-specific attributes:
process.runtime.name = "rust"rust.target_os, rust.target_arch, rust.target_familyrust.debug (true for debug builds)process.executable.size (binary size in bytes)To capture rustc version and channel, add to your build.rs:
fn main() {
opentelemetry_configuration::emit_rustc_env();
}
Then in your application:
use opentelemetry_configuration::{OtelSdkBuilder, capture_rust_build_info};
let _guard = OtelSdkBuilder::new()
.service_name("my-service")
.with_rust_build_info(capture_rust_build_info!())
.build()?;
This adds:
process.runtime.version (e.g., "1.84.0")process.runtime.description (full rustc version string)rust.channel ("stable", "beta", or "nightly")The SdkError enum covers all failure modes:
| Variant | Cause |
|---|---|
Config |
Invalid configuration (malformed TOML, type mismatches) |
TraceExporter |
Failed to create trace exporter (invalid endpoint, TLS issues) |
MetricExporter |
Failed to create metric exporter |
LogExporter |
Failed to create log exporter |
TracingSubscriber |
Failed to initialise tracing (already initialised) |
Flush |
Failed to flush pending data |
Shutdown |
Failed to shut down providers cleanly |
InvalidEndpoint |
Endpoint URL missing http:// or https:// scheme |
use opentelemetry_configuration::{OtelSdkBuilder, SdkError};
match OtelSdkBuilder::new().service_name("my-service").build() {
Ok(guard) => { /* use guard */ }
Err(SdkError::Config(e)) => eprintln!("Configuration error: {e}"),
Err(SdkError::InvalidEndpoint { url }) => eprintln!("Bad endpoint: {url}"),
Err(e) => eprintln!("SDK error: {e}"),
}
.traces(true) etc.Set init_tracing_subscriber to false if you manage tracing yourself:
let _guard = OtelSdkBuilder::new()
.service_name("my-service")
.init_tracing_subscriber(false)
.build()?;
ComputeEnvironment::None disables all automatic detectionAWS_LAMBDA_FUNCTION_NAME is set (or ComputeEnvironment::Lambda is explicit)ComputeEnvironment::KubernetesMIT