Блоки экспорта интервалов OpenTelemetry из тонического RPC

Я хочу экспортировать диапазоны с использованием протокола 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])));

Где я ошибаюсь?

Его блокировка происходит именно на exporter.export(), а не на мьютексе. Адрес OTLP-сервера где-то теряется? Я его нигде не устанавливаю, просто по умолчанию стоит localhost:4317.

Alex Martin 22.07.2024 20:42
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
0
1
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решение состоит в том, чтобы использовать пакетный экспортер 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, чтобы разобраться в этом.

Другие вопросы по теме