diff --git a/editoast/Cargo.lock b/editoast/Cargo.lock index 86e93ff2c30..bf67cf18972 100644 --- a/editoast/Cargo.lock +++ b/editoast/Cargo.lock @@ -1363,6 +1363,7 @@ dependencies = [ "opentelemetry", "opentelemetry-otlp", "opentelemetry-semantic-conventions", + "opentelemetry-stdout", "opentelemetry_sdk", "ordered-float", "osm_to_railjson", @@ -3085,6 +3086,23 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db945c1eaea8ac6a9677185357480d215bb6999faa9f691d0c4d4d641eab7a09" +[[package]] +name = "opentelemetry-stdout" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc8a298402aa5c260be90d10dc54b5a7d4e1025c354848f8e2c976d761351049" +dependencies = [ + "async-trait", + "chrono", + "futures-util", + "opentelemetry", + "opentelemetry_sdk", + "ordered-float", + "serde", + "serde_json", + "thiserror 1.0.69", +] + [[package]] name = "opentelemetry_sdk" version = "0.27.1" diff --git a/editoast/Cargo.toml b/editoast/Cargo.toml index b70a36242b0..c357a26f39e 100644 --- a/editoast/Cargo.toml +++ b/editoast/Cargo.toml @@ -146,6 +146,7 @@ opentelemetry-otlp = { version = "0.27.0", default-features = false, features = "trace", ] } opentelemetry-semantic-conventions.workspace = true +opentelemetry-stdout = { version = "0.27.0" } opentelemetry_sdk = { version = "0.27.1", features = ["rt-tokio", "trace"] } ordered-float = { version = "4.5.0", features = ["serde"] } osm_to_railjson = { path = "./osm_to_railjson" } diff --git a/editoast/src/main.rs b/editoast/src/main.rs index 7ca4b46553f..9e80ae9b60c 100644 --- a/editoast/src/main.rs +++ b/editoast/src/main.rs @@ -33,10 +33,12 @@ use client::Commands; use editoast_models::DbConnectionPoolV2; use models::RollingStockModel; use opentelemetry::trace::TracerProvider as _; +use opentelemetry_sdk::export::trace::SpanExporter; use opentelemetry_sdk::propagation::TraceContextPropagator; use opentelemetry_sdk::resource::EnvResourceDetector; use opentelemetry_sdk::resource::SdkProvidedResourceDetector; use opentelemetry_sdk::resource::TelemetryResourceDetector; +use tracing_subscriber::util::TryInitError; pub use views::AppState; use models::prelude::*; @@ -66,12 +68,16 @@ pub use valkey_utils::ValkeyConnection; /// - we *expect* a webserver to output logging information, so since it's an expected /// output (and not extra information), it should be on stdout #[derive(Debug, PartialEq)] -enum EditoastMode { +pub enum EditoastMode { Webservice, Cli, } -fn init_tracing(mode: EditoastMode, telemetry_config: &client::TelemetryConfig) { +pub fn try_init_tracing( + mode: EditoastMode, + telemetry_config: &client::TelemetryConfig, + exporter: T, +) -> Result<(), TryInitError> { let env_filter_layer = tracing_subscriber::EnvFilter::builder() // Set the default log level to 'info' .with_default_directive(tracing_subscriber::filter::LevelFilter::INFO.into()) @@ -89,11 +95,6 @@ fn init_tracing(mode: EditoastMode, telemetry_config: &client::TelemetryConfig) let telemetry_layer = match telemetry_config.telemetry_kind { client::TelemetryKind::None => None, client::TelemetryKind::Opentelemetry => { - let exporter = opentelemetry_otlp::SpanExporter::builder() - .with_tonic() - .with_endpoint(telemetry_config.telemetry_endpoint.as_str()) - .build() - .expect("failed to build a span exporter"); let resource = Resource::new(vec![KeyValue::new( opentelemetry_semantic_conventions::resource::SERVICE_NAME, telemetry_config.service_name.clone(), @@ -116,11 +117,12 @@ fn init_tracing(mode: EditoastMode, telemetry_config: &client::TelemetryConfig) Some(layer) } }; + tracing_subscriber::registry() .with(telemetry_layer) .with(env_filter_layer) .with(fmt_layer) - .init(); + .try_init() } impl EditoastMode { @@ -151,7 +153,17 @@ async fn main() { async fn run() -> Result<(), Box> { let client = Client::parse(); - init_tracing(EditoastMode::from_client(&client), &client.telemetry_config); + let exporter = opentelemetry_otlp::SpanExporter::builder() + .with_tonic() + .with_endpoint(client.telemetry_config.telemetry_endpoint.as_str()) + .build() + .expect("failed to build a span exporter"); + try_init_tracing( + EditoastMode::from_client(&client), + &client.telemetry_config, + exporter, + ) + .expect("failed to init tracing"); let pg_config = client.postgres_config; let db_pool = diff --git a/editoast/src/views/test_app.rs b/editoast/src/views/test_app.rs index 9ab47d93081..b481b61a840 100644 --- a/editoast/src/views/test_app.rs +++ b/editoast/src/views/test_app.rs @@ -14,12 +14,14 @@ use tower_http::trace::TraceLayer; use url::Url; use crate::{ + client::{TelemetryConfig, TelemetryKind}, core::{mocking::MockingClient, CoreClient}, generated_data::speed_limit_tags_config::SpeedLimitTagIds, infra_cache::InfraCache, map::MapLayers, + try_init_tracing, valkey_utils::ValkeyConfig, - AppState, ValkeyClient, + AppState, EditoastMode, ValkeyClient, }; use axum_test::TestRequest; use axum_test::TestServer; @@ -106,16 +108,12 @@ impl TestAppBuilder { }; // Setup tracing - let sub = tracing_subscriber::fmt() - .pretty() - .with_env_filter( - tracing_subscriber::EnvFilter::builder() - .with_default_directive(tracing_subscriber::filter::LevelFilter::DEBUG.into()) - .from_env_lossy(), - ) - .with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE) - .finish(); - let tracing_guard = tracing::subscriber::set_default(sub); + let exporter = opentelemetry_stdout::SpanExporter::default(); + let telemety_config = TelemetryConfig { + telemetry_kind: TelemetryKind::Opentelemetry, + ..Default::default() + }; + let _ = try_init_tracing(EditoastMode::Webservice, &telemety_config, exporter); // Config valkey let valkey = ValkeyClient::new(config.valkey_config.clone()) @@ -175,7 +173,6 @@ impl TestAppBuilder { server, db_pool: db_pool_v2, core_client, - tracing_guard, } } } @@ -188,8 +185,6 @@ pub(crate) struct TestApp { server: TestServer, db_pool: Arc, core_client: Arc, - #[allow(unused)] // included here to extend its lifetime, not meant to be used in any way - tracing_guard: tracing::subscriber::DefaultGuard, } impl TestApp {