use opentelemetry::trace::TracerProvider as _;
use opentelemetry::KeyValue;
use opentelemetry_otlp::WithExportConfig;
use opentelemetry_sdk::trace::SdkTracerProvider;
use opentelemetry_sdk::Resource;
#[derive(Debug)]
pub struct InstallError(pub String);
impl std::fmt::Display for InstallError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "OTLP layer install: {}", self.0)
}
}
impl std::error::Error for InstallError {}
pub fn install_otlp_layer(
service_name: &str,
endpoint: &str,
) -> Result<
tracing_opentelemetry::OpenTelemetryLayer<
tracing_subscriber::registry::Registry,
opentelemetry_sdk::trace::Tracer,
>,
InstallError,
> {
let exporter = opentelemetry_otlp::SpanExporter::builder()
.with_tonic()
.with_endpoint(endpoint.to_string())
.build()
.map_err(|e| InstallError(format!("build exporter: {e}")))?;
let resource = Resource::builder()
.with_attribute(KeyValue::new("service.name", service_name.to_string()))
.build();
let provider = SdkTracerProvider::builder()
.with_batch_exporter(exporter)
.with_resource(resource)
.build();
let tracer = provider.tracer("bytesandbrains");
let _ = opentelemetry::global::set_tracer_provider(provider);
Ok(tracing_opentelemetry::layer().with_tracer(tracer))
}