mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-28 12:10:37 +00:00

## Motivation In order to support conventions that add namespacing to `tokio-trace` field names, it's necessary to accept at least one type of separator character. Currently, the `tokio-trace` macros only accept valid Rust identifiers, so there is no clear separator character for namespaced conventions. See also #1018. ## Solution This branch changes the single `ident` fragment matcher for field names to match *one or more* `ident` fragments separated by `.` characters. ## Notes The resulting key is still exposed to `tokio-trace-core` as a string constant created by stringifying the dotted expression. However, if `tokio-trace-core` were later to adopt a first class notion of hierarchical field keys, we would be able to track that change in `tokio-trace` as an implementation detail. Closes #1018. Closes #1022. Signed-off-by: Eliza Weisman <eliza@buoyant.io>
190 lines
5.0 KiB
Rust
190 lines
5.0 KiB
Rust
#[macro_use]
|
|
extern crate tokio_trace;
|
|
mod support;
|
|
|
|
use self::support::*;
|
|
|
|
use tokio_trace::{field::display, subscriber::with_default, Level};
|
|
|
|
#[test]
|
|
fn event_without_message() {
|
|
let (subscriber, handle) = subscriber::mock()
|
|
.event(
|
|
event::mock().with_fields(
|
|
field::mock("answer")
|
|
.with_value(&42)
|
|
.and(
|
|
field::mock("to_question")
|
|
.with_value(&"life, the universe, and everything"),
|
|
)
|
|
.only(),
|
|
),
|
|
)
|
|
.done()
|
|
.run_with_handle();
|
|
|
|
with_default(subscriber, || {
|
|
info!(
|
|
answer = 42,
|
|
to_question = "life, the universe, and everything"
|
|
);
|
|
});
|
|
|
|
handle.assert_finished();
|
|
}
|
|
|
|
#[test]
|
|
fn event_with_message() {
|
|
let (subscriber, handle) = subscriber::mock()
|
|
.event(event::mock().with_fields(field::mock("message").with_value(
|
|
&tokio_trace::field::debug(format_args!(
|
|
"hello from my event! yak shaved = {:?}",
|
|
true
|
|
)),
|
|
)))
|
|
.done()
|
|
.run_with_handle();
|
|
|
|
with_default(subscriber, || {
|
|
debug!("hello from my event! yak shaved = {:?}", true);
|
|
});
|
|
|
|
handle.assert_finished();
|
|
}
|
|
|
|
#[test]
|
|
fn one_with_everything() {
|
|
let (subscriber, handle) = subscriber::mock()
|
|
.event(
|
|
event::mock()
|
|
.with_fields(
|
|
field::mock("message")
|
|
.with_value(&tokio_trace::field::debug(format_args!(
|
|
"{:#x} make me one with{what:.>20}",
|
|
4277009102u64,
|
|
what = "everything"
|
|
)))
|
|
.and(field::mock("foo").with_value(&666))
|
|
.and(field::mock("bar").with_value(&false))
|
|
.only(),
|
|
)
|
|
.at_level(Level::ERROR)
|
|
.with_target("whatever"),
|
|
)
|
|
.done()
|
|
.run_with_handle();
|
|
|
|
with_default(subscriber, || {
|
|
event!(
|
|
target: "whatever",
|
|
Level::ERROR,
|
|
{ foo = 666, bar = false },
|
|
"{:#x} make me one with{what:.>20}", 4277009102u64, what = "everything"
|
|
);
|
|
});
|
|
|
|
handle.assert_finished();
|
|
}
|
|
|
|
#[test]
|
|
fn moved_field() {
|
|
let (subscriber, handle) = subscriber::mock()
|
|
.event(
|
|
event::mock().with_fields(
|
|
field::mock("foo")
|
|
.with_value(&display("hello from my event"))
|
|
.only(),
|
|
),
|
|
)
|
|
.done()
|
|
.run_with_handle();
|
|
with_default(subscriber, || {
|
|
let from = "my event";
|
|
event!(Level::INFO, foo = display(format!("hello from {}", from)))
|
|
});
|
|
|
|
handle.assert_finished();
|
|
}
|
|
|
|
#[test]
|
|
fn dotted_field_name() {
|
|
let (subscriber, handle) = subscriber::mock()
|
|
.event(
|
|
event::mock().with_fields(
|
|
field::mock("foo.bar")
|
|
.with_value(&true)
|
|
.and(field::mock("foo.baz").with_value(&false))
|
|
.only(),
|
|
),
|
|
)
|
|
.done()
|
|
.run_with_handle();
|
|
with_default(subscriber, || {
|
|
event!(Level::INFO, foo.bar = true, foo.baz = false);
|
|
});
|
|
|
|
handle.assert_finished();
|
|
}
|
|
|
|
#[test]
|
|
fn borrowed_field() {
|
|
let (subscriber, handle) = subscriber::mock()
|
|
.event(
|
|
event::mock().with_fields(
|
|
field::mock("foo")
|
|
.with_value(&display("hello from my event"))
|
|
.only(),
|
|
),
|
|
)
|
|
.done()
|
|
.run_with_handle();
|
|
with_default(subscriber, || {
|
|
let from = "my event";
|
|
let mut message = format!("hello from {}", from);
|
|
event!(Level::INFO, foo = display(&message));
|
|
message.push_str(", which happened!");
|
|
});
|
|
|
|
handle.assert_finished();
|
|
}
|
|
|
|
#[test]
|
|
// If emitting log instrumentation, this gets moved anyway, breaking the test.
|
|
#[cfg(not(feature = "log"))]
|
|
fn move_field_out_of_struct() {
|
|
use tokio_trace::field::debug;
|
|
|
|
#[derive(Debug)]
|
|
struct Position {
|
|
x: f32,
|
|
y: f32,
|
|
}
|
|
|
|
let pos = Position {
|
|
x: 3.234,
|
|
y: -1.223,
|
|
};
|
|
let (subscriber, handle) = subscriber::mock()
|
|
.event(
|
|
event::mock().with_fields(
|
|
field::mock("x")
|
|
.with_value(&debug(3.234))
|
|
.and(field::mock("y").with_value(&debug(-1.223)))
|
|
.only(),
|
|
),
|
|
)
|
|
.event(event::mock().with_fields(field::mock("position").with_value(&debug(&pos))))
|
|
.done()
|
|
.run_with_handle();
|
|
|
|
with_default(subscriber, || {
|
|
let pos = Position {
|
|
x: 3.234,
|
|
y: -1.223,
|
|
};
|
|
debug!(x = debug(pos.x), y = debug(pos.y));
|
|
debug!(target: "app_events", { position = debug(pos) }, "New position");
|
|
});
|
|
handle.assert_finished();
|
|
}
|