trace2 0.1.0

A proc macro for tracing the execution of functions, similar to trace crate, but thread safe and use log
# 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)]   // 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](./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/