diff --git a/editoast/Cargo.lock b/editoast/Cargo.lock index 3b16dbb9ae2..1788947e4e9 100644 --- a/editoast/Cargo.lock +++ b/editoast/Cargo.lock @@ -507,6 +507,17 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -1145,6 +1156,7 @@ dependencies = [ "actix-web", "async-std", "async-trait", + "atty", "chashmap", "chrono", "clap", @@ -1690,6 +1702,15 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.2" @@ -1902,7 +1923,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.2", "libc", "windows-sys", ] @@ -1919,7 +1940,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.2", "rustix 0.38.8", "windows-sys", ] @@ -2253,7 +2274,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.2", "libc", ] diff --git a/editoast/Cargo.toml b/editoast/Cargo.toml index 9da5a916099..71360cdacaa 100644 --- a/editoast/Cargo.toml +++ b/editoast/Cargo.toml @@ -64,6 +64,7 @@ osm4routing = "0.5.8" osmpbfreader = "0.16.0" itertools = "0.11" utoipa = { version = "3.5", features = ["actix_extras"] } +atty = "0.2.14" [dev-dependencies] async-std = { version = "1.12", features = ["attributes", "tokio1"] } diff --git a/editoast/src/client/mod.rs b/editoast/src/client/mod.rs index fdf9cc295a1..3e46d498e0f 100644 --- a/editoast/src/client/mod.rs +++ b/editoast/src/client/mod.rs @@ -1,7 +1,7 @@ mod postgres_config; mod redis_config; -use clap::{Args, Parser, Subcommand}; +use clap::{Args, Parser, Subcommand, ValueEnum}; use derivative::Derivative; pub use postgres_config::PostgresConfig; pub use redis_config::RedisConfig; @@ -14,10 +14,21 @@ pub struct Client { pub postgres_config: PostgresConfig, #[command(flatten)] pub redis_config: RedisConfig, + #[arg(long, env, value_enum, default_value_t = Color::Auto)] + pub color: Color, #[command(subcommand)] pub command: Commands, } +#[derive(ValueEnum, Debug, Derivative, Clone)] +#[derivative(Default)] +pub enum Color { + Never, + Always, + #[derivative(Default)] + Auto, +} + #[derive(Subcommand, Debug)] pub enum Commands { Runserver(RunserverArgs), diff --git a/editoast/src/core/mod.rs b/editoast/src/core/mod.rs index 262310a09e1..f006a79a12c 100644 --- a/editoast/src/core/mod.rs +++ b/editoast/src/core/mod.rs @@ -12,6 +12,7 @@ use std::marker::PhantomData; use crate::error::Result; use async_trait::async_trait; +use colored::{ColoredString, Colorize}; use editoast_derive::EditoastError; pub use http_client::{HttpClient, HttpClientBuilder}; use log::info; @@ -22,6 +23,19 @@ use thiserror::Error; const MAX_RETRIES: u8 = 5; +fn colored_method(method: &reqwest::Method) -> ColoredString { + let m = method.as_str(); + match *method { + reqwest::Method::GET => m.green(), + reqwest::Method::POST => m.yellow(), + reqwest::Method::PUT => m.blue(), + reqwest::Method::PATCH => m.magenta(), + reqwest::Method::DELETE => m.red(), + _ => m.normal(), + } + .bold() +} + #[derive(Debug, Clone)] pub enum CoreClient { Direct(HttpClient), @@ -51,6 +65,9 @@ impl CoreClient { path: &str, body: Option<&B>, ) -> Result { + let method_s = colored_method(&method); + log::info!(target: "editoast::coreclient", "{method_s} {path}"); + log::debug!(target: "editoast::coreclient", "Request content: {body}", body = body.and_then(|b| serde_json::to_string_pretty(b).ok()).unwrap_or_default()); match self { CoreClient::Direct(client) => { let mut i_try = 0; @@ -84,8 +101,11 @@ impl CoreClient { msg: err.to_string(), })?; if status.is_success() { + log::info!(target: "editoast::coreclient", "{method_s} {path} {status}", status = status.to_string().bold().green()); return R::from_bytes(bytes.as_ref()); } + + log::error!(target: "editoast::coreclient", "{method_s} {path} {status}", status = status.to_string().bold().red()); // We try to deserialize the response as the standard Core error format // If that fails we try to return a generic error containing the raw error let core_error = as CoreResponse>::from_bytes( diff --git a/editoast/src/error.rs b/editoast/src/error.rs index df1078c0cc7..0bf4e0e9973 100644 --- a/editoast/src/error.rs +++ b/editoast/src/error.rs @@ -1,8 +1,10 @@ use actix_web::{error::JsonPayloadError, http::StatusCode, HttpResponse, ResponseError}; +use colored::Colorize; use diesel::result::Error as DieselError; use redis::RedisError; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; +use std::backtrace::Backtrace; use std::collections::HashMap; use std::result::Result as StdResult; use std::{ @@ -77,6 +79,12 @@ impl ResponseError for InternalError { } fn error_response(&self) -> HttpResponse { + log::error!( + "[{}] {}: {}", + self.error_type.bold(), + self.message, + Backtrace::capture() // won't log unless RUST_BACKTRACE=1 + ); HttpResponse::build(self.status).json(self) } } diff --git a/editoast/src/main.rs b/editoast/src/main.rs index eaa4ebc0fee..0f5f502e13a 100644 --- a/editoast/src/main.rs +++ b/editoast/src/main.rs @@ -29,7 +29,7 @@ use actix_web::{App, HttpServer}; use chashmap::CHashMap; use clap::Parser; use client::{ - ClearArgs, Client, Commands, GenerateArgs, ImportProfileSetArgs, ImportRailjsonArgs, + ClearArgs, Client, Color, Commands, GenerateArgs, ImportProfileSetArgs, ImportRailjsonArgs, PostgresConfig, RedisConfig, RunserverArgs, }; use colored::*; @@ -71,6 +71,12 @@ async fn run() -> Result<(), Box> { let pg_config = client.postgres_config; let redis_config = client.redis_config; + match client.color { + Color::Never => colored::control::set_override(false), + Color::Always => colored::control::set_override(true), + Color::Auto => colored::control::set_override(atty::is(atty::Stream::Stderr)), + } + match client.command { Commands::Runserver(args) => runserver(args, pg_config, redis_config).await, Commands::Generate(args) => generate(args, pg_config, redis_config).await,