diff --git a/Cargo.lock b/Cargo.lock index dfe9bc14..c402442d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -650,6 +650,16 @@ dependencies = [ "syn", ] +[[package]] +name = "diesel_logger" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a22b1f4804a69ed8954910b2ab30dedc759665e0284e57db95eef4a7b5edffb" +dependencies = [ + "diesel", + "log", +] + [[package]] name = "diesel_migrations" version = "2.0.0" @@ -3180,6 +3190,7 @@ dependencies = [ "data-encoding", "data-url", "diesel", + "diesel_logger", "diesel_migrations", "dotenvy", "email_address", diff --git a/Cargo.toml b/Cargo.toml index 1f3930c7..c667ab90 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,11 @@ vendored_openssl = ["openssl/vendored"] # Enable MiMalloc memory allocator to replace the default malloc # This can improve performance for Alpine builds enable_mimalloc = ["mimalloc"] +# This is a development dependency, and should only be used during development! +# It enables the usage of the diesel_logger crate, which is able to output the generated queries. +# You also need to set an env variable `QUERY_LOGGER=1` to fully activate this so you do not have to re-compile +# if you want to turn off the logging for a specific run. +query_logger = ["diesel_logger"] # Enable unstable features, requires nightly # Currently only used to enable rusts official ip support @@ -70,6 +75,7 @@ serde_json = "1.0.87" # A safe, extensible ORM and Query builder diesel = { version = "2.0.2", features = ["chrono", "r2d2"] } diesel_migrations = "2.0.0" +diesel_logger = { version = "0.2.0", optional = true } # Bundled SQLite libsqlite3-sys = { version = "0.25.2", features = ["bundled"], optional = true } diff --git a/build.rs b/build.rs index 7d0a7bce..1b171fb4 100644 --- a/build.rs +++ b/build.rs @@ -9,20 +9,25 @@ fn main() { println!("cargo:rustc-cfg=mysql"); #[cfg(feature = "postgresql")] println!("cargo:rustc-cfg=postgresql"); + #[cfg(feature = "query_logger")] + println!("cargo:rustc-cfg=query_logger"); #[cfg(not(any(feature = "sqlite", feature = "mysql", feature = "postgresql")))] compile_error!( "You need to enable one DB backend. To build with previous defaults do: cargo build --features sqlite" ); + #[cfg(all(not(debug_assertions), feature = "query_logger"))] + compile_error!("Query Logging is only allowed during development, it is not intented for production usage!"); + // Support $BWRS_VERSION for legacy compatibility, but default to $VW_VERSION. // If neither exist, read from git. let maybe_vaultwarden_version = env::var("VW_VERSION").or_else(|_| env::var("BWRS_VERSION")).or_else(|_| version_from_git_info()); if let Ok(version) = maybe_vaultwarden_version { - println!("cargo:rustc-env=VW_VERSION={}", version); - println!("cargo:rustc-env=CARGO_PKG_VERSION={}", version); + println!("cargo:rustc-env=VW_VERSION={version}"); + println!("cargo:rustc-env=CARGO_PKG_VERSION={version}"); } } @@ -47,29 +52,29 @@ fn version_from_git_info() -> Result { // the current commit doesn't have an associated tag let exact_tag = run(&["git", "describe", "--abbrev=0", "--tags", "--exact-match"]).ok(); if let Some(ref exact) = exact_tag { - println!("cargo:rustc-env=GIT_EXACT_TAG={}", exact); + println!("cargo:rustc-env=GIT_EXACT_TAG={exact}"); } // The last available tag, equal to exact_tag when // the current commit is tagged let last_tag = run(&["git", "describe", "--abbrev=0", "--tags"])?; - println!("cargo:rustc-env=GIT_LAST_TAG={}", last_tag); + println!("cargo:rustc-env=GIT_LAST_TAG={last_tag}"); // The current branch name let branch = run(&["git", "rev-parse", "--abbrev-ref", "HEAD"])?; - println!("cargo:rustc-env=GIT_BRANCH={}", branch); + println!("cargo:rustc-env=GIT_BRANCH={branch}"); // The current git commit hash let rev = run(&["git", "rev-parse", "HEAD"])?; let rev_short = rev.get(..8).unwrap_or_default(); - println!("cargo:rustc-env=GIT_REV={}", rev_short); + println!("cargo:rustc-env=GIT_REV={rev_short}"); // Combined version if let Some(exact) = exact_tag { Ok(exact) } else if &branch != "main" && &branch != "master" { - Ok(format!("{}-{} ({})", last_tag, rev_short, branch)) + Ok(format!("{last_tag}-{rev_short} ({branch})")) } else { - Ok(format!("{}-{}", last_tag, rev_short)) + Ok(format!("{last_tag}-{rev_short}")) } } diff --git a/src/db/mod.rs b/src/db/mod.rs index c2570d9d..b04e7e7d 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -182,12 +182,20 @@ macro_rules! generate_connections { }; } +#[cfg(not(query_logger))] generate_connections! { sqlite: diesel::sqlite::SqliteConnection, mysql: diesel::mysql::MysqlConnection, postgresql: diesel::pg::PgConnection } +#[cfg(query_logger)] +generate_connections! { + sqlite: diesel_logger::LoggingConnection, + mysql: diesel_logger::LoggingConnection, + postgresql: diesel_logger::LoggingConnection +} + impl DbConnType { pub fn from_url(url: &str) -> Result { // Mysql diff --git a/src/main.rs b/src/main.rs index 86bcc36c..08e223b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -171,6 +171,13 @@ fn init_logging(level: log::LevelFilter) -> Result<(), fern::InitError> { log::LevelFilter::Off }; + let diesel_logger_level: log::LevelFilter = + if cfg!(feature = "query_logger") && std::env::var("QUERY_LOGGER").is_ok() { + log::LevelFilter::Debug + } else { + log::LevelFilter::Off + }; + let mut logger = fern::Dispatch::new() .level(level) // Hide unknown certificate errors if using self-signed @@ -191,6 +198,7 @@ fn init_logging(level: log::LevelFilter) -> Result<(), fern::InitError> { .level_for("cookie_store", log::LevelFilter::Off) // Variable level for trust-dns used by reqwest .level_for("trust_dns_proto", trust_dns_level) + .level_for("diesel_logger", diesel_logger_level) .chain(std::io::stdout()); // Enable smtp debug logging only specifically for smtp when need.