From 2c243a3cb814939bbe40fda1608781825ab0d77d Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 22 Feb 2026 10:29:19 +0900 Subject: feat(tracing): add performance profiling via tracing crate Wire up the existing --profile flag with tracing-subscriber to emit span timings on stderr. Supports MOZART_LOG env var override and verbose-level-aware filtering. No subscriber is installed when --profile is off, keeping tracing macros zero-cost. Co-Authored-By: Claude Opus 4.6 --- Cargo.lock | 95 +++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 + crates/mozart-autoload/Cargo.toml | 1 + crates/mozart-core/Cargo.toml | 1 + crates/mozart-registry/Cargo.toml | 1 + crates/mozart/Cargo.toml | 2 + crates/mozart/src/commands.rs | 41 +++++++++++++++++ crates/mozart/src/main.rs | 36 +++++++++++++++ 8 files changed, 179 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 5e7b497..9051a53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -932,6 +932,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.181" @@ -983,6 +989,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + [[package]] name = "md5" version = "0.7.0" @@ -1044,6 +1059,8 @@ dependencies = [ "serde_json", "sha1", "tempfile", + "tracing", + "tracing-subscriber", ] [[package]] @@ -1072,6 +1089,7 @@ dependencies = [ "serde", "serde_json", "tempfile", + "tracing", ] [[package]] @@ -1089,6 +1107,7 @@ dependencies = [ "serde", "serde_json", "tempfile", + "tracing", ] [[package]] @@ -1110,6 +1129,7 @@ dependencies = [ "tar", "tempfile", "tokio", + "tracing", "zip", ] @@ -1119,6 +1139,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" +[[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-traits" version = "0.2.19" @@ -1690,6 +1719,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 = "shell-words" version = "1.1.1" @@ -1879,6 +1917,15 @@ dependencies = [ "syn", ] +[[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 = "tinystr" version = "0.8.2" @@ -2007,9 +2054,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" version = "0.1.36" @@ -2017,6 +2076,36 @@ 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 = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -2073,6 +2162,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "version-ranges" version = "0.1.2" diff --git a/Cargo.toml b/Cargo.toml index 8d93856..9d0691a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,8 @@ sha1 = "0.10" tar = "0.4" tempfile = "3.25.0" tokio = { version = "1.49.0", features = ["full"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] } zip = { version = "2", default-features = false, features = ["deflate"] } assert_cmd = "2" predicates = "3" diff --git a/crates/mozart-autoload/Cargo.toml b/crates/mozart-autoload/Cargo.toml index 6aba8ab..84ec08a 100644 --- a/crates/mozart-autoload/Cargo.toml +++ b/crates/mozart-autoload/Cargo.toml @@ -11,6 +11,7 @@ md5.workspace = true regex.workspace = true serde.workspace = true serde_json.workspace = true +tracing.workspace = true [dev-dependencies] tempfile.workspace = true diff --git a/crates/mozart-core/Cargo.toml b/crates/mozart-core/Cargo.toml index 25210be..85a5c9f 100644 --- a/crates/mozart-core/Cargo.toml +++ b/crates/mozart-core/Cargo.toml @@ -10,6 +10,7 @@ dialoguer.workspace = true regex.workspace = true serde.workspace = true serde_json.workspace = true +tracing.workspace = true [dev-dependencies] tempfile.workspace = true diff --git a/crates/mozart-registry/Cargo.toml b/crates/mozart-registry/Cargo.toml index 964e0a1..a048f91 100644 --- a/crates/mozart-registry/Cargo.toml +++ b/crates/mozart-registry/Cargo.toml @@ -19,4 +19,5 @@ sha1.workspace = true tar.workspace = true tempfile.workspace = true tokio.workspace = true +tracing.workspace = true zip.workspace = true diff --git a/crates/mozart/Cargo.toml b/crates/mozart/Cargo.toml index 8a803fa..ec35e24 100644 --- a/crates/mozart/Cargo.toml +++ b/crates/mozart/Cargo.toml @@ -20,6 +20,8 @@ serde.workspace = true serde_json.workspace = true sha1.workspace = true tempfile.workspace = true +tracing.workspace = true +tracing-subscriber.workspace = true [dev-dependencies] assert_cmd.workspace = true diff --git a/crates/mozart/src/commands.rs b/crates/mozart/src/commands.rs index a745b3a..7b94f4d 100644 --- a/crates/mozart/src/commands.rs +++ b/crates/mozart/src/commands.rs @@ -197,6 +197,47 @@ pub enum Commands { Validate(validate::ValidateArgs), } +impl Commands { + pub fn name(&self) -> &'static str { + match self { + Commands::About(_) => "about", + Commands::Archive(_) => "archive", + Commands::Audit(_) => "audit", + Commands::Browse(_) => "browse", + Commands::Bump(_) => "bump", + Commands::CheckPlatformReqs(_) => "check-platform-reqs", + Commands::ClearCache(_) => "clear-cache", + Commands::Completion(_) => "completion", + Commands::Config(_) => "config", + Commands::CreateProject(_) => "create-project", + Commands::Depends(_) => "depends", + Commands::Diagnose(_) => "diagnose", + Commands::DumpAutoload(_) => "dump-autoload", + Commands::Exec(_) => "exec", + Commands::Fund(_) => "fund", + Commands::Global(_) => "global", + Commands::Init(_) => "init", + Commands::Install(_) => "install", + Commands::Licenses(_) => "licenses", + Commands::Outdated(_) => "outdated", + Commands::Prohibits(_) => "prohibits", + Commands::Reinstall(_) => "reinstall", + Commands::Remove(_) => "remove", + Commands::Repository(_) => "repository", + Commands::Require(_) => "require", + Commands::RunScript(_) => "run-script", + Commands::Search(_) => "search", + Commands::SelfUpdate(_) => "self-update", + Commands::Show(_) => "show", + Commands::Status(_) => "status", + Commands::Suggests(_) => "suggests", + Commands::Update(_) => "update", + Commands::Validate(_) => "validate", + } + } +} + +#[tracing::instrument(skip(cli), fields(command = cli.command.name()))] pub fn execute(cli: &Cli) -> anyhow::Result<()> { let console = mozart_core::console::Console::new( cli.verbose, diff --git a/crates/mozart/src/main.rs b/crates/mozart/src/main.rs index 59ad392..ebe84e5 100644 --- a/crates/mozart/src/main.rs +++ b/crates/mozart/src/main.rs @@ -1,9 +1,45 @@ use clap::Parser; use mozart::commands; use mozart_core::exit_code; +use tracing_subscriber::{fmt, prelude::*, EnvFilter}; + +fn init_tracing(profile: bool, verbose: u8, quiet: bool) { + // MOZART_LOG environment variable takes highest priority. + if let Ok(env_filter) = EnvFilter::try_from_env("MOZART_LOG") { + tracing_subscriber::registry() + .with(fmt::layer().with_writer(std::io::stderr)) + .with(env_filter) + .init(); + return; + } + + if profile { + let filter = match verbose { + 0 => "mozart=info", + 1 | 2 => "mozart=debug", + _ => "mozart=trace", + }; + tracing_subscriber::registry() + .with( + fmt::layer() + .with_writer(std::io::stderr) + .with_timer(fmt::time::uptime()) + .with_span_events(fmt::format::FmtSpan::CLOSE), + ) + .with(EnvFilter::new(filter)) + .init(); + } else if verbose >= 3 && !quiet { + tracing_subscriber::registry() + .with(fmt::layer().with_writer(std::io::stderr).with_target(false)) + .with(EnvFilter::new("mozart=debug")) + .init(); + } + // Otherwise: no subscriber installed → tracing macros are effectively zero-cost no-ops. +} fn main() { let cli = commands::Cli::parse(); + init_tracing(cli.profile, cli.verbose, cli.quiet); match commands::execute(&cli) { Ok(()) => {} Err(e) => { -- cgit v1.3.1