# 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`:
```toml
trace2 = "0.1"
```
2. Import crate:
```rust
#![feature(use_extern_macros)] 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](./examples/basic.rs): Trace specified function by adding trace2 attribute to the function.
```rust
#![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](./examples/impl_level.rs): Trace all functions in the impl block by adding trace2 attribute
to the impl block.
```rust
#![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](./examples) directory.
## TODO
- Support outputting impl type for nested trace attributes
- Support pausing
## License
MIT
[trace]: https://docs.rs/trace/
[log]: https://docs.rs/log/