-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Open
Description
When using actix-web-rt, flushing the Opentelemetry logger provider with GRPC tonic in main() results in a flushing timeout error. However, flushing within a router function completes without issue.
Expected Behavior
Flushing Opentelemetry logger provider succeeds.
Current Behavior
Flushing Opentelemetry logger results in a timeout error.
Possible Solution
use tokio runtime
replace actix-web::main with tokio::main
Steps to Reproduce (for bugs)
cargo.toml
[package]
name = "actix-web-sample"
version = "0.1.0"
edition = "2024"
[dependencies]
actix-web = "4.11.0"
futures-executor = "0.3.31"
tokio = { version = "1.47.1", features = ["macros","rt-multi-thread"] }
opentelemetry_sdk = "0.30.0"
opentelemetry = "0.30.0"
opentelemetry-stdout = "0.30.0"
opentelemetry-otlp = { version = "0.30.0", features = ["grpc-tonic"] }
opentelemetry-appender-tracing = "0.30.1"
anyhow = "1.0.99"
tracing = { version = "0.1.41", features = ["log"] }
tracing-appender = "0.2.3"
tracing-subscriber = { version = "0.3.20", features = ["env-filter","time"] }
tracing-opentelemetry = "0.31.0"main.rs
use actix_web::{
App, HttpRequest, HttpServer,
web::{self, Data},
};
use anyhow::{Ok, Result, anyhow};
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
use opentelemetry_otlp::WithExportConfig;
use opentelemetry_sdk::logs::SdkLoggerProvider;
use tracing_subscriber::{Layer, layer::SubscriberExt, util::SubscriberInitExt};
async fn index(logger_provider: Data<SdkLoggerProvider>, req: HttpRequest) -> &'static str {
tracing::info!("REQ: {:?}", req);
// flushing logs
if let Err(err) = logger_provider.force_flush() {
return "flushing error";
}
"Hello world!\r\n"
}
#[actix_web::main]
async fn main() -> Result<()> {
let otlp_endpoint = "http://localhost:4317";
let otlp_log_exporter = opentelemetry_otlp::LogExporter::builder()
.with_tonic()
.with_endpoint(otlp_endpoint)
.build()?;
let logger_provider = SdkLoggerProvider::builder()
.with_batch_exporter(otlp_log_exporter)
.build();
tracing_subscriber::registry()
.with(
OpenTelemetryTracingBridge::new(&logger_provider)
.with_filter(tracing::level_filters::LevelFilter::INFO),
)
.init();
if let Err(e) = database_setup() {
tracing::error!("database setup error");
logger_provider.force_flush()?;
return Err(e);
}
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(logger_provider.clone()))
.service(web::resource("/").route(web::get().to(index)))
})
.bind(("127.0.0.1", 8080))?
.run()
.await?;
Ok(())
}
fn database_setup() -> Result<()> {
// simluate error
Err(anyhow!("database connection error"))
}Context
The application can not log the error msg before exit at main()
The batch_log_processor in opentelemetry sdk uses futures_executor::block_on() to flush the log, which appears to cause this issue. But why does flushing within a router function complete without issue?
Your Environment
- Rust Version (I.e, output of
rustc -V): 1.90.0 - Actix Web Version: 4.11.0
Metadata
Metadata
Assignees
Labels
No labels