Files
tokio/tokio-trace/test-log-support/tests/log_no_trace.rs
T
Eliza Weisman 84d5a7f5a0 trace: Change Span::enter to return a guard, add Span::in_scope (#1076)
## Motivation

Currently, the primary way to use a span is to use `.enter` and pass a
closure to be executed under the span. While that is convenient in many
settings, it also comes with two decently inconvenient drawbacks:

 - It breaks control flow statements like `return`, `?`, `break`, and
   `continue`
 - It require re-indenting a potentially large chunk of code if you wish
   it to appear under a span

## Solution

This branch changes the `Span::enter` function to return a scope guard 
that exits the span when dropped, as in:
```rust
let guard = span.enter();

// code here is within the span

drop(guard);

// code here is no longer within the span
```
The method previously called `enter`, which takes a closure and 
executes it in the span's context, is now called `Span::in_scope`, and
was reimplemented on top of the new `enter` method. 

This is a breaking change to `tokio-trace` that will be part of the
upcoming 0.2 release.

Closes #1075 

Signed-off-by: Eliza Weisman <[email protected]>
2019-05-24 15:24:13 -07:00

73 lines
1.8 KiB
Rust

extern crate log;
#[macro_use]
extern crate tokio_trace;
use log::{LevelFilter, Log, Metadata, Record};
use std::sync::{Arc, Mutex};
use tokio_trace::Level;
struct State {
last_log: Mutex<Option<String>>,
}
struct Logger(Arc<State>);
impl Log for Logger {
fn enabled(&self, _: &Metadata) -> bool {
true
}
fn log(&self, record: &Record) {
let line = format!("{}", record.args());
println!("{:<5} {} {}", record.level(), record.target(), line);
*self.0.last_log.lock().unwrap() = Some(line);
}
fn flush(&self) {}
}
#[test]
fn test_always_log() {
let me = Arc::new(State {
last_log: Mutex::new(None),
});
let a = me.clone();
log::set_boxed_logger(Box::new(Logger(me))).unwrap();
log::set_max_level(LevelFilter::Trace);
error!(foo = 5);
last(&a, "foo=5");
warn!("hello {};", "world");
last(&a, "hello world;");
info!(message = "hello world;", thingy = 42, other_thingy = 666);
last(&a, "hello world; thingy=42 other_thingy=666");
let mut foo = span!(Level::TRACE, "foo");
last(&a, "foo;");
foo.in_scope(|| {
last(&a, "-> foo");
trace!({foo = 3, bar = 4}, "hello {};", "san francisco");
last(&a, "hello san francisco; foo=3 bar=4");
});
last(&a, "<- foo");
span!(Level::TRACE, "foo", bar = 3, baz = false);
last(&a, "foo; bar=3 baz=false");
let mut span = span!(Level::TRACE, "foo", bar, baz);
span.record("bar", &3);
last(&a, "foo; bar=3");
span.record("baz", &"a string");
last(&a, "foo; baz=\"a string\"");
}
fn last(state: &State, expected: &str) {
let mut lock = state.last_log.lock().unwrap();
{
let last = lock.as_ref().map(|s| s.as_str().trim());
assert_eq!(last, Some(expected));
}
*lock = None;
}