Skip to content

fast/logcall

Repository files navigation

Logcall

Crates.io Downloads Documentation CI Status License

Logcall is a Rust procedural macro crate that automatically logs function calls, their inputs, and outputs. It keeps boilerplate low while making debugging and observability easy.

This is a re-implementation of log-derive with async-trait compatibility.

Installation

Add to Cargo.toml:

[dependencies]
logcall = "0.1"

Quick Start

Annotate functions with #[logcall] and configure logging with logforth:

use logcall::logcall;
use logforth::append;
use logforth::filter::EnvFilter;

/// Logs the function call at the default `debug` level.
#[logcall]
fn add(a: i32, b: i32) -> i32 {
    a + b
}

/// Logs the function call at the `info` level.
#[logcall("info")]
fn multiply(a: i32, b: i32) -> i32 {
    a * b
}

/// Logs `Ok` results at the `info` level and `Err` results at the `error` level.
#[logcall(ok = "info", err = "error")]
fn divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err("Division by zero".to_string())
    } else {
        Ok(a / b)
    }
}

/// Logs errors at the `error` level. No log output for `Ok` variant.
#[logcall(err = "error")]
fn divide2(a: usize, b: usize) -> Result<usize, String> {
    if b == 0 {
        Err("Division by zero".to_string())
    } else {
        Ok(a / b)
    }
}

/// Logs the function call with custom input logging format.
#[logcall(input = "a = {a:?}, ..")]
fn subtract(a: i32, b: i32) -> i32 {
    a - b
}

/// Logs the function call with custom output logging format.
#[logcall(output = ": {:?}")]
fn negate(a: i32) -> i32 {
    -a
}

/// Omits the return value from the log output.
#[logcall(output = "")]
fn ping(a: i32) -> i32 {
    a
}

fn main() {
    logforth::builder()
        .dispatch(|d| {
            d.filter(EnvFilter::from_default_env_or("trace"))
                .append(append::Stderr::default())
        })
        .apply();

    add(2, 3);
    multiply(2, 3);
    divide(2, 0).ok();
    divide2(2, 0).ok();
    subtract(3, 2);
    negate(5);
    ping(42);
}

Example Run

cargo run --example main

Sample output (from 2025-12-11):

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)

Minimum Supported Rust Version (MSRV)

This crate is built against the latest stable release, and its minimum supported rustc version is 1.80.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.

Contributing

Contributions are welcome! Please submit pull requests or open issues to improve the crate.

License

This project is licensed under the MIT License. See the LICENSE file for details.

About

An attribute macro that logs the function return value

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages