From 6dbb97f7f2640d4095c62ef1c5dfa7f72d2d4fe4 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Fri, 9 Jan 2026 23:08:00 +0100 Subject: [PATCH 01/39] migrate to tracing --- Cargo.lock | 133 +++++++++++++- Cargo.toml | 3 + martin/Cargo.toml | 4 +- martin/src/bin/martin-cp.rs | 31 +--- martin/src/bin/martin.rs | 29 +-- martin/src/config/args/root.rs | 2 +- martin/src/config/file/file_config.rs | 4 +- .../src/config/file/tiles/postgres/builder.rs | 2 +- martin/src/lib.rs | 1 + martin/src/logging.rs | 171 ++++++++++++++++++ martin/tests/cors_test.rs | 2 +- martin/tests/mb_server_test.rs | 2 +- martin/tests/pg_function_source_test.rs | 2 +- martin/tests/pg_server_test.rs | 2 +- martin/tests/pg_table_source_test.rs | 2 +- martin/tests/pmt_server_test.rs | 2 +- martin/tests/styles_server_test.rs | 2 +- 17 files changed, 328 insertions(+), 66 deletions(-) create mode 100644 martin/src/logging.rs diff --git a/Cargo.lock b/Cargo.lock index 765ffc8d5..4438eab70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -249,6 +249,17 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.16", + "once_cell", + "version_check", +] + [[package]] name = "ahash" version = "0.8.12" @@ -369,7 +380,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -380,7 +391,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -700,7 +711,7 @@ dependencies = [ "http 0.2.12", "http 1.4.0", "http-body 0.4.6", - "lru", + "lru 0.12.5", "percent-encoding", "regex-lite", "sha2", @@ -2231,7 +2242,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2821,6 +2832,9 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.8", +] [[package]] name = "hashbrown" @@ -2828,7 +2842,7 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash", + "ahash 0.8.12", ] [[package]] @@ -3723,6 +3737,15 @@ dependencies = [ "imgref", ] +[[package]] +name = "lru" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" +dependencies = [ + "hashbrown 0.12.3", +] + [[package]] name = "lru" version = "0.12.5" @@ -3776,7 +3799,6 @@ dependencies = [ "ctor", "dashmap", "enum-display", - "env_logger", "futures", "image", "indoc", @@ -3805,6 +3827,9 @@ dependencies = [ "thiserror 2.0.17", "tilejson", "tokio", + "tracing", + "tracing-log", + "tracing-subscriber", "url", "walkdir", ] @@ -3869,6 +3894,15 @@ dependencies = [ "serde", ] +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + [[package]] name = "matchit" version = "0.8.4" @@ -4085,6 +4119,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "num" version = "0.2.1" @@ -5635,7 +5678,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5648,7 +5691,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.11.0", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -6045,6 +6088,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -6634,7 +6686,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix 1.1.3", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -6735,6 +6787,15 @@ dependencies = [ "syn 2.0.112", ] +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + [[package]] name = "tiff" version = "0.10.3" @@ -7179,6 +7240,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "ahash 0.7.8", + "log", + "lru 0.7.8", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "chrono", + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", ] [[package]] @@ -7414,6 +7521,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "varint-rs" version = "2.2.0" @@ -7617,7 +7730,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f8e8d254e..e11856b54 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,9 @@ base64 = "0.22.1" bit-set = "0.8" brotli = ">=5, <9" bytes = "1" +tracing = { version = "0.1.44", features = ["log"] } +tracing-log = { version = "0.2.0", features = ["interest-cache"] } +tracing-subscriber = { version = "0.3.22", features = ["env-filter", "json", "fmt", "chrono"] } clap = { version = "4", features = ["derive", "unstable-markdown", "wrap_help"] } criterion = { version = "0.8", features = ["async_futures", "async_tokio", "html_reports"] } ctor = "0.6.3" diff --git a/martin/Cargo.toml b/martin/Cargo.toml index b35e2130e..710d80f44 100644 --- a/martin/Cargo.toml +++ b/martin/Cargo.toml @@ -130,7 +130,6 @@ async-trait.workspace = true clap.workspace = true dashmap.workspace = true enum-display = { workspace = true, optional = true } -env_logger.workspace = true futures.workspace = true image = { workspace = true, optional = true } itertools.workspace = true @@ -154,6 +153,9 @@ subst.workspace = true thiserror.workspace = true tilejson.workspace = true tokio = { workspace = true, features = ["io-std"] } +tracing = { workspace = true, features = ["log"] } +tracing-log = { workspace = true, features = ["interest-cache"] } +tracing-subscriber = { workspace = true, features = ["env-filter", "json", "fmt", "chrono"] } url.workspace = true walkdir = { workspace = true, optional = true } diff --git a/martin/src/bin/martin-cp.rs b/martin/src/bin/martin-cp.rs index 54d93332f..849a3a0c1 100644 --- a/martin/src/bin/martin-cp.rs +++ b/martin/src/bin/martin-cp.rs @@ -1,5 +1,5 @@ use std::borrow::Cow; -use std::fmt::{Debug, Display, Formatter, Write}; +use std::fmt::{Debug, Display, Formatter}; use std::num::NonZeroUsize; use std::ops::RangeInclusive; use std::path::PathBuf; @@ -14,9 +14,9 @@ use clap::builder::Styles; use clap::builder::styling::AnsiColor; use futures::TryStreamExt; use futures::stream::{self, StreamExt}; -use log::{debug, error, info, log_enabled, warn}; use martin::config::args::{Args, ExtraArgs, MetaArgs, SrvArgs}; use martin::config::file::{Config, ServerState, read_config}; +use martin::logging::{ensure_martin_core_log_level_matches, init_tracing}; use martin::srv::{DynTileSource, merge_tilejson}; use martin::{MartinError, MartinResult}; use martin_core::config::env::OsEnv; @@ -33,6 +33,7 @@ use tilejson::Bounds; use tokio::sync::mpsc::channel; use tokio::time::Instant; use tokio::try_join; +use tracing::{debug, error, info, warn}; const VERSION: &str = env!("CARGO_PKG_VERSION"); const SAVE_EVERY: Duration = Duration::from_secs(60); @@ -50,7 +51,7 @@ const HELP_STYLES: Styles = Styles::styled() #[command( about = "A tool to bulk copy tiles from any Martin-supported sources into an mbtiles file", version, - after_help = "Use RUST_LOG environment variable to control logging level, e.g. RUST_LOG=debug or RUST_LOG=martin_cp=debug. See https://docs.rs/env_logger/latest/env_logger/index.html#enabling-logging for more information.", + after_help = "Use RUST_LOG environment variable to control logging level, e.g. RUST_LOG=debug or RUST_LOG=martin_cp=debug.\nUse MARTIN_CP_FORMAT environment variable to control output format: compact (default), full, pretty, or json.\nSee https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html for more information.", styles = HELP_STYLES )] pub struct CopierArgs { @@ -576,26 +577,12 @@ async fn init_schema( #[actix_web::main] async fn main() { - let mut log_filter = std::env::var("RUST_LOG").unwrap_or("martin-cp=info".to_string()); - // if we don't have martin_core set, this can hide parts of our logs unintentionally - if log_filter.contains("martin-cp=") - && !log_filter.contains("martin_core=") - && let Some(level) = log_filter - .split(',') - .find_map(|s| s.strip_prefix("martin-cp=")) - { - let level = level.to_string(); - let _ = write!(log_filter, ",martin_core={level}"); - } - env_logger::builder().parse_filters(&log_filter).init(); + let filter = ensure_martin_core_log_level_matches(std::env::var("RUST_LOG").ok(), "martin_cp="); + init_tracing(&filter, std::env::var("MARTIN_CP_FORMAT").ok()); - if let Err(e) = start(CopierArgs::parse()).await { - // Ensure the message is printed, even if the logging is disabled - if log_enabled!(log::Level::Error) { - error!("{e}"); - } else { - eprintln!("{e}"); - } + let args = CopierArgs::parse(); + if let Err(e) = start(args).await { + error!("{e}"); std::process::exit(1); } } diff --git a/martin/src/bin/martin.rs b/martin/src/bin/martin.rs index 8db79ee48..51d3df384 100644 --- a/martin/src/bin/martin.rs +++ b/martin/src/bin/martin.rs @@ -1,12 +1,11 @@ -use std::fmt::Write; - use clap::Parser; -use log::{error, info, log_enabled}; use martin::MartinResult; use martin::config::args::Args; use martin::config::file::{Config, read_config}; +use martin::logging::{ensure_martin_core_log_level_matches, init_tracing}; use martin::srv::new_server; use martin_core::config::env::OsEnv; +use tracing::{error, info}; const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -54,26 +53,12 @@ async fn start(args: Args) -> MartinResult<()> { #[actix_web::main] async fn main() { - let mut log_filter = std::env::var("RUST_LOG").unwrap_or("martin=info".to_string()); - // if we don't have martin_core set, this can hide parts of our logs unintentionally - if log_filter.contains("martin=") - && !log_filter.contains("martin_core=") - && let Some(level) = log_filter - .split(',') - .find_map(|s| s.strip_prefix("martin=")) - { - let level = level.to_string(); - let _ = write!(log_filter, ",martin_core={level}"); - } - env_logger::builder().parse_filters(&log_filter).init(); + let filter = ensure_martin_core_log_level_matches(std::env::var("RUST_LOG").ok(), "martin="); + init_tracing(&filter, std::env::var("MARTIN_FORMAT").ok()); - if let Err(e) = start(Args::parse()).await { - // Ensure the message is printed, even if the logging is disabled - if log_enabled!(log::Level::Error) { - error!("{e}"); - } else { - eprintln!("{e}"); - } + let args = Args::parse(); + if let Err(e) = start(args).await { + error!("{e}"); std::process::exit(1); } } diff --git a/martin/src/config/args/root.rs b/martin/src/config/args/root.rs index 7d76cfeaa..676ca8ca1 100644 --- a/martin/src/config/args/root.rs +++ b/martin/src/config/args/root.rs @@ -34,7 +34,7 @@ const HELP_STYLES: Styles = Styles::styled() #[command( about, version, - after_help = "Use RUST_LOG environment variable to control logging level, e.g. RUST_LOG=debug or RUST_LOG=martin=debug. See https://docs.rs/env_logger/latest/env_logger/index.html#enabling-logging for more information.", + after_help = "Use RUST_LOG environment variable to control logging level, e.g. RUST_LOG=debug or RUST_LOG=martin=debug.\nUse MARTIN_FORMAT environment variable to control output format: compact (default), full, pretty, or json.\nSee https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html for more information.", styles = HELP_STYLES )] pub struct Args { diff --git a/martin/src/config/file/file_config.rs b/martin/src/config/file/file_config.rs index 2b4818aa1..f4c455196 100644 --- a/martin/src/config/file/file_config.rs +++ b/martin/src/config/file/file_config.rs @@ -519,7 +519,7 @@ mod mbtiles_tests { #[tokio::test] async fn test_invalid_path_warns_instead_of_failing() { - let _ = env_logger::builder().is_test(true).try_init(); + let _ = crate::logging::init_tracing_for_tests(); let invalid_path = PathBuf::from("/nonexistent/path/"); let invalid_source = PathBuf::from("/nonexistent/path/to/file.mbtiles"); @@ -552,7 +552,7 @@ mod pmtiles_tests { #[tokio::test] async fn test_invalid_path_warns_instead_of_failing() { - let _ = env_logger::builder().is_test(true).try_init(); + let _ = crate::logging::init_tracing_for_tests(); let invalid_path = PathBuf::from("/nonexistent/path/"); let invalid_source = PathBuf::from("/nonexistent/path/to/file.pmtiles"); diff --git a/martin/src/config/file/tiles/postgres/builder.rs b/martin/src/config/file/tiles/postgres/builder.rs index c56c3b890..d401fca8b 100644 --- a/martin/src/config/file/tiles/postgres/builder.rs +++ b/martin/src/config/file/tiles/postgres/builder.rs @@ -769,7 +769,7 @@ mod tests { use testcontainers_modules::testcontainers::ImageExt; use testcontainers_modules::testcontainers::runners::AsyncRunner; - let _ = env_logger::builder().is_test(true).try_init(); + let _ = crate::logging::init_tracing_for_tests(); let container = Postgres::default() .with_name("postgis/postgis") diff --git a/martin/src/lib.rs b/martin/src/lib.rs index 8764ab0e5..9f143bb38 100644 --- a/martin/src/lib.rs +++ b/martin/src/lib.rs @@ -2,6 +2,7 @@ #![forbid(unsafe_code)] pub mod config; +pub mod logging; #[cfg(feature = "_tiles")] mod source; diff --git a/martin/src/logging.rs b/martin/src/logging.rs new file mode 100644 index 000000000..0b43d31de --- /dev/null +++ b/martin/src/logging.rs @@ -0,0 +1,171 @@ +//! Logging initialization for Martin using `tracing` and `tracing-subscriber`. +//! +//! This module provides static (non-reloadable) logging configuration controlled by: +//! - `RUST_LOG`: Controls log level filtering (standard tracing-subscriber behavior) +//! - `MARTIN_FORMAT`: Controls output format (compact, full, pretty, json) + +use std::str::FromStr; + +use tracing_subscriber::fmt::format::FmtSpan; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; +use tracing_subscriber::{EnvFilter, Layer, Registry}; + +/// Log output format options. +/// +/// Controlled by the `MARTIN_FORMAT` environment variable. +#[derive(Debug, Clone, Copy)] +pub enum LogFormat { + /// Emit human-readable, single-line logs. + /// See [format::Full](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/format/struct.Full.html#example-output) + Full, + + /// A variant of the full-format, optimized for short line lengths (default). + /// See [format::Compact](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/format/struct.Compact.html#example-output) + Compact, + + /// Excessively pretty, multi-line logs for local development/debugging. + /// See [format::Pretty](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/format/struct.Pretty.html#example-output) + Pretty, + + /// Output newline-delimited (structured) JSON logs. + /// See [format::Json](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/format/struct.Json.html#example-output) + Json, +} + +impl Default for LogFormat { + fn default() -> Self { + if cfg!(debug_assertions) { + Self::Pretty + } else { + Self::Compact + } + } +} + +impl FromStr for LogFormat { + type Err = String; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "full" => Ok(Self::Full), + "compact" => Ok(Self::Compact), + "pretty" | "verbose" => Ok(Self::Pretty), + "json" | "jsonl" => Ok(Self::Json), + _ => Err(format!( + "Invalid log format '{s}'. Valid options: full, compact, pretty, json" + )), + } + } +} + +/// Initialize the global tracing subscriber for the given filter and format. +/// +/// This function: +/// 1. Bridges `log` records into `tracing` events for compatibility +/// 2. Uses the provided filter string for log filtering +/// 3. Uses the provided format for output +/// 4. Sets up the global tracing subscriber +pub fn init_tracing(filter: &str, format: Option) { + // Initialize log -> tracing bridge (ignore if already initialized) + let _ = tracing_log::LogTracer::builder() + .with_interest_cache(tracing_log::InterestCacheConfig::default()) + .init().expect("failed to intialise the global log -> tracing bridge"); + + // Set up the filter from the provided string + let env_filter = EnvFilter::from_str(filter).unwrap_or_else(|_| { + eprintln!("Warning: Invalid filter string '{filter}' passed. Since you passed a filter, you likely want to debug us, so we set the filter to debug"); + EnvFilter::new("debug") + }); + + // Build and install the subscriber based on format + let format = format + .and_then(|s| { + s.parse::() + .map_err(|e| { + eprintln!("Warning: {e}"); + eprintln!("Falling back to default format (compact)"); + }) + .ok() + }) + .unwrap_or_default(); + match format { + LogFormat::Full => { + let fmt_layer = tracing_subscriber::fmt::layer() + .with_span_events(FmtSpan::NONE) + .with_filter(env_filter); + + Registry::default().with(fmt_layer).init() + } + LogFormat::Compact => { + let fmt_layer = tracing_subscriber::fmt::layer() + .compact() + .with_span_events(FmtSpan::NONE) + .with_filter(env_filter); + + Registry::default().with(fmt_layer).init() + } + LogFormat::Pretty => { + let fmt_layer = tracing_subscriber::fmt::layer() + .pretty() + .with_filter(env_filter); + + Registry::default().with(fmt_layer).init() + } + LogFormat::Json => { + let fmt_layer = tracing_subscriber::fmt::layer() + .json() + .with_span_events(FmtSpan::NONE) + .with_filter(env_filter); + + Registry::default().with(fmt_layer).init() + } + }; +} + +pub fn ensure_martin_core_log_level_matches( + env_filter: Option, + replacement: &'static str, +) -> String { + if let Some(rust_log) = env_filter { + // If RUST_LOG is set and contains replacement (e.g., martin=) but not martin_core=, mirror the level + if rust_log.contains(replacement) && !rust_log.contains("martin_core=") { + if let Some(level) = rust_log + .split(',') + .find_map(|s| s.strip_prefix(replacement)) + { + format!("{rust_log},martin_core={level}") + } else { + rust_log + } + } else { + rust_log + } + } else { + format!("{replacement}info,martin_core=info") + } +} + +/// Initialize tracing for tests. +/// +/// This is a simplified version that: +/// - Doesn't panic if already initialized (returns Ok/Err) +/// - Uses compact format +/// - Sets `is_test(true)` to avoid interference between tests +pub fn init_tracing_for_tests() -> Result<(), Box> { + use tracing_subscriber::fmt; + + let env_filter = EnvFilter::try_from_default_env() + .or_else(|_| EnvFilter::from_str("info")) + .unwrap(); + + let subscriber = fmt() + .compact() + .with_test_writer() + .with_env_filter(env_filter) + .with_span_events(FmtSpan::NONE) + .finish(); + + tracing::subscriber::set_global_default(subscriber)?; + Ok(()) +} diff --git a/martin/tests/cors_test.rs b/martin/tests/cors_test.rs index 7dedb2e37..e6486ce95 100644 --- a/martin/tests/cors_test.rs +++ b/martin/tests/cors_test.rs @@ -12,7 +12,7 @@ pub use utils::*; #[ctor] fn init() { - let _ = env_logger::builder().is_test(true).try_init(); + let _ = martin::logging::init_tracing_for_tests(); } macro_rules! create_app { diff --git a/martin/tests/mb_server_test.rs b/martin/tests/mb_server_test.rs index b2499f3fd..b885cf7f7 100644 --- a/martin/tests/mb_server_test.rs +++ b/martin/tests/mb_server_test.rs @@ -16,7 +16,7 @@ pub use utils::*; #[ctor] fn init() { - let _ = env_logger::builder().is_test(true).try_init(); + let _ = martin::logging::init_tracing_for_tests(); } macro_rules! create_app { diff --git a/martin/tests/pg_function_source_test.rs b/martin/tests/pg_function_source_test.rs index bde703117..a39595f29 100644 --- a/martin/tests/pg_function_source_test.rs +++ b/martin/tests/pg_function_source_test.rs @@ -10,7 +10,7 @@ pub use utils::*; #[ctor] fn init() { - let _ = env_logger::builder().is_test(true).try_init(); + let _ = martin::logging::init_tracing_for_tests(); } #[actix_rt::test] diff --git a/martin/tests/pg_server_test.rs b/martin/tests/pg_server_test.rs index 08e565e6e..17b696e07 100644 --- a/martin/tests/pg_server_test.rs +++ b/martin/tests/pg_server_test.rs @@ -15,7 +15,7 @@ pub use utils::*; #[ctor] fn init() { - let _ = env_logger::builder().is_test(true).try_init(); + let _ = martin::logging::init_tracing_for_tests(); } macro_rules! create_app { diff --git a/martin/tests/pg_table_source_test.rs b/martin/tests/pg_table_source_test.rs index 8e48a91ad..a3bae588f 100644 --- a/martin/tests/pg_table_source_test.rs +++ b/martin/tests/pg_table_source_test.rs @@ -9,7 +9,7 @@ pub use utils::*; #[ctor] fn init() { - let _ = env_logger::builder().is_test(true).try_init(); + let _ = martin::logging::init_tracing_for_tests(); } #[actix_rt::test] diff --git a/martin/tests/pmt_server_test.rs b/martin/tests/pmt_server_test.rs index 4317e3ea7..5608f66d0 100644 --- a/martin/tests/pmt_server_test.rs +++ b/martin/tests/pmt_server_test.rs @@ -14,7 +14,7 @@ pub use utils::*; #[ctor] fn init() { - let _ = env_logger::builder().is_test(true).try_init(); + let _ = martin::logging::init_tracing_for_tests(); } macro_rules! create_app { diff --git a/martin/tests/styles_server_test.rs b/martin/tests/styles_server_test.rs index 8de8889e3..8d9fd04b3 100644 --- a/martin/tests/styles_server_test.rs +++ b/martin/tests/styles_server_test.rs @@ -13,7 +13,7 @@ pub use utils::*; #[ctor] fn init() { - let _ = env_logger::builder().is_test(true).try_init(); + let _ = martin::logging::init_tracing_for_tests(); } macro_rules! create_app { From 0381c27f9b712f591b54831093e5cf3b92e628fe Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Fri, 9 Jan 2026 23:37:03 +0100 Subject: [PATCH 02/39] remove ctor --- Cargo.lock | 55 ++++++++++--------------- Cargo.toml | 2 +- martin/Cargo.toml | 2 +- martin/src/logging.rs | 3 +- martin/tests/cors_test.rs | 13 +++--- martin/tests/mb_server_test.rs | 19 ++++++--- martin/tests/pg_function_source_test.rs | 5 --- martin/tests/pg_server_test.rs | 24 ++++++++--- martin/tests/pg_table_source_test.rs | 5 --- martin/tests/pmt_server_test.rs | 13 +++--- martin/tests/styles_server_test.rs | 11 ++--- mbtiles/Cargo.toml | 1 - mbtiles/tests/copy.rs | 11 ++--- mbtiles/tests/validate.rs | 8 ++-- 14 files changed, 89 insertions(+), 83 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4438eab70..e306b7a66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1751,22 +1751,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "ctor" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "424e0138278faeb2b401f174ad17e715c829512d74f3d1e81eb43365c2e0590e" -dependencies = [ - "ctor-proc-macro", - "dtor", -] - -[[package]] -name = "ctor-proc-macro" -version = "0.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" - [[package]] name = "cxx" version = "1.0.192" @@ -2069,21 +2053,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "dtor" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "404d02eeb088a82cfd873006cb713fe411306c7d182c344905e101fb1167d301" -dependencies = [ - "dtor-proc-macro", -] - -[[package]] -name = "dtor-proc-macro" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" - [[package]] name = "dunce" version = "1.0.5" @@ -3796,7 +3765,6 @@ dependencies = [ "async-trait", "clap", "criterion", - "ctor", "dashmap", "enum-display", "futures", @@ -3830,6 +3798,7 @@ dependencies = [ "tracing", "tracing-log", "tracing-subscriber", + "tracing-test", "url", "walkdir", ] @@ -3937,7 +3906,6 @@ dependencies = [ "actix-rt", "anyhow", "clap", - "ctor", "enum-display", "env_logger", "flume 0.12.0", @@ -7288,6 +7256,27 @@ dependencies = [ "tracing-serde", ] +[[package]] +name = "tracing-test" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "557b891436fe0d5e0e363427fc7f217abf9ccd510d5136549847bdcbcd011d68" +dependencies = [ + "tracing-core", + "tracing-subscriber", + "tracing-test-macro", +] + +[[package]] +name = "tracing-test-macro" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" +dependencies = [ + "quote", + "syn 2.0.112", +] + [[package]] name = "try-lock" version = "0.2.5" diff --git a/Cargo.toml b/Cargo.toml index e11856b54..252766987 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,6 @@ tracing-log = { version = "0.2.0", features = ["interest-cache"] } tracing-subscriber = { version = "0.3.22", features = ["env-filter", "json", "fmt", "chrono"] } clap = { version = "4", features = ["derive", "unstable-markdown", "wrap_help"] } criterion = { version = "0.8", features = ["async_futures", "async_tokio", "html_reports"] } -ctor = "0.6.3" dashmap = { version = "6.1.0", features = ["serde", "inline", "rayon"] } deadpool-postgres = "0.14" enum-display = "0.2" @@ -107,6 +106,7 @@ tiff = "0.10.1" tilejson = "0.4" tokio = { version = "1", features = ["macros"] } tokio-postgres-rustls = "0.13" +tracing-test = "0.2" url = "2.5" walkdir = "2.5.0" xxhash-rust = { version = "0.8", features = ["xxh3"] } diff --git a/martin/Cargo.toml b/martin/Cargo.toml index 710d80f44..2b1c0f41b 100644 --- a/martin/Cargo.toml +++ b/martin/Cargo.toml @@ -166,12 +166,12 @@ walkdir = { workspace = true, optional = true } [dev-dependencies] approx.workspace = true criterion.workspace = true -ctor.workspace = true indoc.workspace = true insta = { workspace = true, features = ["json", "yaml", "redactions"] } rstest.workspace = true tempfile.workspace = true testcontainers-modules.workspace = true +tracing-test.workspace = true [lints] workspace = true diff --git a/martin/src/logging.rs b/martin/src/logging.rs index 0b43d31de..0647c40a6 100644 --- a/martin/src/logging.rs +++ b/martin/src/logging.rs @@ -70,7 +70,8 @@ pub fn init_tracing(filter: &str, format: Option) { // Initialize log -> tracing bridge (ignore if already initialized) let _ = tracing_log::LogTracer::builder() .with_interest_cache(tracing_log::InterestCacheConfig::default()) - .init().expect("failed to intialise the global log -> tracing bridge"); + .init() + .expect("failed to intialise the global log -> tracing bridge"); // Set up the filter from the provided string let env_filter = EnvFilter::from_str(filter).unwrap_or_else(|_| { diff --git a/martin/tests/cors_test.rs b/martin/tests/cors_test.rs index e6486ce95..d0a9ddf3f 100644 --- a/martin/tests/cors_test.rs +++ b/martin/tests/cors_test.rs @@ -4,17 +4,11 @@ use actix_http::Method; use actix_http::header::ACCESS_CONTROL_MAX_AGE; use actix_web::http::header::{ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_REQUEST_METHOD, ORIGIN}; use actix_web::test::{TestRequest, call_service}; -use ctor::ctor; use indoc::formatdoc; use mbtiles::temp_named_mbtiles; pub mod utils; pub use utils::*; -#[ctor] -fn init() { - let _ = martin::logging::init_tracing_for_tests(); -} - macro_rules! create_app { ($sources:expr) => {{ let cfg = mock_cfg($sources); @@ -47,6 +41,7 @@ macro_rules! create_app { } #[actix_rt::test] +#[traced_test::traced_test] async fn test_cors_explicit_disabled() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = temp_named_mbtiles("test_cors_explicit_disabled", script).await; @@ -72,6 +67,7 @@ async fn test_cors_explicit_disabled() { } #[actix_rt::test] +#[traced_test::traced_test] async fn test_cors_implicit_enabled() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = temp_named_mbtiles("test_cors_implicit_enabled", script).await; @@ -95,6 +91,7 @@ async fn test_cors_implicit_enabled() { } #[actix_rt::test] +#[traced_test::traced_test] async fn test_cors_explicit_enabled() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = temp_named_mbtiles("test_cors_explicit_enabled", script).await; @@ -119,6 +116,7 @@ async fn test_cors_explicit_enabled() { } #[actix_rt::test] +#[traced_test::traced_test] async fn test_cors_specific_origin() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = temp_named_mbtiles("test_cors_specific_origin", script).await; @@ -144,6 +142,7 @@ async fn test_cors_specific_origin() { } #[actix_rt::test] +#[traced_test::traced_test] async fn test_cors_no_header_on_mismatch() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = temp_named_mbtiles("test_cors_no_header_on_mismatch", script).await; @@ -171,6 +170,7 @@ async fn test_cors_no_header_on_mismatch() { } #[actix_rt::test] +#[traced_test::traced_test] async fn test_cors_preflight_request_with_max_age() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = @@ -205,6 +205,7 @@ async fn test_cors_preflight_request_with_max_age() { } #[actix_rt::test] +#[traced_test::traced_test] async fn test_cors_preflight_request_without_max_age() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = diff --git a/martin/tests/mb_server_test.rs b/martin/tests/mb_server_test.rs index b885cf7f7..486eba625 100644 --- a/martin/tests/mb_server_test.rs +++ b/martin/tests/mb_server_test.rs @@ -14,11 +14,6 @@ use tilejson::TileJSON; pub mod utils; pub use utils::*; -#[ctor] -fn init() { - let _ = martin::logging::init_tracing_for_tests(); -} - macro_rules! create_app { ($sources:expr) => {{ let state = mock_sources(mock_cfg($sources)).await.0; @@ -90,6 +85,7 @@ async fn config( } #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_catalog() { let (config, _conns) = config("mbt_get_catalog").await; let app = create_app!(&config); @@ -121,6 +117,7 @@ async fn mbt_get_catalog() { } #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_catalog_gzip() { let (config, _conns) = config("mbt_get_catalog_gzip").await; let app = create_app!(&config); @@ -154,6 +151,7 @@ async fn mbt_get_catalog_gzip() { } #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_tilejson() { let (config, _conns) = config("mbt_get_tilejson").await; let app = create_app!(&config); @@ -168,6 +166,7 @@ async fn mbt_get_tilejson() { } #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_tilejson_gzip() { let (config, _conns) = config("mbt_get_tilejson_gzip").await; let app = create_app!(&config); @@ -184,6 +183,7 @@ async fn mbt_get_tilejson_gzip() { } #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_raster() { let (config, _conns) = config("mbt_get_raster").await; let app = create_app!(&config); @@ -198,6 +198,7 @@ async fn mbt_get_raster() { /// get a raster tile with accepted gzip enc, but should still be non-gzipped #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_raster_gzip() { let (config, _conns) = config("mbt_get_raster_gzip").await; let app = create_app!(&config); @@ -212,6 +213,7 @@ async fn mbt_get_raster_gzip() { } #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_mvt() { let (config, _conns) = config("mbt_get_mvt").await; let app = create_app!(&config); @@ -232,6 +234,7 @@ async fn mbt_get_mvt() { /// get an MVT tile with accepted gzip enc #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_mvt_gzip() { let (config, _conns) = config("mbt_get_mvt_gzip").await; let app = create_app!(&config); @@ -252,6 +255,7 @@ async fn mbt_get_mvt_gzip() { /// get an MVT tile with accepted brotli enc #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_mvt_brotli() { let (config, _conns) = config("mbt_get_mvt_brotli").await; let app = create_app!(&config); @@ -272,6 +276,7 @@ async fn mbt_get_mvt_brotli() { /// get an uncompressed MVT tile #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_raw_mvt() { let (config, _conns) = config("mbt_get_raw_mvt").await; let app = create_app!(&config); @@ -289,6 +294,7 @@ async fn mbt_get_raw_mvt() { /// get an uncompressed MVT tile with accepted gzip #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_raw_mvt_gzip() { let (config, _conns) = config("mbt_get_raw_mvt_gzip").await; let app = create_app!(&config); @@ -311,6 +317,7 @@ async fn mbt_get_raw_mvt_gzip() { /// get an uncompressed MVT tile with accepted both gzip and brotli enc #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_raw_mvt_gzip_br() { let (config, _conns) = config("mbt_get_raw_mvt_gzip_br").await; let app = create_app!(&config); @@ -334,6 +341,7 @@ async fn mbt_get_raw_mvt_gzip_br() { /// get a JSON tile #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_json() { let (config, _conns) = config("mbt_get_json").await; let app = create_app!(&config); @@ -351,6 +359,7 @@ async fn mbt_get_json() { /// get a JSON tile with accepted gzip #[actix_rt::test] +#[traced_test::traced_test] async fn mbt_get_json_gzip() { let (config, _conns) = config("mbt_get_json_gzip").await; let app = create_app!(&config); diff --git a/martin/tests/pg_function_source_test.rs b/martin/tests/pg_function_source_test.rs index a39595f29..e704ed664 100644 --- a/martin/tests/pg_function_source_test.rs +++ b/martin/tests/pg_function_source_test.rs @@ -8,11 +8,6 @@ use martin_tile_utils::TileCoord; pub mod utils; pub use utils::*; -#[ctor] -fn init() { - let _ = martin::logging::init_tracing_for_tests(); -} - #[actix_rt::test] async fn function_source_tilejson() { let mock = mock_sources(mock_pgcfg("connection_string: $DATABASE_URL")).await; diff --git a/martin/tests/pg_server_test.rs b/martin/tests/pg_server_test.rs index 17b696e07..ceb8ed61b 100644 --- a/martin/tests/pg_server_test.rs +++ b/martin/tests/pg_server_test.rs @@ -13,11 +13,6 @@ use tilejson::TileJSON; pub mod utils; pub use utils::*; -#[ctor] -fn init() { - let _ = martin::logging::init_tracing_for_tests(); -} - macro_rules! create_app { ($sources:expr) => {{ let cfg = mock_cfg(indoc::indoc!($sources)); @@ -43,6 +38,7 @@ fn test_get(path: &str) -> Request { } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_catalog() { let app = create_app! { " postgres: @@ -151,6 +147,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_table_source_ok() { let app = create_app! { " on_invalid: warn @@ -187,6 +184,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_table_source_rewrite() { let app = create_app! { " postgres: @@ -228,6 +226,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_table_source_tile_ok() { let app = create_app! { " postgres: @@ -318,6 +317,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_table_source_multiple_geom_tile_ok() { let app = create_app! { " postgres: @@ -408,6 +408,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_table_source_tile_minmax_zoom_ok() { let app = create_app! { " postgres: @@ -516,6 +517,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_function_tiles() { let app = create_app! { " postgres: @@ -548,6 +550,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_composite_source_ok() { let app = create_app! { " postgres: @@ -637,6 +640,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_composite_source_tile_ok() { let app = create_app! { " postgres: @@ -727,6 +731,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_composite_source_tile_minmax_zoom_ok() { let app = create_app! { " postgres: @@ -793,6 +798,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_null_functions() { let app = create_app! { " postgres: @@ -813,6 +819,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_function_source_ok() { let app = create_app! { " postgres: @@ -857,6 +864,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_function_source_ok_rewrite() { let app = create_app! { " postgres: @@ -875,6 +883,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_function_source_ok_rewrite_all() { let app = create_app! { " postgres: @@ -895,6 +904,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_function_source_tile_ok() { let app = create_app! { " postgres: @@ -907,6 +917,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_function_source_tile_minmax_zoom_ok() { let app = create_app! {" postgres: @@ -965,6 +976,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_function_source_query_params_ok() { let app = create_app! { " postgres: @@ -981,6 +993,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_get_health_returns_ok() { let app = create_app! { " postgres: @@ -993,6 +1006,7 @@ postgres: } #[actix_rt::test] +#[traced_test::traced_test] async fn pg_tables_feature_id() { let cfg = mock_pgcfg(indoc! {" connection_string: $DATABASE_URL diff --git a/martin/tests/pg_table_source_test.rs b/martin/tests/pg_table_source_test.rs index a3bae588f..6111b4798 100644 --- a/martin/tests/pg_table_source_test.rs +++ b/martin/tests/pg_table_source_test.rs @@ -7,11 +7,6 @@ use martin_tile_utils::TileCoord; pub mod utils; pub use utils::*; -#[ctor] -fn init() { - let _ = martin::logging::init_tracing_for_tests(); -} - #[actix_rt::test] async fn table_source() { let mock = mock_sources(mock_pgcfg("connection_string: $DATABASE_URL")).await; diff --git a/martin/tests/pmt_server_test.rs b/martin/tests/pmt_server_test.rs index 5608f66d0..75286c6af 100644 --- a/martin/tests/pmt_server_test.rs +++ b/martin/tests/pmt_server_test.rs @@ -12,11 +12,6 @@ use tilejson::TileJSON; pub mod utils; pub use utils::*; -#[ctor] -fn init() { - let _ = martin::logging::init_tracing_for_tests(); -} - macro_rules! create_app { ($sources:expr) => {{ let state = mock_sources(mock_cfg($sources)).await.0; @@ -50,6 +45,7 @@ const CONFIG: &str = indoc! {" "}; #[actix_rt::test] +#[traced_test::traced_test] async fn pmt_get_catalog() { let path = "pmtiles: ../tests/fixtures/pmtiles/stamen_toner__raster_CC-BY+ODbL_z3.pmtiles"; let app = create_app! { path }; @@ -69,6 +65,7 @@ async fn pmt_get_catalog() { } #[actix_rt::test] +#[traced_test::traced_test] async fn pmt_get_catalog_gzip() { let app = create_app! { CONFIG }; let accept = (ACCEPT_ENCODING, "gzip"); @@ -93,6 +90,7 @@ async fn pmt_get_catalog_gzip() { } #[actix_rt::test] +#[traced_test::traced_test] async fn pmt_get_tilejson() { let app = create_app! { CONFIG }; let req = test_get("/p_png").to_request(); @@ -106,6 +104,7 @@ async fn pmt_get_tilejson() { } #[actix_rt::test] +#[traced_test::traced_test] async fn pmt_get_tilejson_gzip() { let app = create_app! { CONFIG }; let accept = (ACCEPT_ENCODING, "gzip"); @@ -121,6 +120,7 @@ async fn pmt_get_tilejson_gzip() { } #[actix_rt::test] +#[traced_test::traced_test] async fn pmt_get_raster() { let app = create_app! { CONFIG }; let req = test_get("/p_png/0/0/0").to_request(); @@ -134,6 +134,7 @@ async fn pmt_get_raster() { /// get a raster tile with accepted gzip enc, but should still be non-gzipped #[actix_rt::test] +#[traced_test::traced_test] async fn pmt_get_raster_gzip() { let app = create_app! { CONFIG }; let accept = (ACCEPT_ENCODING, "gzip"); @@ -147,6 +148,7 @@ async fn pmt_get_raster_gzip() { } #[actix_rt::test] +#[traced_test::traced_test] async fn pmt_get_tilejson_s3() { let app = create_app! { CONFIG }; let req = test_get("/s3").to_request(); @@ -161,6 +163,7 @@ async fn pmt_get_tilejson_s3() { } #[actix_rt::test] +#[traced_test::traced_test] async fn pmt_get_tile_s3() { let app = create_app! { CONFIG }; let req = test_get("/s3/0/0/0").to_request(); diff --git a/martin/tests/styles_server_test.rs b/martin/tests/styles_server_test.rs index 8d9fd04b3..e125fb93e 100644 --- a/martin/tests/styles_server_test.rs +++ b/martin/tests/styles_server_test.rs @@ -11,11 +11,6 @@ use serde_json::Value; pub mod utils; pub use utils::*; -#[ctor] -fn init() { - let _ = martin::logging::init_tracing_for_tests(); -} - macro_rules! create_app { ($sources:expr) => {{ let state = mock_sources(mock_cfg($sources)).await.0; @@ -51,6 +46,7 @@ const CONFIG_STYLES: &str = indoc! {" "}; #[actix_rt::test] +#[traced_test::traced_test] async fn catalog_multiple_styles() { let app = create_app! { CONFIG_STYLES }; @@ -71,6 +67,7 @@ async fn catalog_multiple_styles() { } #[actix_rt::test] +#[traced_test::traced_test] async fn style_json_not_found() { let app = create_app! { CONFIG_STYLES }; @@ -99,6 +96,7 @@ mod render_tests { #[case::single_style_corner(CONFIG_STYLES, "/style/maplibre_demo/1/1/0.png")] #[case::single_style_mid_zoom(CONFIG_STYLES, "/style/maplibre_demo/5/15/15.png")] #[tokio::test] +#[traced_test::traced_test] async fn render_tile_png(#[case] config: &str, #[case] path: &str) { let app = create_app! { config }; @@ -119,6 +117,7 @@ mod render_tests { } #[tokio::test] +#[traced_test::traced_test] async fn render_tile_not_found_style() { let app = create_app! { CONFIG_STYLES }; @@ -131,6 +130,7 @@ mod render_tests { } #[tokio::test] +#[traced_test::traced_test] async fn render_tile_impossible() { let app = create_app! { CONFIG_STYLES }; @@ -144,6 +144,7 @@ mod render_tests { } #[tokio::test] +#[traced_test::traced_test] async fn render_concurrent_requests() { let app = create_app! { CONFIG_STYLES }; diff --git a/mbtiles/Cargo.toml b/mbtiles/Cargo.toml index a6265a875..4f492e733 100644 --- a/mbtiles/Cargo.toml +++ b/mbtiles/Cargo.toml @@ -51,7 +51,6 @@ xxhash-rust.workspace = true [dev-dependencies] # For testing, might as well use the same async framework as the Martin itself actix-rt.workspace = true -ctor.workspace = true env_logger.workspace = true insta = { workspace = true, features = ["toml", "yaml"] } pretty_assertions.workspace = true diff --git a/mbtiles/tests/copy.rs b/mbtiles/tests/copy.rs index 41b1755e4..b46084914 100644 --- a/mbtiles/tests/copy.rs +++ b/mbtiles/tests/copy.rs @@ -84,11 +84,6 @@ const METADATA_V2: &str = " , ('md-new', 'value - new') ;"; -#[ctor] -fn init() { - let _ = env_logger::builder().is_test(true).try_init(); -} - fn path(mbt: &Mbtiles) -> PathBuf { PathBuf::from(mbt.filepath()) } @@ -414,6 +409,7 @@ fn databases() -> Databases { } #[tokio::test] +#[traced_test::traced_test] async fn update() -> MbtResult<()> { let (mbt, mut cn) = new_file_no_hash!(databases, Flat, METADATA_V1, TILES_V1, "update"); mbt.update_metadata(&mut cn, UpdateZoomType::Reset).await?; @@ -426,6 +422,7 @@ async fn update() -> MbtResult<()> { #[rstest] #[trace] #[tokio::test(flavor = "multi_thread")] +#[traced_test::traced_test] async fn convert( #[values(Flat, FlatWithHash, Normalized)] frm_type: MbtTypeCli, #[values(Flat, FlatWithHash, Normalized)] dst_type: MbtTypeCli, @@ -513,6 +510,7 @@ async fn convert( #[rstest] #[trace] #[tokio::test(flavor = "multi_thread")] +#[traced_test::traced_test] async fn diff_and_patch( #[values(Flat, FlatWithHash, Normalized)] a_type: MbtTypeCli, #[values(Flat, FlatWithHash, Normalized)] b_type: MbtTypeCli, @@ -598,6 +596,7 @@ async fn diff_and_patch( #[trace] #[ignore = "test used to run for a while, and then became too complicated to maintain and got out of whack. TODO: bring it back or deleete"] #[tokio::test(flavor = "multi_thread")] +#[traced_test::traced_test] async fn diff_and_patch_bsdiff( #[values(Flat, FlatWithHash)] a_type: MbtTypeCli, #[values(Flat, FlatWithHash)] b_type: MbtTypeCli, @@ -656,6 +655,7 @@ async fn diff_and_patch_bsdiff( #[rstest] #[trace] #[tokio::test(flavor = "multi_thread")] +#[traced_test::traced_test] async fn patch_on_copy( #[values(Flat, FlatWithHash, Normalized)] v1_type: MbtTypeCli, #[values(Flat, FlatWithHash, Normalized)] dif_type: MbtTypeCli, @@ -687,6 +687,7 @@ async fn patch_on_copy( /// A simple tester to run specific values #[tokio::test(flavor = "multi_thread")] #[ignore = "this test is for debugging only, and should be disabled"] +#[traced_test::traced_test] async fn test_one() { // This will cause an error if ran together with other tests let db = databases(); diff --git a/mbtiles/tests/validate.rs b/mbtiles/tests/validate.rs index 0fb75388f..b1ddc16d6 100644 --- a/mbtiles/tests/validate.rs +++ b/mbtiles/tests/validate.rs @@ -7,11 +7,6 @@ use mbtiles::{Mbtiles, create_metadata_table}; use rstest::rstest; use sqlx::{Executor as _, SqliteConnection, query}; -#[ctor::ctor] -fn init() { - let _ = env_logger::builder().is_test(true).try_init(); -} - async fn new(values: &str) -> (Mbtiles, SqliteConnection) { let mbtiles = Mbtiles::new(":memory:").unwrap(); let mut conn = mbtiles.open().await.unwrap(); @@ -66,6 +61,7 @@ macro_rules! err { #[case("0, 0, ", ", NULL")] // test tile_row #[trace] #[actix_rt::test] +#[traced_test::traced_test] async fn integers(#[case] prefix: &str, #[case] suffix: &str) { ok!("{prefix} 0 {suffix}"); @@ -90,6 +86,7 @@ async fn integers(#[case] prefix: &str, #[case] suffix: &str) { #[case("0, ", ", NULL")] // test tile_row #[trace] #[actix_rt::test] +#[traced_test::traced_test] async fn tile_coordinate(#[case] prefix: &str, #[case] suffix: &str) { ok!("0, {prefix} 0 {suffix}"); ok!("1, {prefix} 1 {suffix}"); @@ -111,6 +108,7 @@ async fn tile_coordinate(#[case] prefix: &str, #[case] suffix: &str) { } #[actix_rt::test] +#[traced_test::traced_test] async fn tile_data() { ok!("0, 0, 0, NULL"); ok!("0, 0, 0, CAST('' AS BLOB)"); From a3184cf7ab438d4b388627247f5f0162460b0c32 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 00:14:21 +0100 Subject: [PATCH 03/39] fmt --- martin/tests/styles_server_test.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/martin/tests/styles_server_test.rs b/martin/tests/styles_server_test.rs index e125fb93e..006b67598 100644 --- a/martin/tests/styles_server_test.rs +++ b/martin/tests/styles_server_test.rs @@ -96,7 +96,7 @@ mod render_tests { #[case::single_style_corner(CONFIG_STYLES, "/style/maplibre_demo/1/1/0.png")] #[case::single_style_mid_zoom(CONFIG_STYLES, "/style/maplibre_demo/5/15/15.png")] #[tokio::test] -#[traced_test::traced_test] + #[traced_test::traced_test] async fn render_tile_png(#[case] config: &str, #[case] path: &str) { let app = create_app! { config }; @@ -117,7 +117,7 @@ mod render_tests { } #[tokio::test] -#[traced_test::traced_test] + #[traced_test::traced_test] async fn render_tile_not_found_style() { let app = create_app! { CONFIG_STYLES }; @@ -130,7 +130,7 @@ mod render_tests { } #[tokio::test] -#[traced_test::traced_test] + #[traced_test::traced_test] async fn render_tile_impossible() { let app = create_app! { CONFIG_STYLES }; @@ -144,7 +144,7 @@ mod render_tests { } #[tokio::test] -#[traced_test::traced_test] + #[traced_test::traced_test] async fn render_concurrent_requests() { let app = create_app! { CONFIG_STYLES }; From 6334750679cfadbef51514d35f4722398f3e0f4d Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 00:16:08 +0100 Subject: [PATCH 04/39] slight optimisation --- Cargo.toml | 6 +-- martin/Cargo.toml | 2 +- martin/src/bin/martin.rs | 2 +- martin/src/logging.rs | 97 ++++++++++++++++++++++------------------ 4 files changed, 59 insertions(+), 48 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 252766987..1ea2bf0ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,9 +46,6 @@ base64 = "0.22.1" bit-set = "0.8" brotli = ">=5, <9" bytes = "1" -tracing = { version = "0.1.44", features = ["log"] } -tracing-log = { version = "0.2.0", features = ["interest-cache"] } -tracing-subscriber = { version = "0.3.22", features = ["env-filter", "json", "fmt", "chrono"] } clap = { version = "4", features = ["derive", "unstable-markdown", "wrap_help"] } criterion = { version = "0.8", features = ["async_futures", "async_tokio", "html_reports"] } dashmap = { version = "6.1.0", features = ["serde", "inline", "rayon"] } @@ -106,6 +103,9 @@ tiff = "0.10.1" tilejson = "0.4" tokio = { version = "1", features = ["macros"] } tokio-postgres-rustls = "0.13" +tracing = "0.1.44" +tracing-log = { version = "0.2.0", features = ["interest-cache"] } +tracing-subscriber = { version = "0.3", default-features = false } tracing-test = "0.2" url = "2.5" walkdir = "2.5.0" diff --git a/martin/Cargo.toml b/martin/Cargo.toml index 2b1c0f41b..e39b0507e 100644 --- a/martin/Cargo.toml +++ b/martin/Cargo.toml @@ -155,7 +155,7 @@ tilejson.workspace = true tokio = { workspace = true, features = ["io-std"] } tracing = { workspace = true, features = ["log"] } tracing-log = { workspace = true, features = ["interest-cache"] } -tracing-subscriber = { workspace = true, features = ["env-filter", "json", "fmt", "chrono"] } +tracing-subscriber = { workspace = true, default-features=false, features = ["env-filter", "json", "fmt","std", "ansi", "chrono"] } url.workspace = true walkdir = { workspace = true, optional = true } diff --git a/martin/src/bin/martin.rs b/martin/src/bin/martin.rs index 51d3df384..024961697 100644 --- a/martin/src/bin/martin.rs +++ b/martin/src/bin/martin.rs @@ -51,7 +51,7 @@ async fn start(args: Args) -> MartinResult<()> { server.await } -#[actix_web::main] +#[tokio::main] async fn main() { let filter = ensure_martin_core_log_level_matches(std::env::var("RUST_LOG").ok(), "martin="); init_tracing(&filter, std::env::var("MARTIN_FORMAT").ok()); diff --git a/martin/src/logging.rs b/martin/src/logging.rs index 0647c40a6..016e21f21 100644 --- a/martin/src/logging.rs +++ b/martin/src/logging.rs @@ -6,10 +6,8 @@ use std::str::FromStr; +use tracing_subscriber::EnvFilter; use tracing_subscriber::fmt::format::FmtSpan; -use tracing_subscriber::layer::SubscriberExt; -use tracing_subscriber::util::SubscriberInitExt; -use tracing_subscriber::{EnvFilter, Layer, Registry}; /// Log output format options. /// @@ -33,6 +31,39 @@ pub enum LogFormat { Json, } +impl LogFormat { + pub fn init(self, env_filter: EnvFilter) { + match self { + LogFormat::Full => { + tracing_subscriber::fmt() + .with_span_events(FmtSpan::NONE) + .with_env_filter(env_filter) + .init(); + } + LogFormat::Compact => { + tracing_subscriber::fmt() + .compact() + .with_span_events(FmtSpan::NONE) + .with_env_filter(env_filter) + .init(); + } + LogFormat::Pretty => { + tracing_subscriber::fmt() + .pretty() + .with_env_filter(env_filter) + .init(); + } + LogFormat::Json => { + tracing_subscriber::fmt() + .json() + .with_span_events(FmtSpan::NONE) + .with_env_filter(env_filter) + .init(); + } + }; + } +} + impl Default for LogFormat { fn default() -> Self { if cfg!(debug_assertions) { @@ -67,12 +98,6 @@ impl FromStr for LogFormat { /// 3. Uses the provided format for output /// 4. Sets up the global tracing subscriber pub fn init_tracing(filter: &str, format: Option) { - // Initialize log -> tracing bridge (ignore if already initialized) - let _ = tracing_log::LogTracer::builder() - .with_interest_cache(tracing_log::InterestCacheConfig::default()) - .init() - .expect("failed to intialise the global log -> tracing bridge"); - // Set up the filter from the provided string let env_filter = EnvFilter::from_str(filter).unwrap_or_else(|_| { eprintln!("Warning: Invalid filter string '{filter}' passed. Since you passed a filter, you likely want to debug us, so we set the filter to debug"); @@ -80,7 +105,7 @@ pub fn init_tracing(filter: &str, format: Option) { }); // Build and install the subscriber based on format - let format = format + format .and_then(|s| { s.parse::() .map_err(|e| { @@ -89,39 +114,25 @@ pub fn init_tracing(filter: &str, format: Option) { }) .ok() }) - .unwrap_or_default(); - match format { - LogFormat::Full => { - let fmt_layer = tracing_subscriber::fmt::layer() - .with_span_events(FmtSpan::NONE) - .with_filter(env_filter); - - Registry::default().with(fmt_layer).init() - } - LogFormat::Compact => { - let fmt_layer = tracing_subscriber::fmt::layer() - .compact() - .with_span_events(FmtSpan::NONE) - .with_filter(env_filter); - - Registry::default().with(fmt_layer).init() - } - LogFormat::Pretty => { - let fmt_layer = tracing_subscriber::fmt::layer() - .pretty() - .with_filter(env_filter); - - Registry::default().with(fmt_layer).init() - } - LogFormat::Json => { - let fmt_layer = tracing_subscriber::fmt::layer() - .json() - .with_span_events(FmtSpan::NONE) - .with_filter(env_filter); - - Registry::default().with(fmt_layer).init() - } - }; + .unwrap_or_default() + .init(env_filter.clone()); + + // Initialize log -> tracing bridge + let mut log_builder = tracing_log::LogTracer::builder() + .with_interest_cache(tracing_log::InterestCacheConfig::default()); + if let Some(Some(max_level)) = env_filter.max_level_hint().map(|l| l.into_level()) { + let max_level = match max_level { + tracing::Level::DEBUG => log::LevelFilter::Debug, + tracing::Level::INFO => log::LevelFilter::Info, + tracing::Level::WARN => log::LevelFilter::Warn, + tracing::Level::ERROR => log::LevelFilter::Error, + tracing::Level::TRACE => log::LevelFilter::Trace, + }; + log_builder = log_builder.with_max_level(max_level); + } + log_builder + .init() + .expect("Failed to initialize log -> tracing bridge"); } pub fn ensure_martin_core_log_level_matches( From 8c04deae04f5a931de8ae80e3b298ea3299dab75 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 00:26:09 +0100 Subject: [PATCH 05/39] fix fmt --- martin/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/martin/Cargo.toml b/martin/Cargo.toml index e39b0507e..44dfb9b5d 100644 --- a/martin/Cargo.toml +++ b/martin/Cargo.toml @@ -155,7 +155,7 @@ tilejson.workspace = true tokio = { workspace = true, features = ["io-std"] } tracing = { workspace = true, features = ["log"] } tracing-log = { workspace = true, features = ["interest-cache"] } -tracing-subscriber = { workspace = true, default-features=false, features = ["env-filter", "json", "fmt","std", "ansi", "chrono"] } +tracing-subscriber = { workspace = true, default-features = false, features = ["env-filter", "json", "fmt","std", "ansi", "chrono"] } url.workspace = true walkdir = { workspace = true, optional = true } From 6e21c10c0e06151bc3d34b8442fa29e6f6398c79 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 00:34:46 +0100 Subject: [PATCH 06/39] fix clippy issues --- Cargo.lock | 2 ++ martin/Cargo.toml | 2 +- martin/src/logging.rs | 9 ++++-- martin/tests/cors_test.rs | 14 ++++----- martin/tests/mb_server_test.rs | 29 +++++++++--------- martin/tests/pg_function_source_test.rs | 1 - martin/tests/pg_server_test.rs | 39 ++++++++++++------------- martin/tests/pg_table_source_test.rs | 1 - martin/tests/pmt_server_test.rs | 17 +++++------ martin/tests/styles_server_test.rs | 13 ++++----- mbtiles/Cargo.toml | 2 ++ mbtiles/tests/copy.rs | 13 ++++----- mbtiles/tests/validate.rs | 6 ++-- 13 files changed, 75 insertions(+), 73 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e306b7a66..cf9878bc7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3929,6 +3929,8 @@ dependencies = [ "thiserror 2.0.17", "tilejson", "tokio", + "tracing", + "tracing-test", "xxhash-rust", ] diff --git a/martin/Cargo.toml b/martin/Cargo.toml index 44dfb9b5d..14cd2d625 100644 --- a/martin/Cargo.toml +++ b/martin/Cargo.toml @@ -153,7 +153,7 @@ subst.workspace = true thiserror.workspace = true tilejson.workspace = true tokio = { workspace = true, features = ["io-std"] } -tracing = { workspace = true, features = ["log"] } +tracing.workspace = true tracing-log = { workspace = true, features = ["interest-cache"] } tracing-subscriber = { workspace = true, default-features = false, features = ["env-filter", "json", "fmt","std", "ansi", "chrono"] } url.workspace = true diff --git a/martin/src/logging.rs b/martin/src/logging.rs index 016e21f21..1a3d0f0d3 100644 --- a/martin/src/logging.rs +++ b/martin/src/logging.rs @@ -60,7 +60,7 @@ impl LogFormat { .with_env_filter(env_filter) .init(); } - }; + } } } @@ -120,7 +120,10 @@ pub fn init_tracing(filter: &str, format: Option) { // Initialize log -> tracing bridge let mut log_builder = tracing_log::LogTracer::builder() .with_interest_cache(tracing_log::InterestCacheConfig::default()); - if let Some(Some(max_level)) = env_filter.max_level_hint().map(|l| l.into_level()) { + if let Some(Some(max_level)) = env_filter + .max_level_hint() + .map(tracing::level_filters::LevelFilter::into_level) + { let max_level = match max_level { tracing::Level::DEBUG => log::LevelFilter::Debug, tracing::Level::INFO => log::LevelFilter::Info, @@ -135,6 +138,8 @@ pub fn init_tracing(filter: &str, format: Option) { .expect("Failed to initialize log -> tracing bridge"); } +/// Ensures that the log level for `martin_core` matches the log level for `replacement`. +#[must_use] pub fn ensure_martin_core_log_level_matches( env_filter: Option, replacement: &'static str, diff --git a/martin/tests/cors_test.rs b/martin/tests/cors_test.rs index d0a9ddf3f..9c3e45269 100644 --- a/martin/tests/cors_test.rs +++ b/martin/tests/cors_test.rs @@ -41,7 +41,7 @@ macro_rules! create_app { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn test_cors_explicit_disabled() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = temp_named_mbtiles("test_cors_explicit_disabled", script).await; @@ -67,7 +67,7 @@ async fn test_cors_explicit_disabled() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn test_cors_implicit_enabled() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = temp_named_mbtiles("test_cors_implicit_enabled", script).await; @@ -91,7 +91,7 @@ async fn test_cors_implicit_enabled() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn test_cors_explicit_enabled() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = temp_named_mbtiles("test_cors_explicit_enabled", script).await; @@ -116,7 +116,7 @@ async fn test_cors_explicit_enabled() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn test_cors_specific_origin() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = temp_named_mbtiles("test_cors_specific_origin", script).await; @@ -142,7 +142,7 @@ async fn test_cors_specific_origin() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn test_cors_no_header_on_mismatch() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = temp_named_mbtiles("test_cors_no_header_on_mismatch", script).await; @@ -170,7 +170,7 @@ async fn test_cors_no_header_on_mismatch() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn test_cors_preflight_request_with_max_age() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = @@ -205,7 +205,7 @@ async fn test_cors_preflight_request_with_max_age() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn test_cors_preflight_request_without_max_age() { let script = include_str!("../../tests/fixtures/mbtiles/world_cities.sql"); let (_mbt, _conn, file) = diff --git a/martin/tests/mb_server_test.rs b/martin/tests/mb_server_test.rs index 486eba625..a6c4c05d7 100644 --- a/martin/tests/mb_server_test.rs +++ b/martin/tests/mb_server_test.rs @@ -2,7 +2,6 @@ use actix_web::http::header::{ACCEPT_ENCODING, CONTENT_ENCODING, CONTENT_TYPE}; use actix_web::test::{TestRequest, call_service, read_body, read_body_json}; -use ctor::ctor; use indoc::formatdoc; use insta::assert_yaml_snapshot; use martin::config::file::srv::SrvConfig; @@ -85,7 +84,7 @@ async fn config( } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_catalog() { let (config, _conns) = config("mbt_get_catalog").await; let app = create_app!(&config); @@ -117,7 +116,7 @@ async fn mbt_get_catalog() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_catalog_gzip() { let (config, _conns) = config("mbt_get_catalog_gzip").await; let app = create_app!(&config); @@ -151,7 +150,7 @@ async fn mbt_get_catalog_gzip() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_tilejson() { let (config, _conns) = config("mbt_get_tilejson").await; let app = create_app!(&config); @@ -166,7 +165,7 @@ async fn mbt_get_tilejson() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_tilejson_gzip() { let (config, _conns) = config("mbt_get_tilejson_gzip").await; let app = create_app!(&config); @@ -183,7 +182,7 @@ async fn mbt_get_tilejson_gzip() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_raster() { let (config, _conns) = config("mbt_get_raster").await; let app = create_app!(&config); @@ -198,7 +197,7 @@ async fn mbt_get_raster() { /// get a raster tile with accepted gzip enc, but should still be non-gzipped #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_raster_gzip() { let (config, _conns) = config("mbt_get_raster_gzip").await; let app = create_app!(&config); @@ -213,7 +212,7 @@ async fn mbt_get_raster_gzip() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_mvt() { let (config, _conns) = config("mbt_get_mvt").await; let app = create_app!(&config); @@ -234,7 +233,7 @@ async fn mbt_get_mvt() { /// get an MVT tile with accepted gzip enc #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_mvt_gzip() { let (config, _conns) = config("mbt_get_mvt_gzip").await; let app = create_app!(&config); @@ -255,7 +254,7 @@ async fn mbt_get_mvt_gzip() { /// get an MVT tile with accepted brotli enc #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_mvt_brotli() { let (config, _conns) = config("mbt_get_mvt_brotli").await; let app = create_app!(&config); @@ -276,7 +275,7 @@ async fn mbt_get_mvt_brotli() { /// get an uncompressed MVT tile #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_raw_mvt() { let (config, _conns) = config("mbt_get_raw_mvt").await; let app = create_app!(&config); @@ -294,7 +293,7 @@ async fn mbt_get_raw_mvt() { /// get an uncompressed MVT tile with accepted gzip #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_raw_mvt_gzip() { let (config, _conns) = config("mbt_get_raw_mvt_gzip").await; let app = create_app!(&config); @@ -317,7 +316,7 @@ async fn mbt_get_raw_mvt_gzip() { /// get an uncompressed MVT tile with accepted both gzip and brotli enc #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_raw_mvt_gzip_br() { let (config, _conns) = config("mbt_get_raw_mvt_gzip_br").await; let app = create_app!(&config); @@ -341,7 +340,7 @@ async fn mbt_get_raw_mvt_gzip_br() { /// get a JSON tile #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_json() { let (config, _conns) = config("mbt_get_json").await; let app = create_app!(&config); @@ -359,7 +358,7 @@ async fn mbt_get_json() { /// get a JSON tile with accepted gzip #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn mbt_get_json_gzip() { let (config, _conns) = config("mbt_get_json_gzip").await; let app = create_app!(&config); diff --git a/martin/tests/pg_function_source_test.rs b/martin/tests/pg_function_source_test.rs index e704ed664..137fb0d10 100644 --- a/martin/tests/pg_function_source_test.rs +++ b/martin/tests/pg_function_source_test.rs @@ -1,6 +1,5 @@ #![cfg(feature = "postgres")] -use ctor::ctor; use indoc::indoc; use insta::assert_yaml_snapshot; use martin_tile_utils::TileCoord; diff --git a/martin/tests/pg_server_test.rs b/martin/tests/pg_server_test.rs index ceb8ed61b..6d9b9c9d8 100644 --- a/martin/tests/pg_server_test.rs +++ b/martin/tests/pg_server_test.rs @@ -3,7 +3,6 @@ use actix_http::Request; use actix_web::http::StatusCode; use actix_web::test::{TestRequest, call_and_read_body_json, call_service, read_body}; -use ctor::ctor; use indoc::indoc; use insta::assert_yaml_snapshot; use martin::config::file::srv::SrvConfig; @@ -38,7 +37,7 @@ fn test_get(path: &str) -> Request { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_catalog() { let app = create_app! { " postgres: @@ -147,7 +146,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_table_source_ok() { let app = create_app! { " on_invalid: warn @@ -184,7 +183,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_table_source_rewrite() { let app = create_app! { " postgres: @@ -226,7 +225,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_table_source_tile_ok() { let app = create_app! { " postgres: @@ -317,7 +316,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_table_source_multiple_geom_tile_ok() { let app = create_app! { " postgres: @@ -408,7 +407,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_table_source_tile_minmax_zoom_ok() { let app = create_app! { " postgres: @@ -517,7 +516,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_function_tiles() { let app = create_app! { " postgres: @@ -550,7 +549,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_composite_source_ok() { let app = create_app! { " postgres: @@ -640,7 +639,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_composite_source_tile_ok() { let app = create_app! { " postgres: @@ -731,7 +730,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_composite_source_tile_minmax_zoom_ok() { let app = create_app! { " postgres: @@ -798,7 +797,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_null_functions() { let app = create_app! { " postgres: @@ -819,7 +818,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_function_source_ok() { let app = create_app! { " postgres: @@ -864,7 +863,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_function_source_ok_rewrite() { let app = create_app! { " postgres: @@ -883,7 +882,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_function_source_ok_rewrite_all() { let app = create_app! { " postgres: @@ -904,7 +903,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_function_source_tile_ok() { let app = create_app! { " postgres: @@ -917,7 +916,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_function_source_tile_minmax_zoom_ok() { let app = create_app! {" postgres: @@ -976,7 +975,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_function_source_query_params_ok() { let app = create_app! { " postgres: @@ -993,7 +992,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_get_health_returns_ok() { let app = create_app! { " postgres: @@ -1006,7 +1005,7 @@ postgres: } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pg_tables_feature_id() { let cfg = mock_pgcfg(indoc! {" connection_string: $DATABASE_URL diff --git a/martin/tests/pg_table_source_test.rs b/martin/tests/pg_table_source_test.rs index 6111b4798..b868aaf00 100644 --- a/martin/tests/pg_table_source_test.rs +++ b/martin/tests/pg_table_source_test.rs @@ -1,6 +1,5 @@ #![cfg(feature = "postgres")] -use ctor::ctor; use indoc::indoc; use insta::assert_yaml_snapshot; use martin_tile_utils::TileCoord; diff --git a/martin/tests/pmt_server_test.rs b/martin/tests/pmt_server_test.rs index 75286c6af..f4704c569 100644 --- a/martin/tests/pmt_server_test.rs +++ b/martin/tests/pmt_server_test.rs @@ -2,7 +2,6 @@ use actix_web::http::header::{ACCEPT_ENCODING, CONTENT_ENCODING, CONTENT_TYPE}; use actix_web::test::{TestRequest, call_service, read_body, read_body_json}; -use ctor::ctor; use indoc::indoc; use insta::assert_yaml_snapshot; use martin::config::file::srv::SrvConfig; @@ -45,7 +44,7 @@ const CONFIG: &str = indoc! {" "}; #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pmt_get_catalog() { let path = "pmtiles: ../tests/fixtures/pmtiles/stamen_toner__raster_CC-BY+ODbL_z3.pmtiles"; let app = create_app! { path }; @@ -65,7 +64,7 @@ async fn pmt_get_catalog() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pmt_get_catalog_gzip() { let app = create_app! { CONFIG }; let accept = (ACCEPT_ENCODING, "gzip"); @@ -90,7 +89,7 @@ async fn pmt_get_catalog_gzip() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pmt_get_tilejson() { let app = create_app! { CONFIG }; let req = test_get("/p_png").to_request(); @@ -104,7 +103,7 @@ async fn pmt_get_tilejson() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pmt_get_tilejson_gzip() { let app = create_app! { CONFIG }; let accept = (ACCEPT_ENCODING, "gzip"); @@ -120,7 +119,7 @@ async fn pmt_get_tilejson_gzip() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pmt_get_raster() { let app = create_app! { CONFIG }; let req = test_get("/p_png/0/0/0").to_request(); @@ -134,7 +133,7 @@ async fn pmt_get_raster() { /// get a raster tile with accepted gzip enc, but should still be non-gzipped #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pmt_get_raster_gzip() { let app = create_app! { CONFIG }; let accept = (ACCEPT_ENCODING, "gzip"); @@ -148,7 +147,7 @@ async fn pmt_get_raster_gzip() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pmt_get_tilejson_s3() { let app = create_app! { CONFIG }; let req = test_get("/s3").to_request(); @@ -163,7 +162,7 @@ async fn pmt_get_tilejson_s3() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn pmt_get_tile_s3() { let app = create_app! { CONFIG }; let req = test_get("/s3/0/0/0").to_request(); diff --git a/martin/tests/styles_server_test.rs b/martin/tests/styles_server_test.rs index 006b67598..969d79794 100644 --- a/martin/tests/styles_server_test.rs +++ b/martin/tests/styles_server_test.rs @@ -2,7 +2,6 @@ use actix_web::http::header::CONTENT_TYPE; use actix_web::test::{TestRequest, call_service, read_body, read_body_json}; -use ctor::ctor; use indoc::indoc; use insta::assert_json_snapshot; use martin::config::file::srv::SrvConfig; @@ -46,7 +45,7 @@ const CONFIG_STYLES: &str = indoc! {" "}; #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn catalog_multiple_styles() { let app = create_app! { CONFIG_STYLES }; @@ -67,7 +66,7 @@ async fn catalog_multiple_styles() { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn style_json_not_found() { let app = create_app! { CONFIG_STYLES }; @@ -96,7 +95,7 @@ mod render_tests { #[case::single_style_corner(CONFIG_STYLES, "/style/maplibre_demo/1/1/0.png")] #[case::single_style_mid_zoom(CONFIG_STYLES, "/style/maplibre_demo/5/15/15.png")] #[tokio::test] - #[traced_test::traced_test] + #[tracing_test::traced_test] async fn render_tile_png(#[case] config: &str, #[case] path: &str) { let app = create_app! { config }; @@ -117,7 +116,7 @@ mod render_tests { } #[tokio::test] - #[traced_test::traced_test] + #[tracing_test::traced_test] async fn render_tile_not_found_style() { let app = create_app! { CONFIG_STYLES }; @@ -130,7 +129,7 @@ mod render_tests { } #[tokio::test] - #[traced_test::traced_test] + #[tracing_test::traced_test] async fn render_tile_impossible() { let app = create_app! { CONFIG_STYLES }; @@ -144,7 +143,7 @@ mod render_tests { } #[tokio::test] - #[traced_test::traced_test] + #[tracing_test::traced_test] async fn render_concurrent_requests() { let app = create_app! { CONFIG_STYLES }; diff --git a/mbtiles/Cargo.toml b/mbtiles/Cargo.toml index 4f492e733..4be7997ef 100644 --- a/mbtiles/Cargo.toml +++ b/mbtiles/Cargo.toml @@ -55,6 +55,8 @@ env_logger.workspace = true insta = { workspace = true, features = ["toml", "yaml"] } pretty_assertions.workspace = true rstest.workspace = true +tracing-test.workspace = true +tracing.workspace = true [lints] workspace = true diff --git a/mbtiles/tests/copy.rs b/mbtiles/tests/copy.rs index b46084914..426ae5538 100644 --- a/mbtiles/tests/copy.rs +++ b/mbtiles/tests/copy.rs @@ -4,7 +4,6 @@ use std::path::PathBuf; use std::str::from_utf8; use std::sync::Mutex; -use ctor::ctor; use insta::{allow_duplicates, assert_snapshot}; use itertools::Itertools as _; use martin_tile_utils::xyz_to_bbox; @@ -409,7 +408,7 @@ fn databases() -> Databases { } #[tokio::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn update() -> MbtResult<()> { let (mbt, mut cn) = new_file_no_hash!(databases, Flat, METADATA_V1, TILES_V1, "update"); mbt.update_metadata(&mut cn, UpdateZoomType::Reset).await?; @@ -422,7 +421,7 @@ async fn update() -> MbtResult<()> { #[rstest] #[trace] #[tokio::test(flavor = "multi_thread")] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn convert( #[values(Flat, FlatWithHash, Normalized)] frm_type: MbtTypeCli, #[values(Flat, FlatWithHash, Normalized)] dst_type: MbtTypeCli, @@ -510,7 +509,7 @@ async fn convert( #[rstest] #[trace] #[tokio::test(flavor = "multi_thread")] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn diff_and_patch( #[values(Flat, FlatWithHash, Normalized)] a_type: MbtTypeCli, #[values(Flat, FlatWithHash, Normalized)] b_type: MbtTypeCli, @@ -596,7 +595,7 @@ async fn diff_and_patch( #[trace] #[ignore = "test used to run for a while, and then became too complicated to maintain and got out of whack. TODO: bring it back or deleete"] #[tokio::test(flavor = "multi_thread")] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn diff_and_patch_bsdiff( #[values(Flat, FlatWithHash)] a_type: MbtTypeCli, #[values(Flat, FlatWithHash)] b_type: MbtTypeCli, @@ -655,7 +654,7 @@ async fn diff_and_patch_bsdiff( #[rstest] #[trace] #[tokio::test(flavor = "multi_thread")] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn patch_on_copy( #[values(Flat, FlatWithHash, Normalized)] v1_type: MbtTypeCli, #[values(Flat, FlatWithHash, Normalized)] dif_type: MbtTypeCli, @@ -687,7 +686,7 @@ async fn patch_on_copy( /// A simple tester to run specific values #[tokio::test(flavor = "multi_thread")] #[ignore = "this test is for debugging only, and should be disabled"] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn test_one() { // This will cause an error if ran together with other tests let db = databases(); diff --git a/mbtiles/tests/validate.rs b/mbtiles/tests/validate.rs index b1ddc16d6..6bf844381 100644 --- a/mbtiles/tests/validate.rs +++ b/mbtiles/tests/validate.rs @@ -61,7 +61,7 @@ macro_rules! err { #[case("0, 0, ", ", NULL")] // test tile_row #[trace] #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn integers(#[case] prefix: &str, #[case] suffix: &str) { ok!("{prefix} 0 {suffix}"); @@ -86,7 +86,7 @@ async fn integers(#[case] prefix: &str, #[case] suffix: &str) { #[case("0, ", ", NULL")] // test tile_row #[trace] #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn tile_coordinate(#[case] prefix: &str, #[case] suffix: &str) { ok!("0, {prefix} 0 {suffix}"); ok!("1, {prefix} 1 {suffix}"); @@ -108,7 +108,7 @@ async fn tile_coordinate(#[case] prefix: &str, #[case] suffix: &str) { } #[actix_rt::test] -#[traced_test::traced_test] +#[tracing_test::traced_test] async fn tile_data() { ok!("0, 0, 0, NULL"); ok!("0, 0, 0, CAST('' AS BLOB)"); From ec718e9d3b5e9e410f49a0ac9ea81d59766aaf52 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 00:40:36 +0100 Subject: [PATCH 07/39] various doc issues --- martin/src/logging.rs | 8 +++----- mbtiles/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/martin/src/logging.rs b/martin/src/logging.rs index 1a3d0f0d3..fda6bc6ee 100644 --- a/martin/src/logging.rs +++ b/martin/src/logging.rs @@ -1,8 +1,8 @@ //! Logging initialization for Martin using `tracing` and `tracing-subscriber`. //! -//! This module provides static (non-reloadable) logging configuration controlled by: -//! - `RUST_LOG`: Controls log level filtering (standard tracing-subscriber behavior) -//! - `MARTIN_FORMAT`: Controls output format (compact, full, pretty, json) +//! This module provides static logging configuration controlled by: +//! - [`EnvFilter`]: Controls log level filtering (standard tracing-subscriber behavior) +//! - [`LogFormat`]: Controls output format (compact, full, pretty, json) use std::str::FromStr; @@ -10,8 +10,6 @@ use tracing_subscriber::EnvFilter; use tracing_subscriber::fmt::format::FmtSpan; /// Log output format options. -/// -/// Controlled by the `MARTIN_FORMAT` environment variable. #[derive(Debug, Clone, Copy)] pub enum LogFormat { /// Emit human-readable, single-line logs. diff --git a/mbtiles/Cargo.toml b/mbtiles/Cargo.toml index 4be7997ef..8726a22b1 100644 --- a/mbtiles/Cargo.toml +++ b/mbtiles/Cargo.toml @@ -55,8 +55,8 @@ env_logger.workspace = true insta = { workspace = true, features = ["toml", "yaml"] } pretty_assertions.workspace = true rstest.workspace = true -tracing-test.workspace = true tracing.workspace = true +tracing-test.workspace = true [lints] workspace = true From 2240c124a55f963aa9ae91032dc9ab26d2479ba8 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 01:40:58 +0100 Subject: [PATCH 08/39] add the bare format for tests --- martin/src/bin/martin-cp.rs | 2 +- martin/src/config/args/root.rs | 2 +- martin/src/logging.rs | 16 +++++++++++++++- tests/test.sh | 2 ++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/martin/src/bin/martin-cp.rs b/martin/src/bin/martin-cp.rs index 849a3a0c1..ab891411b 100644 --- a/martin/src/bin/martin-cp.rs +++ b/martin/src/bin/martin-cp.rs @@ -51,7 +51,7 @@ const HELP_STYLES: Styles = Styles::styled() #[command( about = "A tool to bulk copy tiles from any Martin-supported sources into an mbtiles file", version, - after_help = "Use RUST_LOG environment variable to control logging level, e.g. RUST_LOG=debug or RUST_LOG=martin_cp=debug.\nUse MARTIN_CP_FORMAT environment variable to control output format: compact (default), full, pretty, or json.\nSee https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html for more information.", + after_help = "Use RUST_LOG environment variable to control logging level, e.g. RUST_LOG=debug or RUST_LOG=martin_cp=debug.\nUse MARTIN_CP_FORMAT environment variable to control output format: json, full, compact (default), bare or pretty.\nSee https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html for more information.", styles = HELP_STYLES )] pub struct CopierArgs { diff --git a/martin/src/config/args/root.rs b/martin/src/config/args/root.rs index 676ca8ca1..b91daa7ad 100644 --- a/martin/src/config/args/root.rs +++ b/martin/src/config/args/root.rs @@ -34,7 +34,7 @@ const HELP_STYLES: Styles = Styles::styled() #[command( about, version, - after_help = "Use RUST_LOG environment variable to control logging level, e.g. RUST_LOG=debug or RUST_LOG=martin=debug.\nUse MARTIN_FORMAT environment variable to control output format: compact (default), full, pretty, or json.\nSee https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html for more information.", + after_help = "Use RUST_LOG environment variable to control logging level, e.g. RUST_LOG=debug or RUST_LOG=martin=debug.\nUse MARTIN_FORMAT environment variable to control output format: json, full, compact (default), bare or pretty.\nSee https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html for more information.", styles = HELP_STYLES )] pub struct Args { diff --git a/martin/src/logging.rs b/martin/src/logging.rs index fda6bc6ee..254429370 100644 --- a/martin/src/logging.rs +++ b/martin/src/logging.rs @@ -2,7 +2,7 @@ //! //! This module provides static logging configuration controlled by: //! - [`EnvFilter`]: Controls log level filtering (standard tracing-subscriber behavior) -//! - [`LogFormat`]: Controls output format (compact, full, pretty, json) +//! - [`LogFormat`]: Controls output format (json, full, compact, bare, pretty) use std::str::FromStr; @@ -20,6 +20,9 @@ pub enum LogFormat { /// See [format::Compact](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/format/struct.Compact.html#example-output) Compact, + /// A very bare format, optimized for short line lengths, without timestamps, spans, locations or ANSI colors. + Bare, + /// Excessively pretty, multi-line logs for local development/debugging. /// See [format::Pretty](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/format/struct.Pretty.html#example-output) Pretty, @@ -51,6 +54,16 @@ impl LogFormat { .with_env_filter(env_filter) .init(); } + LogFormat::Bare => { + tracing_subscriber::fmt() + .compact() + .with_span_events(FmtSpan::NONE) + .without_time() + .with_target(false) + .with_ansi(false) + .with_env_filter(env_filter) + .init(); + } LogFormat::Json => { tracing_subscriber::fmt() .json() @@ -80,6 +93,7 @@ impl FromStr for LogFormat { "full" => Ok(Self::Full), "compact" => Ok(Self::Compact), "pretty" | "verbose" => Ok(Self::Pretty), + "bare" => Ok(Self::Bare), "json" | "jsonl" => Ok(Self::Json), _ => Err(format!( "Invalid log format '{s}'. Valid options: full, compact, pretty, json" diff --git a/tests/test.sh b/tests/test.sh index 305224a8d..8dded1633 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -4,6 +4,8 @@ set -euo pipefail MARTIN_DATABASE_URL="${DATABASE_URL:-postgres://postgres@localhost/db}" unset DATABASE_URL +export MARTIN_FORMAT=bare + # TODO: use --fail-with-body to get the response body on failure CURL=${CURL:-curl --silent --show-error --fail --compressed} From ba19df57b9b19d8afc6fee53cddd5db483da15c1 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 02:01:14 +0100 Subject: [PATCH 09/39] adjust to the new, more stable log format --- tests/test.sh | 64 +++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/tests/test.sh b/tests/test.sh index 8dded1633..7d958eca8 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -455,10 +455,10 @@ test_pbf table_and_view_two_schemas2_0_0_0 table_and_view_two_schemas.1/0/0/0 kill_process "$MARTIN_PROC_ID" Martin -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::postgres::resolver::query_tables] Table public.table_source has no spatial index on column geom' -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::postgres::resolver::query_tables] Table public.table_source_geog has no spatial index on column geog' -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::postgres::resolver::query_tables] Table public.mat_view has no spatial index on column geom' -test_log_has_str "$LOG_FILE" 'WARN martin_core::resources::fonts] Ignoring duplicate font Overpass Mono Regular from tests' +test_log_has_str "$LOG_FILE" 'WARN Table public.table_source has no spatial index on column geom' +test_log_has_str "$LOG_FILE" 'WARN Table public.table_source_geog has no spatial index on column geog' +test_log_has_str "$LOG_FILE" 'WARN Table public.mat_view has no spatial index on column geom' +test_log_has_str "$LOG_FILE" 'WARN Ignoring duplicate font Overpass Mono Regular from tests' test_log_has_str "$LOG_FILE" 'was renamed to `stamen_toner__raster_CC-BY-ODbL_z3`' test_log_has_str "$LOG_FILE" 'was renamed to `table_source_multiple_geom.1`' test_log_has_str "$LOG_FILE" 'was renamed to `-function.withweired---_-characters`' @@ -466,9 +466,9 @@ test_log_has_str "$LOG_FILE" 'was renamed to `.-Points-----------quote`' test_log_has_str "$LOG_FILE" 'was renamed to `table_name_existing_two_schemas.1`' test_log_has_str "$LOG_FILE" 'was renamed to `view_name_existing_two_schemas.1`' test_log_has_str "$LOG_FILE" 'was renamed to `table_and_view_two_schemas.1`' -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::pmtiles] Defaulting `pmtiles.allow_http` to `true`. This is likely to become an error in the future for better security.' -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::pmtiles] Environment variable AWS_SKIP_CREDENTIALS is deprecated. Please use pmtiles.skip_signature in the configuration file instead.' -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::pmtiles] Environment variable AWS_REGION is deprecated. Please use pmtiles.region in the configuration file instead.' +test_log_has_str "$LOG_FILE" 'WARN Defaulting `pmtiles.allow_http` to `true`. This is likely to become an error in the future for better security.' +test_log_has_str "$LOG_FILE" 'WARN Environment variable AWS_SKIP_CREDENTIALS is deprecated. Please use pmtiles.skip_signature in the configuration file instead.' +test_log_has_str "$LOG_FILE" 'WARN Environment variable AWS_REGION is deprecated. Please use pmtiles.region in the configuration file instead.' validate_log "$LOG_FILE" remove_lines "${TEST_OUT_DIR}/save_config.yaml" " connection_string: " echo "::endgroup::" @@ -492,9 +492,9 @@ wait_for "$MARTIN_PROC_ID" Martin "$MARTIN_URL/health" test_jsn catalog_auto catalog kill_process "$MARTIN_PROC_ID" Martin -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::pmtiles] Defaulting `pmtiles.allow_http` to `true`. This is likely to become an error in the future for better security.' -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::pmtiles] Environment variable AWS_SKIP_CREDENTIALS is deprecated. Please use pmtiles.skip_signature in the configuration file instead.' -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::pmtiles] Environment variable AWS_REGION is deprecated. Please use pmtiles.region in the configuration file instead.' +test_log_has_str "$LOG_FILE" 'WARN Defaulting `pmtiles.allow_http` to `true`. This is likely to become an error in the future for better security.' +test_log_has_str "$LOG_FILE" 'WARN Environment variable AWS_SKIP_CREDENTIALS is deprecated. Please use pmtiles.skip_signature in the configuration file instead.' +test_log_has_str "$LOG_FILE" 'WARN Environment variable AWS_REGION is deprecated. Please use pmtiles.region in the configuration file instead.' validate_log "$LOG_FILE" echo "::endgroup::" @@ -570,29 +570,29 @@ test_jsn fnc_comment_cfg function_Mixed_Name test_metrics "metrics_1" kill_process "$MARTIN_PROC_ID" Martin -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::postgres::resolver::query_tables] Table public.table_source has no spatial index on column geom' -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::postgres::resolver::query_tables] Table public.table_source_geog has no spatial index on column geog' -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::postgres::resolver::query_tables] Table public.mat_view has no spatial index on column geom' -test_log_has_str "$LOG_FILE" 'WARN martin_core::resources::fonts] Ignoring duplicate font Overpass Mono Regular from tests' -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'observability.warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'observability.metrics.warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'cors.warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'postgres.warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'postgres.ssl_certificates.warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'postgres.auto_publish.warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'postgres.auto_publish.tables.warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'postgres.auto_publish.functions.warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'postgres.tables.table_source.warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'postgres.functions.function_zxy_query.warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'pmtiles.warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'sprites.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" 'WARN Table public.table_source has no spatial index on column geom' +test_log_has_str "$LOG_FILE" 'WARN Table public.table_source_geog has no spatial index on column geog' +test_log_has_str "$LOG_FILE" 'WARN Table public.mat_view has no spatial index on column geom' +test_log_has_str "$LOG_FILE" 'WARN Ignoring duplicate font Overpass Mono Regular from tests' +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'observability.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'observability.metrics.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'cors.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'postgres.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'postgres.ssl_certificates.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'postgres.auto_publish.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'postgres.auto_publish.tables.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'postgres.auto_publish.functions.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'postgres.tables.table_source.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'postgres.functions.function_zxy_query.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'pmtiles.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'sprites.warning'. Please check your configuration file for typos." # TODO: below should be changed to cog.warning once unstable-cog is made stable -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'cog'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" "WARN martin::config::file::main] Ignoring unrecognized configuration key 'styles.warning'. Please check your configuration file for typos." -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::pmtiles] Defaulting `pmtiles.allow_http` to `true`. This is likely to become an error in the future for better security.' -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::pmtiles] Environment variable AWS_SKIP_CREDENTIALS is deprecated. Please use pmtiles.skip_signature in the configuration file instead.' -test_log_has_str "$LOG_FILE" 'WARN martin::config::file::tiles::pmtiles] Environment variable AWS_REGION is deprecated. Please use pmtiles.region in the configuration file instead.' +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'cog'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" "WARN Ignoring unrecognized configuration key 'styles.warning'. Please check your configuration file for typos." +test_log_has_str "$LOG_FILE" 'WARN Defaulting `pmtiles.allow_http` to `true`. This is likely to become an error in the future for better security.' +test_log_has_str "$LOG_FILE" 'WARN Environment variable AWS_SKIP_CREDENTIALS is deprecated. Please use pmtiles.skip_signature in the configuration file instead.' +test_log_has_str "$LOG_FILE" 'WARN Environment variable AWS_REGION is deprecated. Please use pmtiles.region in the configuration file instead.' validate_log "$LOG_FILE" remove_lines "${TEST_OUT_DIR}/save_config.yaml" " connection_string: " echo "::endgroup::" From 3d72cf6e20862376b882abd5cee026547ed4717b Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Fri, 9 Jan 2026 20:06:56 -0500 Subject: [PATCH 10/39] Fix formatting in Cargo.toml for tracing-subscriber --- martin/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/martin/Cargo.toml b/martin/Cargo.toml index 14cd2d625..fada37920 100644 --- a/martin/Cargo.toml +++ b/martin/Cargo.toml @@ -155,7 +155,7 @@ tilejson.workspace = true tokio = { workspace = true, features = ["io-std"] } tracing.workspace = true tracing-log = { workspace = true, features = ["interest-cache"] } -tracing-subscriber = { workspace = true, default-features = false, features = ["env-filter", "json", "fmt","std", "ansi", "chrono"] } +tracing-subscriber = { workspace = true, default-features = false, features = ["env-filter", "json", "fmt", "std", "ansi", "chrono"] } url.workspace = true walkdir = { workspace = true, optional = true } From e9a4fecaedfd657e8ad7f57be3fac3c314bbb12e Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 02:12:01 +0100 Subject: [PATCH 11/39] Update martin/src/logging.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- martin/src/logging.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/martin/src/logging.rs b/martin/src/logging.rs index 254429370..7b71e3ab7 100644 --- a/martin/src/logging.rs +++ b/martin/src/logging.rs @@ -96,7 +96,7 @@ impl FromStr for LogFormat { "bare" => Ok(Self::Bare), "json" | "jsonl" => Ok(Self::Json), _ => Err(format!( - "Invalid log format '{s}'. Valid options: full, compact, pretty, json" + "Invalid log format '{s}'. Valid options: json, full, compact, bare or pretty" )), } } From 0f26678990585a2a744c47eab89795d068785988 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 02:12:15 +0100 Subject: [PATCH 12/39] Update martin/src/logging.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- martin/src/logging.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/martin/src/logging.rs b/martin/src/logging.rs index 7b71e3ab7..d71df0a06 100644 --- a/martin/src/logging.rs +++ b/martin/src/logging.rs @@ -122,7 +122,10 @@ pub fn init_tracing(filter: &str, format: Option) { s.parse::() .map_err(|e| { eprintln!("Warning: {e}"); - eprintln!("Falling back to default format (compact)"); + eprintln!( + "Falling back to default format ({:?})", + LogFormat::default() + ); }) .ok() }) From 7f2f50c545db94c47ce7fe0b0e9d095ff26004dc Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 02:14:13 +0100 Subject: [PATCH 13/39] fix an issue noticed by copilot --- martin/src/config/file/file_config.rs | 3 +-- .../src/config/file/tiles/postgres/builder.rs | 3 +-- martin/src/logging.rs | 24 ------------------- 3 files changed, 2 insertions(+), 28 deletions(-) diff --git a/martin/src/config/file/file_config.rs b/martin/src/config/file/file_config.rs index f4c455196..bdfc108ab 100644 --- a/martin/src/config/file/file_config.rs +++ b/martin/src/config/file/file_config.rs @@ -551,9 +551,8 @@ mod pmtiles_tests { use crate::config::file::tiles::pmtiles::PmtConfig; #[tokio::test] + #[tracing_test::traced_test] async fn test_invalid_path_warns_instead_of_failing() { - let _ = crate::logging::init_tracing_for_tests(); - let invalid_path = PathBuf::from("/nonexistent/path/"); let invalid_source = PathBuf::from("/nonexistent/path/to/file.pmtiles"); let mut file_sources = BTreeMap::new(); diff --git a/martin/src/config/file/tiles/postgres/builder.rs b/martin/src/config/file/tiles/postgres/builder.rs index d401fca8b..440f8baf1 100644 --- a/martin/src/config/file/tiles/postgres/builder.rs +++ b/martin/src/config/file/tiles/postgres/builder.rs @@ -764,13 +764,12 @@ mod tests { } #[tokio::test] + #[tracing_test::traced_test] async fn test_nonexistent_tables_functions_generate_warning() { use testcontainers_modules::postgres::Postgres; use testcontainers_modules::testcontainers::ImageExt; use testcontainers_modules::testcontainers::runners::AsyncRunner; - let _ = crate::logging::init_tracing_for_tests(); - let container = Postgres::default() .with_name("postgis/postgis") .with_tag("11-3.0") // purposely very old and stable diff --git a/martin/src/logging.rs b/martin/src/logging.rs index d71df0a06..038f47fe1 100644 --- a/martin/src/logging.rs +++ b/martin/src/logging.rs @@ -177,27 +177,3 @@ pub fn ensure_martin_core_log_level_matches( format!("{replacement}info,martin_core=info") } } - -/// Initialize tracing for tests. -/// -/// This is a simplified version that: -/// - Doesn't panic if already initialized (returns Ok/Err) -/// - Uses compact format -/// - Sets `is_test(true)` to avoid interference between tests -pub fn init_tracing_for_tests() -> Result<(), Box> { - use tracing_subscriber::fmt; - - let env_filter = EnvFilter::try_from_default_env() - .or_else(|_| EnvFilter::from_str("info")) - .unwrap(); - - let subscriber = fmt() - .compact() - .with_test_writer() - .with_env_filter(env_filter) - .with_span_events(FmtSpan::NONE) - .finish(); - - tracing::subscriber::set_global_default(subscriber)?; - Ok(()) -} From b3c07cbee9b8b16ce5e0c09f17f650f80a98e512 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Fri, 9 Jan 2026 20:16:07 -0500 Subject: [PATCH 14/39] cleanup env var usage --- martin-core/src/config/env.rs | 11 +++++------ martin/src/bin/martin-cp.rs | 5 +++-- martin/src/bin/martin.rs | 6 ++++-- martin/src/config/file/resources/styles.rs | 3 ++- martin/src/config/file/tiles/pmtiles.rs | 9 +++++---- martin/tests/utils.rs | 4 +++- 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/martin-core/src/config/env.rs b/martin-core/src/config/env.rs index 353fc003a..fe5d0e9e0 100644 --- a/martin-core/src/config/env.rs +++ b/martin-core/src/config/env.rs @@ -8,8 +8,8 @@ use std::cell::RefCell; use std::collections::HashSet; -use std::env::var_os; use std::ffi::OsString; +use std::{collections, env}; use log::warn; use subst::VariableMap; @@ -54,12 +54,11 @@ pub struct OsEnv(RefCell>); impl Env<'_> for OsEnv { fn var_os(&self, key: &str) -> Option { - #[expect(unused_qualifications)] - std::env::var_os(key) + env::var_os(key) } fn has_unused_var(&self, key: &str) -> bool { - !self.0.borrow().contains(key) && var_os(key).is_some() + !self.0.borrow().contains(key) && env::var_os(key).is_some() } } @@ -68,13 +67,13 @@ impl<'a> VariableMap<'a> for OsEnv { fn get(&'a self, key: &str) -> Option { self.0.borrow_mut().insert(key.to_string()); - std::env::var(key).ok() + env::var(key).ok() } } /// Test implementation with configurable environment variables. #[derive(Debug, Default)] -pub struct FauxEnv(pub std::collections::HashMap<&'static str, OsString>); +pub struct FauxEnv(pub collections::HashMap<&'static str, OsString>); impl<'a> VariableMap<'a> for FauxEnv { type Value = String; diff --git a/martin/src/bin/martin-cp.rs b/martin/src/bin/martin-cp.rs index ab891411b..842e4276e 100644 --- a/martin/src/bin/martin-cp.rs +++ b/martin/src/bin/martin-cp.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::env; use std::fmt::{Debug, Display, Formatter}; use std::num::NonZeroUsize; use std::ops::RangeInclusive; @@ -577,8 +578,8 @@ async fn init_schema( #[actix_web::main] async fn main() { - let filter = ensure_martin_core_log_level_matches(std::env::var("RUST_LOG").ok(), "martin_cp="); - init_tracing(&filter, std::env::var("MARTIN_CP_FORMAT").ok()); + let filter = ensure_martin_core_log_level_matches(env::var("RUST_LOG").ok(), "martin_cp="); + init_tracing(&filter, env::var("MARTIN_CP_FORMAT").ok()); let args = CopierArgs::parse(); if let Err(e) = start(args).await { diff --git a/martin/src/bin/martin.rs b/martin/src/bin/martin.rs index 024961697..9a71da45c 100644 --- a/martin/src/bin/martin.rs +++ b/martin/src/bin/martin.rs @@ -1,3 +1,5 @@ +use std::env; + use clap::Parser; use martin::MartinResult; use martin::config::args::Args; @@ -53,8 +55,8 @@ async fn start(args: Args) -> MartinResult<()> { #[tokio::main] async fn main() { - let filter = ensure_martin_core_log_level_matches(std::env::var("RUST_LOG").ok(), "martin="); - init_tracing(&filter, std::env::var("MARTIN_FORMAT").ok()); + let filter = ensure_martin_core_log_level_matches(env::var("RUST_LOG").ok(), "martin="); + init_tracing(&filter, env::var("MARTIN_FORMAT").ok()); let args = Args::parse(); if let Err(e) = start(args).await { diff --git a/martin/src/config/file/resources/styles.rs b/martin/src/config/file/resources/styles.rs index 8608cab00..c882cd10a 100644 --- a/martin/src/config/file/resources/styles.rs +++ b/martin/src/config/file/resources/styles.rs @@ -1,4 +1,5 @@ use std::collections::BTreeMap; +use std::env; use std::path::{Path, PathBuf}; use log::warn; @@ -148,7 +149,7 @@ fn list_contained_files( source_path: &Path, filter_extension: &str, ) -> Result, ConfigFileError> { - let working_directory = std::env::current_dir().ok(); + let working_directory = env::current_dir().ok(); let mut contained_files = Vec::new(); let it = walkdir::WalkDir::new(source_path) .follow_links(true) diff --git a/martin/src/config/file/tiles/pmtiles.rs b/martin/src/config/file/tiles/pmtiles.rs index af8d71f61..a47ebae82 100644 --- a/martin/src/config/file/tiles/pmtiles.rs +++ b/martin/src/config/file/tiles/pmtiles.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::env; use std::path::PathBuf; use std::str::FromStr; @@ -123,7 +124,7 @@ impl PmtConfig { } if let Ok(force_path_style) = - std::env::var("AWS_S3_FORCE_PATH_STYLE").map(|v| v == "1" || v.to_lowercase() == "true") + env::var("AWS_S3_FORCE_PATH_STYLE").map(|v| v == "1" || v.to_lowercase() == "true") { let virtual_hosted_style_request = !force_path_style; self.migrate_aws_value( @@ -147,7 +148,7 @@ impl PmtConfig { } for env in ["AWS_SKIP_CREDENTIALS", "AWS_NO_CREDENTIALS"] { if let Ok(skip_credentials) = - std::env::var(env).map(|v| v == "1" || v.to_lowercase() == "true") + env::var(env).map(|v| v == "1" || v.to_lowercase() == "true") { self.migrate_aws_value( "Environment variable", @@ -165,7 +166,7 @@ impl PmtConfig { "AWS_SESSION_TOKEN", "AWS_REGION", ] { - if let Ok(var) = std::env::var(env_key) { + if let Ok(var) = env::var(env_key) { let new_key_with_aws_prefix = env_key.to_lowercase(); let new_key_without_aws_prefix = new_key_with_aws_prefix .strip_prefix("aws_") @@ -178,7 +179,7 @@ impl PmtConfig { ); } } - if std::env::var("AWS_PROFILE").is_ok() { + if env::var("AWS_PROFILE").is_ok() { warn!( "Environment variable AWS_PROFILE not supported anymore. Supporting this is in scope, but would need more work. See https://github.com/pola-rs/polars/issues/18757#issuecomment-2379398284" ); diff --git a/martin/tests/utils.rs b/martin/tests/utils.rs index 42c821b60..c0ea9b6ce 100644 --- a/martin/tests/utils.rs +++ b/martin/tests/utils.rs @@ -1,5 +1,7 @@ #![cfg(test)] +use std::env; + use actix_web::dev::ServiceResponse; use actix_web::test::read_body; use log::warn; @@ -12,7 +14,7 @@ use martin_core::tiles::BoxedSource; #[must_use] pub fn mock_cfg(yaml: &str) -> Config { - let env = if let Ok(db_url) = std::env::var("DATABASE_URL") { + let env = if let Ok(db_url) = env::var("DATABASE_URL") { FauxEnv(vec![("DATABASE_URL", db_url.into())].into_iter().collect()) } else { warn!("DATABASE_URL env var is not set. Might not be able to do integration tests"); From 22d6b01e63bb8565c7d2f263cb2ed2c60a49bec3 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 02:29:39 +0100 Subject: [PATCH 15/39] remove another occurance --- martin/src/config/file/file_config.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/martin/src/config/file/file_config.rs b/martin/src/config/file/file_config.rs index bdfc108ab..945ec05dc 100644 --- a/martin/src/config/file/file_config.rs +++ b/martin/src/config/file/file_config.rs @@ -518,9 +518,8 @@ mod mbtiles_tests { use crate::config::file::tiles::mbtiles::MbtConfig; #[tokio::test] + #[tracing_test::traced_test] async fn test_invalid_path_warns_instead_of_failing() { - let _ = crate::logging::init_tracing_for_tests(); - let invalid_path = PathBuf::from("/nonexistent/path/"); let invalid_source = PathBuf::from("/nonexistent/path/to/file.mbtiles"); let mut file_sources = BTreeMap::new(); From 2af2bf92e4d603013d04101cadc4488d8e9fbba4 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 03:12:36 +0100 Subject: [PATCH 16/39] Apply suggestions from code review --- martin/src/bin/martin-cp.rs | 7 ++++++- martin/src/bin/martin.rs | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/martin/src/bin/martin-cp.rs b/martin/src/bin/martin-cp.rs index 842e4276e..bb1792d60 100644 --- a/martin/src/bin/martin-cp.rs +++ b/martin/src/bin/martin-cp.rs @@ -583,7 +583,12 @@ async fn main() { let args = CopierArgs::parse(); if let Err(e) = start(args).await { - error!("{e}"); + // Ensure the message is printed, even if the logging is disabled + if log_enabled!(log::Level::Error) { + error!("{e}"); + } else { + eprintln!("{e}"); + } std::process::exit(1); } } diff --git a/martin/src/bin/martin.rs b/martin/src/bin/martin.rs index 9a71da45c..caf2b95f1 100644 --- a/martin/src/bin/martin.rs +++ b/martin/src/bin/martin.rs @@ -60,7 +60,12 @@ async fn main() { let args = Args::parse(); if let Err(e) = start(args).await { - error!("{e}"); + // Ensure the message is printed, even if the logging is disabled + if log_enabled!(log::Level::Error) { + error!("{e}"); + } else { + eprintln!("{e}"); + } std::process::exit(1); } } From 17a55e1aaf5a0d983cafe1ddd9322c2852ddd853 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 10 Jan 2026 02:12:54 +0000 Subject: [PATCH 17/39] chore(fmt): apply pre-commit formatting fixes --- martin/src/bin/martin-cp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/martin/src/bin/martin-cp.rs b/martin/src/bin/martin-cp.rs index bb1792d60..ba95df52e 100644 --- a/martin/src/bin/martin-cp.rs +++ b/martin/src/bin/martin-cp.rs @@ -583,7 +583,7 @@ async fn main() { let args = CopierArgs::parse(); if let Err(e) = start(args).await { - // Ensure the message is printed, even if the logging is disabled + // Ensure the message is printed, even if the logging is disabled if log_enabled!(log::Level::Error) { error!("{e}"); } else { From 14d7f8a6dc336bf467297b29b101e996709b1b03 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 03:16:02 +0100 Subject: [PATCH 18/39] Apply suggestions from code review --- martin/src/bin/martin-cp.rs | 2 +- martin/src/bin/martin.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/martin/src/bin/martin-cp.rs b/martin/src/bin/martin-cp.rs index ba95df52e..3d1b9d6cd 100644 --- a/martin/src/bin/martin-cp.rs +++ b/martin/src/bin/martin-cp.rs @@ -584,7 +584,7 @@ async fn main() { let args = CopierArgs::parse(); if let Err(e) = start(args).await { // Ensure the message is printed, even if the logging is disabled - if log_enabled!(log::Level::Error) { + if log::log_enabled!(log::Level::Error) { error!("{e}"); } else { eprintln!("{e}"); diff --git a/martin/src/bin/martin.rs b/martin/src/bin/martin.rs index caf2b95f1..c4cfbfdfd 100644 --- a/martin/src/bin/martin.rs +++ b/martin/src/bin/martin.rs @@ -61,7 +61,7 @@ async fn main() { let args = Args::parse(); if let Err(e) = start(args).await { // Ensure the message is printed, even if the logging is disabled - if log_enabled!(log::Level::Error) { + if log::log_enabled!(log::Level::Error) { error!("{e}"); } else { eprintln!("{e}"); From 427222ec224d1fe996f17cc99a2eb4141022793d Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 03:24:38 +0100 Subject: [PATCH 19/39] Apply suggestion from @CommanderStorm --- martin/src/bin/martin-cp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/martin/src/bin/martin-cp.rs b/martin/src/bin/martin-cp.rs index 3d1b9d6cd..16163780b 100644 --- a/martin/src/bin/martin-cp.rs +++ b/martin/src/bin/martin-cp.rs @@ -576,7 +576,7 @@ async fn init_schema( ) } -#[actix_web::main] +#[tokio::main] async fn main() { let filter = ensure_martin_core_log_level_matches(env::var("RUST_LOG").ok(), "martin_cp="); init_tracing(&filter, env::var("MARTIN_CP_FORMAT").ok()); From fc693423ecd4d8ca64fa6a0b1883727bbcfe97c2 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 04:39:11 +0100 Subject: [PATCH 20/39] fix docker CI --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e63851a10..d581c28ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -317,8 +317,8 @@ jobs: PLATFORM=linux/arm64 TAG=${{ github.repository }}:linux export MARTIN_BUILD_ALL=- - export MARTIN_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -v $PWD/tests:/tests $TAG" - export MARTIN_CP_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -v $PWD/tests:/tests --entrypoint /usr/local/bin/martin-cp $TAG" + export MARTIN_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e MARTIN_FORMAT=bare -v $PWD/tests:/tests $TAG" + export MARTIN_CP_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e MARTIN_CP_FORMAT=bare -v $PWD/tests:/tests --entrypoint /usr/local/bin/martin-cp $TAG" export MBTILES_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -v $PWD/tests:/tests --entrypoint /usr/local/bin/mbtiles $TAG" tests/test.sh env: From 6c3f18fddd40332882e8305a4a9b5ae233faddda Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sat, 10 Jan 2026 18:56:46 +0100 Subject: [PATCH 21/39] rework our docker integration CI to be justfile based --- .github/workflows/ci.yml | 19 ++----------------- justfile | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d581c28ee..b37f68bdc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -313,26 +313,11 @@ jobs: platforms: linux/arm64,linux/amd64 - name: Test linux/arm64 Docker image - run: | - PLATFORM=linux/arm64 - TAG=${{ github.repository }}:linux - export MARTIN_BUILD_ALL=- - export MARTIN_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e MARTIN_FORMAT=bare -v $PWD/tests:/tests $TAG" - export MARTIN_CP_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e MARTIN_CP_FORMAT=bare -v $PWD/tests:/tests --entrypoint /usr/local/bin/martin-cp $TAG" - export MBTILES_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -v $PWD/tests:/tests --entrypoint /usr/local/bin/mbtiles $TAG" - tests/test.sh + run: just test-int-in-docker-image linux/arm64 ${{ github.repository }}:linux env: DATABASE_URL: postgres://${{ env.PGUSER }}:${{ env.PGUSER }}@${{ env.PGHOST }}:${{ job.services.postgres.ports[5432] }}/${{ env.PGDATABASE }}?sslmode=require - - name: Test linux/amd64 Docker image - run: | - PLATFORM=linux/amd64 - TAG=${{ github.repository }}:linux - export MARTIN_BUILD_ALL=- - export MARTIN_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -v $PWD/tests:/tests $TAG" - export MARTIN_CP_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -v $PWD/tests:/tests --entrypoint /usr/local/bin/martin-cp $TAG" - export MBTILES_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -v $PWD/tests:/tests --entrypoint /usr/local/bin/mbtiles $TAG" - tests/test.sh + run: just test-int-in-docker-image linux/amd64 ${{ github.repository }}:linux env: DATABASE_URL: postgres://${{ env.PGUSER }}:${{ env.PGUSER }}@${{ env.PGHOST }}:${{ job.services.postgres.ports[5432] }}/${{ env.PGDATABASE }}?sslmode=require diff --git a/justfile b/justfile index 2559e7c16..c19707ba1 100755 --- a/justfile +++ b/justfile @@ -287,6 +287,17 @@ restart: run *args='--webui enable-for-all': cargo run -p martin -- {{args}} +# Run a specified entrypoint of a docker image +run-in-docker-image PLATFORM image entrypoint *args: + docker run --rm --net host \ + --platform {{PLATFORM}} \ + --env DATABASE_URL \ + --env AWS_REGION=eu-central-1 --env AWS_SKIP_CREDENTIALS=1 \ + --env MARTIN_FORMAT=bare -e MARTIN_CP_FORMAT=bare \ + --volume "$PWD/tests:/tests" \ + --entrypoint /usr/local/bin/{{entrypoint}} \ + "{{image}}" -- {{args}} + # Start release-compiled Martin server and a test database run-release *args='--webui enable-for-all': start cargo run -p martin --release -- {{args}} @@ -358,6 +369,23 @@ test-int: clean-test install-sqlx fi fi +# Run integration tests against a docker container +test-int-in-docker-image platform image: + #!/usr/bin/env bash + set -euo pipefail + + if ! command -v docker >/dev/null 2>&1; then + echo "Docker is missing -> https://docs.docker.com/get-docker/" + exit 1 + fi + + export MARTIN_BUILD_ALL="-" + export MARTIN_BIN="{{just}} run-in-docker-image {{platform}} {{image}} martin" + export MARTIN_CP_BIN="{{just}} run-in-docker-image {{platform}} {{image}} martin-cp" + export MBTILES_BIN="{{just}} run-in-docker-image {{platform}} {{image}} mbtiles" + + {{just}} test-int + # Run AWS Lambda smoke test against SAM local test-lambda martin_bin='target/debug/martin': #!/usr/bin/env bash From c2f16e38a8eafd98792e69cccd7b1788fa1da078 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sun, 11 Jan 2026 05:33:22 +0100 Subject: [PATCH 22/39] add just to the docker CI --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b37f68bdc..0b810fb15 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -199,6 +199,8 @@ jobs: run: tests/fixtures/initdb.sh env: PGPORT: ${{ job.services.postgres.ports[5432] }} + - uses: taiki-e/install-action@763e3324d4fd026c9bd284c504378585777a87d5 # v2.62.57 + with: { tool: just } # we want to test our docker images before we push them to the registry # this is done by From e27ae1fbd5e88d82fe92da7925607f1cb1135731 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sun, 11 Jan 2026 05:59:03 +0100 Subject: [PATCH 23/39] make the aws dockerfile more debuggable --- justfile | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/justfile b/justfile index c19707ba1..e7a07a3a8 100755 --- a/justfile +++ b/justfile @@ -391,6 +391,7 @@ test-lambda martin_bin='target/debug/martin': #!/usr/bin/env bash set -euo pipefail + echo "::group::Build Lambda Function" if ! command -v sam >/dev/null 2>&1; then echo "The AWS Serverless Application Model Command Line Interface (AWS SAM CLI) is missing." echo " https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html" @@ -409,16 +410,26 @@ test-lambda martin_bin='target/debug/martin': export AWS_PROFILE=dummy export AWS_CONFIG_FILE=.github/files/dummy-aws-config sam build --template-file .github/files/lambda.yaml + echo "::endgroup::" # Just send a single request using `sam local invoke` to verify that # the server boots, finds a source to serve, and can handle a request. # TODO Run the fuller integration suite against this. # In doing so, switch from `sam local invoke`, which starts and stops the # server, to `sam local start-api`, which keeps it running. - sam local generate-event apigateway http-api-proxy \ - | jq '.rawPath = "/" | .requestContext.http.method = "GET"' \ - | sam local invoke -e - \ - | jq -ne 'input.statusCode==200' + echo "::group::Generate Event" + event=$( + sam local generate-event apigateway http-api-proxy \ + | jq '.rawPath = "/" | .requestContext.http.method = "GET"' + ) + echo "::endgroup::" + + echo "::group::Invoke Lambda Function" + response=$(sam local invoke -e <(echo "$event")) + echo "::endgroup::" + + jq -ne 'input.statusCode == 200' <<<"$response" + # Run all tests using the oldest supported version of the database test-legacy: start-legacy (test-cargo '--all-targets') test-doc test-int From 54a10f75ad9a3efd64dcdfadc5bbcaeb6bd4fcb0 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sun, 11 Jan 2026 06:00:53 +0100 Subject: [PATCH 24/39] add more intel to the aws workflow --- justfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/justfile b/justfile index e7a07a3a8..abbe5e351 100755 --- a/justfile +++ b/justfile @@ -422,6 +422,8 @@ test-lambda martin_bin='target/debug/martin': sam local generate-event apigateway http-api-proxy \ | jq '.rawPath = "/" | .requestContext.http.method = "GET"' ) + echo "event:" + echo "$event" | jq . echo "::endgroup::" echo "::group::Invoke Lambda Function" From aae473dbfdae8556c01b271a48cf474e4fb38c6c Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sun, 11 Jan 2026 13:58:16 +0100 Subject: [PATCH 25/39] try if maybe the quoting is the issue? --- justfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/justfile b/justfile index abbe5e351..7165367ea 100755 --- a/justfile +++ b/justfile @@ -380,9 +380,9 @@ test-int-in-docker-image platform image: fi export MARTIN_BUILD_ALL="-" - export MARTIN_BIN="{{just}} run-in-docker-image {{platform}} {{image}} martin" - export MARTIN_CP_BIN="{{just}} run-in-docker-image {{platform}} {{image}} martin-cp" - export MBTILES_BIN="{{just}} run-in-docker-image {{platform}} {{image}} mbtiles" + export MARTIN_BIN="/home/runner/.cargo/bin/just run-in-docker-image {{platform}} {{image}} martin" + export MARTIN_CP_BIN="/home/runner/.cargo/bin/just run-in-docker-image {{platform}} {{image}} martin-cp" + export MBTILES_BIN="/home/runner/.cargo/bin/just run-in-docker-image {{platform}} {{image}} mbtiles" {{just}} test-int From b8f8c9adbf3918993feec1f445302c6ab02b651e Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sun, 11 Jan 2026 13:58:54 +0100 Subject: [PATCH 26/39] try if arguments are the issue --- justfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/justfile b/justfile index 7165367ea..e2edeeede 100755 --- a/justfile +++ b/justfile @@ -288,7 +288,7 @@ run *args='--webui enable-for-all': cargo run -p martin -- {{args}} # Run a specified entrypoint of a docker image -run-in-docker-image PLATFORM image entrypoint *args: +run-in-docker-image PLATFORM image entrypoint: docker run --rm --net host \ --platform {{PLATFORM}} \ --env DATABASE_URL \ @@ -296,7 +296,7 @@ run-in-docker-image PLATFORM image entrypoint *args: --env MARTIN_FORMAT=bare -e MARTIN_CP_FORMAT=bare \ --volume "$PWD/tests:/tests" \ --entrypoint /usr/local/bin/{{entrypoint}} \ - "{{image}}" -- {{args}} + "{{image}}" -- # Start release-compiled Martin server and a test database run-release *args='--webui enable-for-all': start From 601d94ce6bcc1247ebb459614c988ab039c589e0 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sun, 11 Jan 2026 13:58:57 +0100 Subject: [PATCH 27/39] Revert "try if maybe the quoting is the issue?" This reverts commit aae473dbfdae8556c01b271a48cf474e4fb38c6c. --- justfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/justfile b/justfile index e2edeeede..dd95d2ecb 100755 --- a/justfile +++ b/justfile @@ -380,9 +380,9 @@ test-int-in-docker-image platform image: fi export MARTIN_BUILD_ALL="-" - export MARTIN_BIN="/home/runner/.cargo/bin/just run-in-docker-image {{platform}} {{image}} martin" - export MARTIN_CP_BIN="/home/runner/.cargo/bin/just run-in-docker-image {{platform}} {{image}} martin-cp" - export MBTILES_BIN="/home/runner/.cargo/bin/just run-in-docker-image {{platform}} {{image}} mbtiles" + export MARTIN_BIN="{{just}} run-in-docker-image {{platform}} {{image}} martin" + export MARTIN_CP_BIN="{{just}} run-in-docker-image {{platform}} {{image}} martin-cp" + export MBTILES_BIN="{{just}} run-in-docker-image {{platform}} {{image}} mbtiles" {{just}} test-int From 4b37fd0efa0dcb7db0c98a6815cad22e4c969be6 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sun, 11 Jan 2026 14:54:42 +0100 Subject: [PATCH 28/39] fix naming of env params --- justfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/justfile b/justfile index dd95d2ecb..4981f1141 100755 --- a/justfile +++ b/justfile @@ -159,7 +159,7 @@ debug-page *args: start # Build and run martin docker image docker-run *args: - docker run -it --rm --net host -e DATABASE_URL -v $PWD/tests:/tests ghcr.io/maplibre/martin:1.2.0 {{args}} + docker run -it --rm --net host --env DATABASE_URL -v $PWD/tests:/tests ghcr.io/maplibre/martin:1.2.0 {{args}} # Build and open code documentation docs *args='--open': @@ -293,7 +293,7 @@ run-in-docker-image PLATFORM image entrypoint: --platform {{PLATFORM}} \ --env DATABASE_URL \ --env AWS_REGION=eu-central-1 --env AWS_SKIP_CREDENTIALS=1 \ - --env MARTIN_FORMAT=bare -e MARTIN_CP_FORMAT=bare \ + --env MARTIN_FORMAT=bare --env MARTIN_CP_FORMAT=bare \ --volume "$PWD/tests:/tests" \ --entrypoint /usr/local/bin/{{entrypoint}} \ "{{image}}" -- From 50435615e618941fd3ce2980e7f03d39bd6b8b8f Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sun, 11 Jan 2026 14:54:45 +0100 Subject: [PATCH 29/39] Reapply "try if maybe the quoting is the issue?" This reverts commit 601d94ce6bcc1247ebb459614c988ab039c589e0. --- justfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/justfile b/justfile index 4981f1141..0b9ca54b5 100755 --- a/justfile +++ b/justfile @@ -380,9 +380,9 @@ test-int-in-docker-image platform image: fi export MARTIN_BUILD_ALL="-" - export MARTIN_BIN="{{just}} run-in-docker-image {{platform}} {{image}} martin" - export MARTIN_CP_BIN="{{just}} run-in-docker-image {{platform}} {{image}} martin-cp" - export MBTILES_BIN="{{just}} run-in-docker-image {{platform}} {{image}} mbtiles" + export MARTIN_BIN="/home/runner/.cargo/bin/just run-in-docker-image {{platform}} {{image}} martin" + export MARTIN_CP_BIN="/home/runner/.cargo/bin/just run-in-docker-image {{platform}} {{image}} martin-cp" + export MBTILES_BIN="/home/runner/.cargo/bin/just run-in-docker-image {{platform}} {{image}} mbtiles" {{just}} test-int From e0d30216cd7491bdc3da9f84df71044587325cbc Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sun, 11 Jan 2026 15:00:50 +0100 Subject: [PATCH 30/39] make the just executable name more reliable --- justfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/justfile b/justfile index 0b9ca54b5..94320e69c 100755 --- a/justfile +++ b/justfile @@ -380,9 +380,9 @@ test-int-in-docker-image platform image: fi export MARTIN_BUILD_ALL="-" - export MARTIN_BIN="/home/runner/.cargo/bin/just run-in-docker-image {{platform}} {{image}} martin" - export MARTIN_CP_BIN="/home/runner/.cargo/bin/just run-in-docker-image {{platform}} {{image}} martin-cp" - export MBTILES_BIN="/home/runner/.cargo/bin/just run-in-docker-image {{platform}} {{image}} mbtiles" + export MARTIN_BIN="{{just_executable()}} run-in-docker-image {{platform}} {{image}} martin" + export MARTIN_CP_BIN="{{just_executable()}} run-in-docker-image {{platform}} {{image}} martin-cp" + export MBTILES_BIN="{{just_executable()}} run-in-docker-image {{platform}} {{image}} mbtiles" {{just}} test-int From 468bd134db7163846d60600415353912a3f1cc6e Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Sun, 11 Jan 2026 15:05:04 +0100 Subject: [PATCH 31/39] revert to short names for constency --- justfile | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/justfile b/justfile index 94320e69c..5708664d1 100755 --- a/justfile +++ b/justfile @@ -2,7 +2,8 @@ set shell := ['bash', '-c'] -# How to call the current just executable. Note that just_executable() may have `\` in Windows paths, so we need to quote it. +# How to call the current just executable. +# Note that just_executable() may have `\` in Windows paths, so we need to quote it. just := quote(just_executable()) dockercompose := `if docker-compose --version &> /dev/null; then echo "docker-compose"; else echo "docker compose"; fi` @@ -159,7 +160,7 @@ debug-page *args: start # Build and run martin docker image docker-run *args: - docker run -it --rm --net host --env DATABASE_URL -v $PWD/tests:/tests ghcr.io/maplibre/martin:1.2.0 {{args}} + docker run -it --rm --net host -e DATABASE_URL -v $PWD/tests:/tests ghcr.io/maplibre/martin:1.2.0 {{args}} # Build and open code documentation docs *args='--open': @@ -291,10 +292,10 @@ run *args='--webui enable-for-all': run-in-docker-image PLATFORM image entrypoint: docker run --rm --net host \ --platform {{PLATFORM}} \ - --env DATABASE_URL \ - --env AWS_REGION=eu-central-1 --env AWS_SKIP_CREDENTIALS=1 \ - --env MARTIN_FORMAT=bare --env MARTIN_CP_FORMAT=bare \ - --volume "$PWD/tests:/tests" \ + -e DATABASE_URL \ + -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 \ + -e MARTIN_FORMAT=bare -e MARTIN_CP_FORMAT=bare \ + -v "$PWD/tests:/tests" \ --entrypoint /usr/local/bin/{{entrypoint}} \ "{{image}}" -- From e84f64da87bb88c86e9cf5fed7219570c5193480 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Mon, 12 Jan 2026 05:24:42 +0100 Subject: [PATCH 32/39] fix typo with args after run-in-docker-image being missing --- justfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/justfile b/justfile index 5708664d1..fef02a176 100755 --- a/justfile +++ b/justfile @@ -289,7 +289,7 @@ run *args='--webui enable-for-all': cargo run -p martin -- {{args}} # Run a specified entrypoint of a docker image -run-in-docker-image PLATFORM image entrypoint: +run-in-docker-image PLATFORM image entrypoint *args='': docker run --rm --net host \ --platform {{PLATFORM}} \ -e DATABASE_URL \ @@ -297,7 +297,7 @@ run-in-docker-image PLATFORM image entrypoint: -e MARTIN_FORMAT=bare -e MARTIN_CP_FORMAT=bare \ -v "$PWD/tests:/tests" \ --entrypoint /usr/local/bin/{{entrypoint}} \ - "{{image}}" -- + "{{image}}" -- {{args}} # Start release-compiled Martin server and a test database run-release *args='--webui enable-for-all': start From 6ec4fe44dc43439c47801fd2f8e3c03c38f8d785 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Mon, 12 Jan 2026 05:57:11 +0100 Subject: [PATCH 33/39] Apply suggestion from @CommanderStorm --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b810fb15..d9ad248c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -200,7 +200,7 @@ jobs: env: PGPORT: ${{ job.services.postgres.ports[5432] }} - uses: taiki-e/install-action@763e3324d4fd026c9bd284c504378585777a87d5 # v2.62.57 - with: { tool: just } + with: { tool: just,cargo-sqlx } # we want to test our docker images before we push them to the registry # this is done by From b2328ac58405f70ffec52c952311b1b28807e101 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Mon, 12 Jan 2026 17:54:45 +0100 Subject: [PATCH 34/39] minimise the CI change to another PR --- .github/workflows/ci.yml | 20 +++++++++++++++++--- justfile | 28 ---------------------------- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d9ad248c0..fd4216d71 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -200,7 +200,7 @@ jobs: env: PGPORT: ${{ job.services.postgres.ports[5432] }} - uses: taiki-e/install-action@763e3324d4fd026c9bd284c504378585777a87d5 # v2.62.57 - with: { tool: just,cargo-sqlx } + with: { tool: cargo-sqlx } # we want to test our docker images before we push them to the registry # this is done by @@ -315,11 +315,25 @@ jobs: platforms: linux/arm64,linux/amd64 - name: Test linux/arm64 Docker image - run: just test-int-in-docker-image linux/arm64 ${{ github.repository }}:linux + run: | + PLATFORM=linux/arm64 + TAG=${{ github.repository }}:linux + export MARTIN_BUILD_ALL=- + export MARTIN_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e MARTIN_FORMAT=bare -v $PWD/tests:/tests $TAG" + export MARTIN_CP_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e MARTIN_CP_FORMAT=bare -v $PWD/tests:/tests --entrypoint /usr/local/bin/martin-cp $TAG" + export MBTILES_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -v $PWD/tests:/tests --entrypoint /usr/local/bin/mbtiles $TAG" + tests/test.sh env: DATABASE_URL: postgres://${{ env.PGUSER }}:${{ env.PGUSER }}@${{ env.PGHOST }}:${{ job.services.postgres.ports[5432] }}/${{ env.PGDATABASE }}?sslmode=require - name: Test linux/amd64 Docker image - run: just test-int-in-docker-image linux/amd64 ${{ github.repository }}:linux + run: | + PLATFORM=linux/amd64 + TAG=${{ github.repository }}:linux + export MARTIN_BUILD_ALL=- + export MARTIN_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e MARTIN_FORMAT=bare -v $PWD/tests:/tests $TAG" + export MARTIN_CP_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e MARTIN_CP_FORMAT=bare -v $PWD/tests:/tests --entrypoint /usr/local/bin/martin-cp $TAG" + export MBTILES_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -v $PWD/tests:/tests --entrypoint /usr/local/bin/mbtiles $TAG" + tests/test.sh env: DATABASE_URL: postgres://${{ env.PGUSER }}:${{ env.PGUSER }}@${{ env.PGHOST }}:${{ job.services.postgres.ports[5432] }}/${{ env.PGDATABASE }}?sslmode=require diff --git a/justfile b/justfile index fef02a176..c888697df 100755 --- a/justfile +++ b/justfile @@ -288,17 +288,6 @@ restart: run *args='--webui enable-for-all': cargo run -p martin -- {{args}} -# Run a specified entrypoint of a docker image -run-in-docker-image PLATFORM image entrypoint *args='': - docker run --rm --net host \ - --platform {{PLATFORM}} \ - -e DATABASE_URL \ - -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 \ - -e MARTIN_FORMAT=bare -e MARTIN_CP_FORMAT=bare \ - -v "$PWD/tests:/tests" \ - --entrypoint /usr/local/bin/{{entrypoint}} \ - "{{image}}" -- {{args}} - # Start release-compiled Martin server and a test database run-release *args='--webui enable-for-all': start cargo run -p martin --release -- {{args}} @@ -370,23 +359,6 @@ test-int: clean-test install-sqlx fi fi -# Run integration tests against a docker container -test-int-in-docker-image platform image: - #!/usr/bin/env bash - set -euo pipefail - - if ! command -v docker >/dev/null 2>&1; then - echo "Docker is missing -> https://docs.docker.com/get-docker/" - exit 1 - fi - - export MARTIN_BUILD_ALL="-" - export MARTIN_BIN="{{just_executable()}} run-in-docker-image {{platform}} {{image}} martin" - export MARTIN_CP_BIN="{{just_executable()}} run-in-docker-image {{platform}} {{image}} martin-cp" - export MBTILES_BIN="{{just_executable()}} run-in-docker-image {{platform}} {{image}} mbtiles" - - {{just}} test-int - # Run AWS Lambda smoke test against SAM local test-lambda martin_bin='target/debug/martin': #!/usr/bin/env bash From 055add5be1365d4e2ca50f35853b8e39bdf4d503 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Mon, 12 Jan 2026 18:03:26 +0100 Subject: [PATCH 35/39] add to docs --- docs/src/getting-involved.md | 2 +- docs/src/pg-ssl-certificates.md | 2 +- docs/src/troubleshooting.md | 11 ++++++++--- martin/src/bin/martin-cp.rs | 2 +- martin/src/bin/martin.rs | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/src/getting-involved.md b/docs/src/getting-involved.md index 1dbc20f30..0143cefb3 100644 --- a/docs/src/getting-involved.md +++ b/docs/src/getting-involved.md @@ -125,7 +125,7 @@ We add a breakpoint here in the [start of martin](https://github.com/maplibre/ma ```rust, ignore use clap::Parser; -use log::{error, info, log_enabled}; +use tracing::{error, info}; use martin::args::{Args, OsEnv}; use martin::srv::new_server; use martin::{read_config, Config, MartinResult}; diff --git a/docs/src/pg-ssl-certificates.md b/docs/src/pg-ssl-certificates.md index a7c0f3d6f..d5034480e 100644 --- a/docs/src/pg-ssl-certificates.md +++ b/docs/src/pg-ssl-certificates.md @@ -210,7 +210,7 @@ export PGSSLROOTCERT=./ca-cert.pem psql -h localhost -U postgres -d postgres -v # Debug Martin -RUST_LOG=debug martin postgres://... +RUST_LOG=debug MARTIN_FORMAT=pretty martin postgres://... ``` These are the errors that can occur: diff --git a/docs/src/troubleshooting.md b/docs/src/troubleshooting.md index 7a2177987..674cc9538 100644 --- a/docs/src/troubleshooting.md +++ b/docs/src/troubleshooting.md @@ -1,13 +1,14 @@ ## Troubleshooting -Log levels are controlled on a per-module basis, and by default all logging is disabled except for errors. Logging is -controlled via the `RUST_LOG` environment variable. The value of this environment variable is a comma-separated list of -logging directives. +Log levels are controlled on a per-module basis, and by default all logging is disabled except for errors. +Logging is controlled via the `RUST_LOG` environment variable. +The value of this environment variable is a comma-separated list of logging directives. This will enable debug logging for all modules: ```bash export RUST_LOG=debug +export MARTIN_FORMAT=pretty martin postgres://postgres@localhost/db ``` @@ -16,5 +17,9 @@ and `tokio_postgres` modules: ```bash export RUST_LOG=actix_web=info,martin=debug,tokio_postgres=debug +export MARTIN_FORMAT=pretty martin postgres://postgres@localhost/db ``` + +We also allow you to control the format of the logs via the `MARTIN_FORMAT` environment variable. +For troubleshooting, `pretty` or `full` are likely the most useful formats. diff --git a/martin/src/bin/martin-cp.rs b/martin/src/bin/martin-cp.rs index 16163780b..f1695a9de 100644 --- a/martin/src/bin/martin-cp.rs +++ b/martin/src/bin/martin-cp.rs @@ -584,7 +584,7 @@ async fn main() { let args = CopierArgs::parse(); if let Err(e) = start(args).await { // Ensure the message is printed, even if the logging is disabled - if log::log_enabled!(log::Level::Error) { + if tracing::event_enabled!(tracing::Level::ERROR) { error!("{e}"); } else { eprintln!("{e}"); diff --git a/martin/src/bin/martin.rs b/martin/src/bin/martin.rs index c4cfbfdfd..9b57bcd83 100644 --- a/martin/src/bin/martin.rs +++ b/martin/src/bin/martin.rs @@ -61,7 +61,7 @@ async fn main() { let args = Args::parse(); if let Err(e) = start(args).await { // Ensure the message is printed, even if the logging is disabled - if log::log_enabled!(log::Level::Error) { + if tracing::event_enabled!(tracing::Level::ERROR) { error!("{e}"); } else { eprintln!("{e}"); From 08a6ea88fcb4e9b566644826a48ad0d55edf9834 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Mon, 12 Jan 2026 18:14:12 +0100 Subject: [PATCH 36/39] how did this make it past CI???? --- martin/src/bin/martin-cp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/martin/src/bin/martin-cp.rs b/martin/src/bin/martin-cp.rs index a3d7b35d8..4008451d3 100644 --- a/martin/src/bin/martin-cp.rs +++ b/martin/src/bin/martin-cp.rs @@ -300,7 +300,7 @@ enum MartinCpError { InvalidBoundingBox(&'static str, Bounds, RangeInclusive), } -fn write_duration(f: &mut impl Write, secs: f32) -> std::fmt::Result { +fn write_duration(f: &mut impl std::fmt::Write, secs: f32) -> std::fmt::Result { if !secs.is_normal() || secs < 0. { // Nonsense input f.write_str("???") From adb10322982445c018adddee0bdeffcd6e6d01e1 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Mon, 12 Jan 2026 18:36:19 +0100 Subject: [PATCH 37/39] Apply suggestion from @CommanderStorm --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eaa0c01bd..701e91811 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -214,7 +214,7 @@ jobs: env: PGPORT: ${{ job.services.postgres.ports[5432] }} - uses: taiki-e/install-action@763e3324d4fd026c9bd284c504378585777a87d5 # v2.62.57 - with: { tool: cargo-sqlx } + with: { tool: sqlx } # we want to test our docker images before we push them to the registry # this is done by From d8330b02626890f70c77da1d53e4076184dfbadb Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Mon, 12 Jan 2026 19:33:10 +0100 Subject: [PATCH 38/39] Apply suggestion from @CommanderStorm --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 701e91811..0265c8ae3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -214,7 +214,7 @@ jobs: env: PGPORT: ${{ job.services.postgres.ports[5432] }} - uses: taiki-e/install-action@763e3324d4fd026c9bd284c504378585777a87d5 # v2.62.57 - with: { tool: sqlx } + with: { tool: sqlx-cli } # we want to test our docker images before we push them to the registry # this is done by From 45345de80801cfeec6311bd9cd159b34e2a76322 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Tue, 13 Jan 2026 10:04:26 +0100 Subject: [PATCH 39/39] MARTIN_FORMAT -> RUST_LOG_FORMAT --- .github/workflows/ci.yml | 8 ++++---- docs/src/pg-ssl-certificates.md | 2 +- docs/src/troubleshooting.md | 6 +++--- martin/src/bin/martin-cp.rs | 4 ++-- martin/src/bin/martin.rs | 2 +- martin/src/config/args/root.rs | 2 +- tests/test.sh | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0265c8ae3..506b2df0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -333,8 +333,8 @@ jobs: PLATFORM=linux/arm64 TAG=${{ github.repository }}:linux export MARTIN_BUILD_ALL=- - export MARTIN_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e MARTIN_FORMAT=bare -v $PWD/tests:/tests $TAG" - export MARTIN_CP_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e MARTIN_CP_FORMAT=bare -v $PWD/tests:/tests --entrypoint /usr/local/bin/martin-cp $TAG" + export MARTIN_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e RUST_LOG_FORMAT=bare -v $PWD/tests:/tests $TAG" + export MARTIN_CP_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e RUST_LOG_FORMAT=bare -v $PWD/tests:/tests --entrypoint /usr/local/bin/martin-cp $TAG" export MBTILES_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -v $PWD/tests:/tests --entrypoint /usr/local/bin/mbtiles $TAG" tests/test.sh env: @@ -344,8 +344,8 @@ jobs: PLATFORM=linux/amd64 TAG=${{ github.repository }}:linux export MARTIN_BUILD_ALL=- - export MARTIN_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e MARTIN_FORMAT=bare -v $PWD/tests:/tests $TAG" - export MARTIN_CP_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e MARTIN_CP_FORMAT=bare -v $PWD/tests:/tests --entrypoint /usr/local/bin/martin-cp $TAG" + export MARTIN_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e RUST_LOG_FORMAT=bare -v $PWD/tests:/tests $TAG" + export MARTIN_CP_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -e RUST_LOG_FORMAT=bare -v $PWD/tests:/tests --entrypoint /usr/local/bin/martin-cp $TAG" export MBTILES_BIN="docker run --rm --net host --platform $PLATFORM -e DATABASE_URL -e AWS_REGION=eu-central-1 -e AWS_SKIP_CREDENTIALS=1 -v $PWD/tests:/tests --entrypoint /usr/local/bin/mbtiles $TAG" tests/test.sh env: diff --git a/docs/src/pg-ssl-certificates.md b/docs/src/pg-ssl-certificates.md index d5034480e..89c200759 100644 --- a/docs/src/pg-ssl-certificates.md +++ b/docs/src/pg-ssl-certificates.md @@ -210,7 +210,7 @@ export PGSSLROOTCERT=./ca-cert.pem psql -h localhost -U postgres -d postgres -v # Debug Martin -RUST_LOG=debug MARTIN_FORMAT=pretty martin postgres://... +RUST_LOG=debug RUST_LOG_FORMAT=pretty martin postgres://... ``` These are the errors that can occur: diff --git a/docs/src/troubleshooting.md b/docs/src/troubleshooting.md index 674cc9538..40678af99 100644 --- a/docs/src/troubleshooting.md +++ b/docs/src/troubleshooting.md @@ -8,7 +8,7 @@ This will enable debug logging for all modules: ```bash export RUST_LOG=debug -export MARTIN_FORMAT=pretty +export RUST_LOG_FORMAT=pretty martin postgres://postgres@localhost/db ``` @@ -17,9 +17,9 @@ and `tokio_postgres` modules: ```bash export RUST_LOG=actix_web=info,martin=debug,tokio_postgres=debug -export MARTIN_FORMAT=pretty +export RUST_LOG_FORMAT=pretty martin postgres://postgres@localhost/db ``` -We also allow you to control the format of the logs via the `MARTIN_FORMAT` environment variable. +We also allow you to control the format of the logs via the `RUST_LOG_FORMAT` environment variable. For troubleshooting, `pretty` or `full` are likely the most useful formats. diff --git a/martin/src/bin/martin-cp.rs b/martin/src/bin/martin-cp.rs index 4008451d3..48823f3e2 100644 --- a/martin/src/bin/martin-cp.rs +++ b/martin/src/bin/martin-cp.rs @@ -52,7 +52,7 @@ const HELP_STYLES: Styles = Styles::styled() #[command( about = "A tool to bulk copy tiles from any Martin-supported sources into an mbtiles file", version, - after_help = "Use RUST_LOG environment variable to control logging level, e.g. RUST_LOG=debug or RUST_LOG=martin_cp=debug.\nUse MARTIN_CP_FORMAT environment variable to control output format: json, full, compact (default), bare or pretty.\nSee https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html for more information.", + after_help = "Use RUST_LOG environment variable to control logging level, e.g. RUST_LOG=debug or RUST_LOG=martin_cp=debug.\nUse RUST_LOG_FORMAT environment variable to control output format: json, full, compact (default), bare or pretty.\nSee https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html for more information.", styles = HELP_STYLES )] pub struct CopierArgs { @@ -623,7 +623,7 @@ async fn init_schema( #[tokio::main] async fn main() { let filter = ensure_martin_core_log_level_matches(env::var("RUST_LOG").ok(), "martin_cp="); - init_tracing(&filter, env::var("MARTIN_CP_FORMAT").ok()); + init_tracing(&filter, env::var("RUST_LOG_FORMAT").ok()); let args = CopierArgs::parse(); if let Err(e) = start(args).await { diff --git a/martin/src/bin/martin.rs b/martin/src/bin/martin.rs index 9b57bcd83..c085903f6 100644 --- a/martin/src/bin/martin.rs +++ b/martin/src/bin/martin.rs @@ -56,7 +56,7 @@ async fn start(args: Args) -> MartinResult<()> { #[tokio::main] async fn main() { let filter = ensure_martin_core_log_level_matches(env::var("RUST_LOG").ok(), "martin="); - init_tracing(&filter, env::var("MARTIN_FORMAT").ok()); + init_tracing(&filter, env::var("RUST_LOG_FORMAT").ok()); let args = Args::parse(); if let Err(e) = start(args).await { diff --git a/martin/src/config/args/root.rs b/martin/src/config/args/root.rs index b91daa7ad..e0ce905ae 100644 --- a/martin/src/config/args/root.rs +++ b/martin/src/config/args/root.rs @@ -34,7 +34,7 @@ const HELP_STYLES: Styles = Styles::styled() #[command( about, version, - after_help = "Use RUST_LOG environment variable to control logging level, e.g. RUST_LOG=debug or RUST_LOG=martin=debug.\nUse MARTIN_FORMAT environment variable to control output format: json, full, compact (default), bare or pretty.\nSee https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html for more information.", + after_help = "Use RUST_LOG environment variable to control logging level, e.g. RUST_LOG=debug or RUST_LOG=martin=debug.\nUse RUST_LOG_FORMAT environment variable to control output format: json, full, compact (default), bare or pretty.\nSee https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html for more information.", styles = HELP_STYLES )] pub struct Args { diff --git a/tests/test.sh b/tests/test.sh index 7d958eca8..b32527ac2 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -4,7 +4,7 @@ set -euo pipefail MARTIN_DATABASE_URL="${DATABASE_URL:-postgres://postgres@localhost/db}" unset DATABASE_URL -export MARTIN_FORMAT=bare +export RUST_LOG_FORMAT=bare # TODO: use --fail-with-body to get the response body on failure CURL=${CURL:-curl --silent --show-error --fail --compressed}