#thread-safe #trace #proc-macro #tracing #execution #log #function

nightly trace2

A proc macro for tracing the execution of functions, similar to trace crate, but thread safe and use log

1 unstable release

Uses old Rust 2015

0.1.0 Sep 11, 2018

#628 in Procedural macros

MIT license

7KB

trace2

A procedural macro for tracing the execution of functions in Rust language (nightly).

The functionality is similar to the trace crate, but it is thread safe and uses log so that you can have more control. In addition, unlike trace, You don't need to declare any static variable. Just adding attributes to what you want to trace and it just works™.

Usage

  1. Add dependency to your Cargo.toml:

    trace2 = "0.1"
    
  2. Import crate:

    #![feature(use_extern_macros)]   // Not needed if your rustc is recent enough.
    extern crate trace2;
    
  3. Add #[::trace2::trace2] attribute to the function, impl block or mod block.

    Adding trace to a mod requires a recent rust nightly compiler with proc_macro_mod feature enabled.

Examples

Trace specific function

examples/basic.rs: Trace specified function by adding trace2 attribute to the function.

#![feature(use_extern_macros)]
#![feature(proc_macro_path_invoc)]

extern crate trace2;
#[macro_use]
extern crate log;
extern crate env_logger;

#[::trace2::trace2]
fn foo(a: i32, b: i32) {
    println!("I'm in foo!");
    bar((a, b));
}

#[::trace2::trace2]
fn bar((a, b): (i32, i32)) -> i32 {
    println!("I'm in bar!");
    if a == 1 {
        2
    } else {
        b
    }
}

fn main() {
    env_logger::Builder::from_default_env()
        .default_format_module_path(false)
        .init();

    foo(1, 2);
}

Output:

TRACE 2018-09-06T17:06:54Z: >>>> basic::foo(a: 1, b: 2)
I'm in foo!
TRACE 2018-09-06T17:06:54Z: >>>>>>>> basic::bar(a: 1, b: 2)
I'm in bar!
TRACE 2018-09-06T17:06:54Z: <<<<<<<< basic::bar = 2
TRACE 2018-09-06T17:06:54Z: <<<< basic::foo = ()

Trace whole impl block

examples/impl_level.rs: Trace all functions in the impl block by adding trace2 attribute to the impl block.

#![feature(use_extern_macros)]
#![feature(proc_macro_path_invoc)]

extern crate trace2;
#[macro_use]
extern crate log;
extern crate env_logger;

struct Foo;

#[trace2::trace2]
impl Foo {
    fn foo(b: i32) -> i32 {
        b
    }

    fn bar(&self, a: i32) -> i32 {
        a
    }

    fn boz(&self, a: i32) -> i32 {
        self.bar(a)
    }
}

fn main() {
    env_logger::Builder::from_default_env()
        .default_format_module_path(false)
        .init();

    let foo = Foo;
    Foo::foo(2);
    foo.bar(7);
    foo.boz(13);
}

Output:

TRACE 2018-09-11T07:05:59Z: >>>> impl_level::Foo::foo(b: 2)
TRACE 2018-09-11T07:05:59Z: <<<< impl_level::Foo::foo = 2
TRACE 2018-09-11T07:05:59Z: >>>> impl_level::Foo::bar(a: 7)
TRACE 2018-09-11T07:05:59Z: <<<< impl_level::Foo::bar = 7
TRACE 2018-09-11T07:05:59Z: >>>> impl_level::Foo::boz(a: 13)
TRACE 2018-09-11T07:05:59Z: >>>>>>>> impl_level::Foo::bar(a: 13)
TRACE 2018-09-11T07:05:59Z: <<<<<<<< impl_level::Foo::bar = 13
TRACE 2018-09-11T07:05:59Z: <<<< impl_level::Foo::boz = 13

See more examples in the examples directory.

TODO

  • Support outputting impl type for nested trace attributes
  • Support pausing

License

MIT

Dependencies

~2MB
~45K SLoC