When I attempt to export OTLP traces to Jaeger, I get this error:
OpenTelemetry trace error occurred. Exporter otlp encountered the following error(s): the grpc server returns error (Unknown error): , detailed error message: Service was not ready: transport error
My understanding is that might be an interaction between tokio
and tonic
, but I don't control the creation of this client. I couldn't get grpc
to work either, and http
is basically undocumented.
use opentelemetry::trace::Tracer;
use opentelemetry_otlp::WithExportConfig;
#[tokio::main]
async fn main() {
let otlp_exporter = opentelemetry_otlp::new_exporter().tonic().with_endpoint("http://jaeger:4317/");
let tracer = opentelemetry_otlp::new_pipeline()
.tracing()
.with_exporter(otlp_exporter)
.install_simple()
.unwrap();
tracer.in_span("xyz", |_| {});
}
[package]
name = "sample"
version = "0.1.0"
edition = "2021"
[dependencies]
opentelemetry = "0.18.0"
opentelemetry-otlp = "0.11"
tokio = { version = "1.28", features = ["rt-multi-thread"] }
Jaeger is running in an adjacent container with the DNS name 'jaeger', which is resolvable. Here's the compose file (app is the devcontainer where the Rust code runs):
version: '3.8'
services:
app:
image: mcr.microsoft.com/devcontainers/base:jammy
volumes:
- ../..:/workspaces:cached
command: sleep infinity
network_mode: service:jaeger
jaeger:
image: jaegertracing/all-in-one:1.44
restart: unless-stopped
Thanks to Pierre who pointed me along to the reference implementation, I was able to find the root cause was that Jaeger by default does not accept OTLP (the docs don't make this very clear). If you set the environment variable COLLECTOR_OTLP_ENABLED=true
on Jaeger, it will start accepting on 4317.
My updated sample looks like this:
use opentelemetry::sdk::propagation::TraceContextPropagator;
use opentelemetry_otlp::WithExportConfig;
use tracing::metadata::LevelFilter;
use tracing_subscriber::{Registry, Layer};
use tracing_subscriber::layer::SubscriberExt;
#[tokio::main]
async fn main() {
opentelemetry::global::set_text_map_propagator(TraceContextPropagator::new());
let otlp_exporter = opentelemetry_otlp::new_exporter().tonic().with_endpoint("http://jaeger:4317/v1/traces");
let tracer = opentelemetry_otlp::new_pipeline()
.tracing()
.with_exporter(otlp_exporter)
.with_trace_config(opentelemetry::sdk::trace::config().with_resource(
opentelemetry::sdk::Resource::new(vec![opentelemetry::KeyValue::new("service.name", "sample")]),
))
.install_simple()
.unwrap();
let telemetry = tracing_opentelemetry::layer().with_tracer(tracer).with_filter(LevelFilter::INFO);
let subscriber = Registry::default().with(telemetry);
tracing::subscriber::set_global_default(subscriber).unwrap();
// ... do some tracing!
}
[package]
name = "sample"
version = "0.1.0"
edition = "2021"
[dependencies]
opentelemetry = "0.18.0"
opentelemetry-otlp = "0.11"
tokio = { version = "1.28", features = ["rt-multi-thread"] }
tracing = "0.1.37"
tracing-opentelemetry = "0.18"
tracing-subscriber = "0.3.17"