diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be27530..1f0b06d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: test: strategy: matrix: - rust-version: [ "1.80.0", "stable" ] + rust-version: [ "1.91.0", "stable" ] runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index 085642b..ef99786 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,15 +17,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - [[package]] name = "anyhow" version = "1.0.94" @@ -90,11 +81,10 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "colored" -version = "2.2.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" dependencies = [ - "lazy_static", "windows-sys", ] @@ -108,16 +98,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "env_filter" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" -dependencies = [ - "log", - "regex", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -198,25 +178,29 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jiff" -version = "0.1.15" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db69f08d4fb10524cacdb074c10b296299d71274ddbc830a8ee65666867002e9" +checksum = "3590fea8e9e22d449600c9bbd481a8163bef223e4ff938e5f55899f8cf1adb93" dependencies = [ "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", "windows-sys", ] [[package]] name = "jiff-tzdb" -version = "0.1.1" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91335e575850c5c4c673b9bd467b0e025f164ca59d0564f69d0c2ee0ffad4653" +checksum = "c900ef84826f1338a557697dc8fc601df9ca9af4ac137c7fb61d4c6f2dfd3076" [[package]] name = "jiff-tzdb-platform" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9835f0060a626fe59f160437bc725491a6af23133ea906500027d1bd2f8f4329" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" dependencies = [ "jiff-tzdb", ] @@ -231,12 +215,6 @@ 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.169" @@ -255,20 +233,19 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" [[package]] name = "logcall" -version = "0.1.13" +version = "0.2.0" dependencies = [ "async-trait", "fastrace", "log", "logforth", "pollster", - "proc-macro-error2", "proc-macro2", "quote", "syn 2.0.90", @@ -278,15 +255,79 @@ dependencies = [ [[package]] name = "logforth" -version = "0.19.1" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "522000d3921e4b089de59204d2d3ca8792cd53f8ce5a54b5ac8b9a6e867259f0" +dependencies = [ + "log", + "logforth-append-file", + "logforth-bridge-log", + "logforth-core", + "logforth-filter-rustlog", + "logforth-layout-json", + "logforth-layout-text", +] + +[[package]] +name = "logforth-append-file" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80f4ed78a03a30c12285135d98330f0f5d53cb0019bd1ac6d66863dae72d8d52" +dependencies = [ + "jiff", + "logforth-core", +] + +[[package]] +name = "logforth-bridge-log" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "259905c31349678ab17e196b0ca240a729d3d64756fa34e589b9b5debca3b6d6" +checksum = "9c7224c78547e542572ae4d1f787f96c4395a4c3f24513bf221bd8e49888f610" +dependencies = [ + "log", + "logforth-core", +] + +[[package]] +name = "logforth-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "400ba5305e0cb6819efa6c2c503020562eb5b47fd53c91c935be55af1ffd374e" dependencies = [ "anyhow", + "serde", +] + +[[package]] +name = "logforth-filter-rustlog" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e8431cfa1d3eeca479c363651320a66c7003350528f678b30e8c1474fb0d802" +dependencies = [ + "logforth-core", +] + +[[package]] +name = "logforth-layout-json" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d86a105f8f32151ca1e0a6d4097d478badb02d5715239ba0fa431a188a5d966" +dependencies = [ + "jiff", + "logforth-core", + "serde", + "serde_json", +] + +[[package]] +name = "logforth-layout-text" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eafe007ac55293d807e8c7f5a23002e2518d32e476e195443cde23e7845416a" +dependencies = [ "colored", - "env_filter", "jiff", - "log", + "logforth-core", ] [[package]] @@ -384,6 +425,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "portable-atomic-util" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +dependencies = [ + "portable-atomic", +] + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -472,35 +528,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - [[package]] name = "rtrb" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index f58653b..5194752 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "logcall" -version = "0.1.13" -edition = "2021" -rust-version = "1.80.0" +version = "0.2.0" +edition = "2024" +rust-version = "1.91.0" description = "An attribute macro that logs the function return value." repository = "https://github.com/fast/logcall" documentation = "https://docs.rs/logcall" @@ -15,7 +15,6 @@ license = "MIT" proc-macro = true [dependencies] -proc-macro-error2 = { version = "2" } proc-macro2 = { version = "1" } quote = { version = "1" } syn = { version = "2", features = [ @@ -29,8 +28,8 @@ syn = { version = "2", features = [ [dev-dependencies] async-trait = { version = "0.1" } fastrace = { version = "0.7" } -log = { version = "0.4" } -logforth = { version = "0.19" } +log = { version = "0.4.32" } +logforth = { version = "0.30.1", features = ["starter-log"] } pollster = { version = "0.4" } tokio = { version = "1", features = ["rt-multi-thread", "macros"] } trybuild = { version = "1" } diff --git a/LICENSE b/LICENSE index 7e3711c..ea1fb20 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2023-2025 FastLabs Developers +Copyright (c) 2023-2026 FastLabs Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index ae3eaa5..85e6952 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,7 @@ Annotate functions with `#[logcall]` and configure logging with `logforth`: ```rust use logcall::logcall; -use logforth::append; -use logforth::filter::EnvFilter; +use logforth::record::LevelFilter; /// Logs the function call at the default `debug` level. #[logcall] @@ -79,11 +78,8 @@ fn ping(a: i32) -> i32 { } fn main() { - logforth::builder() - .dispatch(|d| { - d.filter(EnvFilter::from_default_env_or("trace")) - .append(append::Stderr::default()) - }) + logforth::starter_log::stdout() + .filter(LevelFilter::All) .apply(); add(2, 3); @@ -102,21 +98,21 @@ fn main() { cargo run --example main ``` -Sample output (from 2025-12-11): +Sample output: ```plaintext -2025-12-11T23:08:39.201289+08:00[Asia/Shanghai] DEBUG main: main.rs:6 main::add(a = 2, b = 3) => 5 -2025-12-11T23:08:39.211065+08:00[Asia/Shanghai] INFO main: main.rs:12 main::multiply(a = 2, b = 3) => 6 -2025-12-11T23:08:39.211086+08:00[Asia/Shanghai] ERROR main: main.rs:18 main::divide(a = 2, b = 0) => Err("Division by zero") -2025-12-11T23:08:39.211118+08:00[Asia/Shanghai] ERROR main: main.rs:28 main::divide2(a = 2, b = 0) => Err("Division by zero") -2025-12-11T23:08:39.211148+08:00[Asia/Shanghai] DEBUG main: main.rs:38 main::subtract(a = 3, ..) => 1 -2025-12-11T23:08:39.211162+08:00[Asia/Shanghai] DEBUG main: main.rs:44 main::negate(a = 5): -5 -2025-12-11T23:08:39.211172+08:00[Asia/Shanghai] DEBUG main: main.rs:50 main::ping(a = 42) +2026-06-11T15:06:32.853867+08:00 DEBUG main: main.rs:5 main::add(a = 2, b = 3) => 5 +2026-06-11T15:06:32.853920+08:00 INFO main: main.rs:11 main::multiply(a = 2, b = 3) => 6 +2026-06-11T15:06:32.853928+08:00 ERROR main: main.rs:17 main::divide(a = 2, b = 0) => Err("Division by zero") +2026-06-11T15:06:32.853934+08:00 ERROR main: main.rs:27 main::divide2(a = 2, b = 0) => Err("divide by zero") +2026-06-11T15:06:32.853939+08:00 DEBUG main: main.rs:33 main::subtract(a = 3, ..) => 1 +2026-06-11T15:06:32.853943+08:00 DEBUG main: main.rs:39 main::negate(a = 5): -5 +2026-06-11T15:06:32.853947+08:00 DEBUG main: main.rs:45 main::ping(a = 42) ``` ## Minimum Supported Rust Version (MSRV) -This crate is built against the latest stable release, and its minimum supported rustc version is 1.80.0. +This crate is built against the latest stable release, and its minimum supported rustc version is 1.91.0. The policy is that the minimum Rust version required to use this crate can be increased in minor version updates. For example, if Logcall 1.0 requires Rust 1.20.0, then Logcall 1.0.z for all values of z will also require Rust 1.20.0 or newer. However, Logcall 1.y for y > 0 may require a newer minimum version of Rust. diff --git a/examples/main.rs b/examples/main.rs index 4bcf981..84f1928 100644 --- a/examples/main.rs +++ b/examples/main.rs @@ -1,6 +1,5 @@ use logcall::logcall; -use logforth::append; -use logforth::filter::EnvFilter; +use logforth::record::LevelFilter; /// Logs the function call at the default `debug` level. #[logcall] @@ -27,11 +26,7 @@ fn divide(a: i32, b: i32) -> Result { /// Logs errors at the `error` level. No log output for `Ok` variant. #[logcall(err = "error")] fn divide2(a: usize, b: usize) -> Result { - if b == 0 { - Err("Division by zero".to_string()) - } else { - Ok(a / b) - } + a.checked_div(b).ok_or("divide by zero".into()) } /// Logs the function call with custom input logging format. @@ -53,11 +48,8 @@ fn ping(a: i32) -> i32 { } fn main() { - logforth::builder() - .dispatch(|d| { - d.filter(EnvFilter::from_default_env_or("trace")) - .append(append::Stderr::default()) - }) + logforth::starter_log::stdout() + .filter(LevelFilter::All) .apply(); add(2, 3); diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..a1a83fd --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,5 @@ +comment_width = 120 +format_code_in_doc_comments = true +group_imports = "StdExternalCrate" +imports_granularity = "Item" +wrap_comments = true diff --git a/src/lib.rs b/src/lib.rs index 393d9cb..c193ab6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,11 +9,6 @@ // [1] https://github.com/tokio-rs/tracing/blob/6a61897a/tracing-attributes/src/expand.rs use proc_macro2::Span; -use proc_macro_error2::abort_call_site; -use proc_macro_error2::proc_macro_error; -use syn::parse::Parse; -use syn::parse::ParseStream; -use syn::spanned::Spanned; use syn::Block; use syn::Expr; use syn::ExprAsync; @@ -30,6 +25,9 @@ use syn::Path; use syn::Signature; use syn::Stmt; use syn::Token; +use syn::parse::Parse; +use syn::parse::ParseStream; +use syn::spanned::Spanned; #[derive(Debug)] enum Args { @@ -145,7 +143,7 @@ impl Parse for Args { return Err(syn::Error::new( ident.span(), "unknown attribute argument", - )) + )); } } } else { @@ -172,12 +170,16 @@ impl Parse for Args { if ok_level.is_some() || err_level.is_some() { if simple_level.is_some() { - abort_call_site!("plain level cannot be specified with `ok` or `err` levels"); + return Err(syn::Error::new( + Span::call_site(), + "plain level cannot be specified with `ok` or `err` levels", + )); } if some_level.is_some() || none_level.is_some() { - abort_call_site!( - "`some` and `none` levels cannot be specified with `ok` or `err` levels" - ); + return Err(syn::Error::new( + Span::call_site(), + "`some` and `none` levels cannot be specified with `ok` or `err` levels", + )); } Ok(Args::Result { ok_level, @@ -187,7 +189,10 @@ impl Parse for Args { }) } else if some_level.is_some() || none_level.is_some() { if simple_level.is_some() { - abort_call_site!("plain level cannot be specified with `some` or `none` levels"); + return Err(syn::Error::new( + Span::call_site(), + "plain level cannot be specified with `some` or `none` levels", + )); } Ok(Args::Option { some_level, @@ -207,7 +212,6 @@ impl Parse for Args { /// `logcall` attribute macro that logs the function inputs and return values. #[proc_macro_attribute] -#[proc_macro_error] pub fn logcall( args: proc_macro::TokenStream, item: proc_macro::TokenStream, @@ -567,7 +571,7 @@ fn gen_log( ) -> proc_macro2::TokenStream { let level = level.to_lowercase(); if !["error", "warn", "info", "debug", "trace"].contains(&level.as_str()) { - abort_call_site!("unknown log level"); + return syn::Error::new(Span::call_site(), "unknown log level").into_compile_error(); } let level: Ident = Ident::new(&level, Span::call_site()); let fn_name = quote::quote! {