diff --git a/editoast/Cargo.lock b/editoast/Cargo.lock index 86e93ff2c30..63d4e3872a7 100644 --- a/editoast/Cargo.lock +++ b/editoast/Cargo.lock @@ -351,6 +351,25 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "async-process" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +dependencies = [ + "async-channel 2.3.1", + "async-io 2.3.3", + "async-lock 3.4.0", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener 5.3.1", + "futures-lite 2.3.0", + "rustix 0.38.40", + "tracing", +] + [[package]] name = "async-reactor-trait" version = "1.1.0" @@ -363,6 +382,24 @@ dependencies = [ "reactor-trait", ] +[[package]] +name = "async-signal" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +dependencies = [ + "async-io 2.3.3", + "async-lock 3.4.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.40", + "signal-hook-registry", + "slab", + "windows-sys 0.59.0", +] + [[package]] name = "async-std" version = "1.13.0" @@ -374,6 +411,7 @@ dependencies = [ "async-global-executor", "async-io 2.3.3", "async-lock 3.4.0", + "async-process", "crossbeam-utils", "futures-channel", "futures-core", @@ -3091,6 +3129,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "231e9d6ceef9b0b2546ddf52335785ce41252bc7474ee8ba05bfad277be13ab8" dependencies = [ + "async-std", "async-trait", "futures-channel", "futures-executor", @@ -4339,6 +4378,15 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + [[package]] name = "simd-adler32" version = "0.3.7" diff --git a/editoast/Cargo.toml b/editoast/Cargo.toml index b70a36242b0..aadfecd4d7f 100644 --- a/editoast/Cargo.toml +++ b/editoast/Cargo.toml @@ -199,6 +199,7 @@ axum = { version = "0.7.9", default-features = false, features = [ editoast_authz = { workspace = true, features = ["fixtures"] } editoast_models = { workspace = true, features = ["testing"] } editoast_osrdyne_client = { workspace = true, features = ["mock_client"] } +opentelemetry_sdk = { version = "0.27.1", features = ["testing"] } pretty_assertions.workspace = true rstest.workspace = true serial_test = "3.2.0" diff --git a/editoast/src/main.rs b/editoast/src/main.rs index 7ca4b46553f..3b5d9438fc7 100644 --- a/editoast/src/main.rs +++ b/editoast/src/main.rs @@ -33,10 +33,14 @@ 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::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; +use tracing_subscriber::Layer; pub use views::AppState; use models::prelude::*; @@ -50,9 +54,6 @@ use std::sync::Arc; use std::time::Duration; use thiserror::Error; use tracing::error; -use tracing_subscriber::layer::SubscriberExt as _; -use tracing_subscriber::util::SubscriberInitExt as _; -use tracing_subscriber::Layer as _; pub use valkey_utils::ValkeyClient; pub use valkey_utils::ValkeyConnection; @@ -66,12 +67,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 init_tracing( + mode: EditoastMode, + telemetry_config: &client::TelemetryConfig, + exporter: T, +) -> impl tracing::Subscriber { 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 +94,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 +116,11 @@ 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(); } impl EditoastMode { @@ -151,7 +151,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"); + init_tracing( + EditoastMode::from_client(&client), + &client.telemetry_config, + exporter, + ) + .init(); 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..903b3679989 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, + init_tracing, map::MapLayers, valkey_utils::ValkeyConfig, - AppState, ValkeyClient, + AppState, EditoastMode, ValkeyClient, }; use axum_test::TestRequest; use axum_test::TestServer; @@ -106,15 +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 exporter = opentelemetry_sdk::testing::trace::NoopSpanExporter::default(); + let telemetry_config = TelemetryConfig { + telemetry_kind: TelemetryKind::Opentelemetry, + ..Default::default() + }; + let sub = init_tracing(EditoastMode::Webservice, &telemetry_config, exporter); let tracing_guard = tracing::subscriber::set_default(sub); // Config valkey