Я хочу экспортировать диапазоны с использованием протокола OpenTelemetry изнутри службы tonic
. Мои попытки сделать это, по-видимому, приводят к тупику. Я создал минимальный пример здесь. Вот краткое изложение:
Сначала я создаю трассировщик otlp и интегрирую его с ящиком tracing
:
let tracer = opentelemetry_otlp::new_pipeline()
.tracing()
.with_exporter(opentelemetry_otlp::new_exporter().tonic())
.install_simple()
.unwrap();
let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
let subscriber = tracing_subscriber::Registry::default().with(telemetry);
tracing::subscriber::set_global_default(subscriber).unwrap();
На этом этапе создание диапазона tracing
и создание события работает. Я могу получить и просмотреть его с помощью этой утилиты.
Далее я запускаю сервер tonic
:
tonic::transport::Server::builder()
.add_service(greeter_server::GreeterServer::new(GreeterService {}))
.serve("[::1]:50051".parse().unwrap())
.await
.unwrap();
Метод RPC украшен tracing::instrument
и пытается создать событие:
#[tonic::async_trait]
impl greeter_server::Greeter for GreeterService {
#[tracing::instrument]
async fn say_hello(...) -> ... {
tracing::info!("hello from server");
...
}
}
Когда я запускаю клиент, поток сервера, обслуживающий запрос, блокируется при отправке события на неопределенный срок.
Похоже, что в этом утверждении блокируется opentelemetry_sdk::trace::span_processor::SimpleSpanProcessor::on_end
:
let result = self
.exporter
.lock()
.map_err(|_| TraceError::Other("SimpleSpanProcessor mutex poison".into()))
.and_then(|mut exporter| futures_executor::block_on(exporter.export(vec![span])));
Где я ошибаюсь?
Решение состоит в том, чтобы использовать пакетный экспортер OpenTelemetry Tokio вместо простого экспортера:
let tracer = opentelemetry_otlp::new_pipeline()
.tracing()
.with_exporter(exporter)
.install_batch(opentelemetry_sdk::runtime::Tokio)
.unwrap();
Для этого требуется следующая функция:
opentelemetry_sdk = { version = "0.23.0", features = ["rt-tokio"] }
Спасибо https://github.com/denizenging на сервере Tokio Discord, чтобы разобраться в этом.
Его блокировка происходит именно на
exporter.export()
, а не на мьютексе. Адрес OTLP-сервера где-то теряется? Я его нигде не устанавливаю, просто по умолчанию стоитlocalhost:4317
.