diff --git a/Cargo.lock b/Cargo.lock index 287cb0ba1f8..7173b7b8f51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -394,7 +394,7 @@ name = "crossbeam-channel" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -404,18 +404,18 @@ name = "crossbeam-deque" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-epoch" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -429,11 +429,6 @@ dependencies = [ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam-utils" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "ctrlc" version = "3.1.1" @@ -1519,6 +1514,7 @@ dependencies = [ name = "semaphore" version = "0.1.1" dependencies = [ + "chrono 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "console 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1536,6 +1532,9 @@ dependencies = [ "semaphore-server 0.1.1", "semaphore-trove 0.1.1", "sentry 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2524,9 +2523,8 @@ source = "git+https://github.com/getsentry/sentry-rust?rev=0bf9723d4bbb1820033d4 "checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" "checksum crossbeam-channel 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "862becd07e73da5746de6d9b3ba055c9bb8b10afd0d2b51155a6e30d81cd20b3" "checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7" -"checksum crossbeam-epoch 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb27ecd6f6e30f19c34b23c368450bed3baa4658c8ad40a192381f2d3c9f1b" +"checksum crossbeam-epoch 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2af0e75710d6181e234c8ecc79f14a97907850a541b13b0be1dd10992f2e4620" "checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b" -"checksum crossbeam-utils 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b71f220442ed14749909b543d4dd7ec3918cb1fe289fd96e88d0abe6ca049783" "checksum ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "630391922b1b893692c6334369ff528dcc3a9d8061ccf4c803aa8f83cb13db5e" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum debugid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57c49686e3eebf4e7cf157f690fca61284e864fb5ce717634af4528f171048e0" diff --git a/Cargo.toml b/Cargo.toml index 21da677add5..a1c5f8cdac1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ with_ssl = ["semaphore-server/with_ssl"] [profile.release] lto = true +debug = true [dependencies] clap = { version = "2.31.2", default-features = false, features = ["wrap_help"] } @@ -24,12 +25,16 @@ tokio-core = "0.1.17" futures = "0.1.21" parking_lot = "0.5.5" ctrlc = { version = "3.1.1", features = ["termination"] } -log = "0.4.2" +log = { version = "0.4.2", features = ["serde"] } sentry = "0.5.4" dialoguer = "0.1.0" uuid = "0.6.5" console = "0.6.1" env_logger = "0.5.10" +chrono = "0.4.3" +serde_derive = "1.0.66" +serde = "1.0.66" +serde_json = "1.0.20" [dependencies.semaphore-aorta] path = "aorta" diff --git a/config/src/types.rs b/config/src/types.rs index 645b595922f..615b53aeadf 100644 --- a/config/src/types.rs +++ b/config/src/types.rs @@ -124,6 +124,20 @@ pub struct MinimalConfig { pub relay: Relay, } +/// Controls the log format +#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum LogFormat { + /// Auto detect (pretty for tty, simplified for other) + Auto, + /// With colors + Pretty, + /// Simplified log output + Simplified, + /// Dump out JSON lines + Json, +} + /// Controls the logging system. #[derive(Serialize, Deserialize, Debug)] #[serde(default)] @@ -132,6 +146,8 @@ struct Logging { level: log::LevelFilter, /// If set to true this emits log messages for failed event payloads. log_failed_payloads: bool, + /// Controls the log format. + format: LogFormat, /// When set to true, backtraces are forced on. enable_backtraces: bool, } @@ -194,6 +210,7 @@ impl Default for Logging { Logging { level: log::LevelFilter::Info, log_failed_payloads: false, + format: LogFormat::Auto, enable_backtraces: true, } } @@ -514,6 +531,11 @@ impl Config { self.values.logging.log_failed_payloads } + /// Which log format should be used? + pub fn log_format(&self) -> LogFormat { + self.values.logging.format + } + /// Returns the socket addresses for statsd. /// /// If stats is disabled an empty vector is returned. diff --git a/server/src/extractors.rs b/server/src/extractors.rs index 61f899fd0d4..2560dbd7666 100644 --- a/server/src/extractors.rs +++ b/server/src/extractors.rs @@ -116,16 +116,25 @@ impl<T: FromRequest<ServiceState> + 'static> FromRequest<ServiceState> for Proje req.extensions_mut().insert(auth.clone()); - match req.match_info() + let project_id = match req.match_info() .get("project") .unwrap_or_default() .parse::<ProjectId>() .map_err(BadProjectRequest::BadProject) { - Ok(project_id) => req.extensions_mut().insert(project_id), + Ok(project_id) => project_id, Err(err) => return Box::new(future::err(err.into())), }; + sentry::configure_scope(|scope| { + scope.set_user(Some(sentry::User { + id: Some(project_id.to_string()), + ..Default::default() + })); + }); + + req.extensions_mut().insert(project_id); + Box::new( T::from_request(&req, cfg) .into() diff --git a/src/main.rs b/src/main.rs index e1b39628fa8..341199f9eb0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,11 @@ extern crate parking_lot; extern crate pretty_env_logger; #[macro_use] extern crate sentry; +extern crate serde; +#[macro_use] +extern crate serde_derive; +extern crate chrono; +extern crate serde_json; extern crate uuid; extern crate semaphore_common; diff --git a/src/setup.rs b/src/setup.rs index b76cdd70e93..cd51928856d 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -1,15 +1,18 @@ use std::env; +use std::io; use std::io::Write; +use chrono::{DateTime, Utc}; use console; use env_logger; use failure::Error; -use log::LevelFilter; +use log::{Level, LevelFilter}; use pretty_env_logger; use sentry; +use serde_json; use semaphore_common::metrics; -use semaphore_config::Config; +use semaphore_config::{Config, LogFormat}; /// Print spawn infos to the log. pub fn dump_spawn_infos(config: &Config) { @@ -79,22 +82,56 @@ pub fn init_logging(config: &Config) { } let mut log_builder = { - if console::user_attended() { - pretty_env_logger::formatted_builder().unwrap() - } else { - let mut builder = env_logger::Builder::new(); - builder.format(|buf, record| { - let ts = buf.timestamp(); - writeln!( - buf, - "{} [{}] {}: {}", - ts, - record.module_path().unwrap_or("<unknown>"), - record.level(), - record.args() - ) - }); - builder + match (config.log_format(), console::user_attended()) { + (LogFormat::Auto, true) | (LogFormat::Pretty, _) => { + pretty_env_logger::formatted_builder().unwrap() + } + (LogFormat::Auto, false) | (LogFormat::Simplified, _) => { + let mut builder = env_logger::Builder::new(); + builder.format(|buf, record| { + let ts = buf.timestamp(); + writeln!( + buf, + "{} [{}] {}: {}", + ts, + record.module_path().unwrap_or("<unknown>"), + record.level(), + record.args() + ) + }); + builder + } + (LogFormat::Json, _) => { + #[derive(Serialize, Deserialize, Debug)] + struct LogRecord<'a> { + timestamp: DateTime<Utc>, + level: Level, + logger: &'a str, + message: String, + module_path: Option<&'a str>, + filename: Option<&'a str>, + lineno: Option<u32>, + } + + let mut builder = env_logger::Builder::new(); + builder.format(|mut buf, record| -> io::Result<()> { + serde_json::to_writer( + &mut buf, + &LogRecord { + timestamp: Utc::now(), + level: record.level(), + logger: record.target(), + message: record.args().to_string(), + module_path: record.module_path(), + filename: record.file(), + lineno: record.line(), + }, + ).map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; + buf.write(b"\n")?; + Ok(()) + }); + builder + } } };