mirror of
https://github.com/tokio-rs/tracing.git
synced 2025-09-30 14:30:42 +00:00
working slog-style example
This commit is contained in:
parent
655121dd3f
commit
f2f3cdfbe4
@ -1,3 +1,15 @@
|
||||
//! A simple example demonstrating how one might implement a custom
|
||||
//! subscriber.
|
||||
//!
|
||||
//! This subscriber implements a tree-structured logger similar to
|
||||
//! the "compact" formatter in [`slog-term`]. The demo mimicks the
|
||||
//! example output in the screenshot in the [`slog` README].
|
||||
//!
|
||||
//! Note that this logger isn't ready for actual production use.
|
||||
//! Several corners were cut to make the example simple.
|
||||
//!
|
||||
//! [`slog-term`]: https://docs.rs/slog-term/2.4.0/slog_term/
|
||||
//! [`slog` README]: https://github.com/slog-rs/slog#terminal-output-example
|
||||
#[macro_use]
|
||||
extern crate tokio_trace;
|
||||
extern crate ansi_term;
|
||||
@ -8,8 +20,8 @@ use tokio_trace::Level;
|
||||
use std::{
|
||||
fmt,
|
||||
io::{self, Write},
|
||||
time::Instant,
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
struct SloggishSubscriber {
|
||||
@ -27,7 +39,7 @@ impl fmt::Display for ColorLevel {
|
||||
Level::Debug => Color::Blue.paint("DEBUG"),
|
||||
Level::Info => Color::Green.paint("INFO "),
|
||||
Level::Warn => Color::Yellow.paint("WARN "),
|
||||
Level::Error => Color::Red.paint("ERROR")
|
||||
Level::Error => Color::Red.paint("ERROR"),
|
||||
}.fmt(f)
|
||||
}
|
||||
}
|
||||
@ -41,18 +53,27 @@ impl SloggishSubscriber {
|
||||
}
|
||||
}
|
||||
|
||||
fn print_kvs<'a, I>(&self, writer: &mut impl Write, kvs: I) -> io::Result<()>
|
||||
fn print_kvs<'a, I>(&self, writer: &mut impl Write, kvs: I, leading: &str) -> io::Result<()>
|
||||
where
|
||||
I: IntoIterator<Item=(&'static str, &'a dyn tokio_trace::Value)>,
|
||||
I: IntoIterator<Item = (&'static str, &'a dyn tokio_trace::Value)>,
|
||||
{
|
||||
let mut kvs = kvs.into_iter();
|
||||
if let Some((k, v)) = kvs.next() {
|
||||
write!(writer, "{}{}: {:?}", leading, Style::new().bold().paint(k), v)?;
|
||||
}
|
||||
for (k, v) in kvs {
|
||||
write!(writer, "{}: {:?} ", Style::new().bold().paint(k), v)?;
|
||||
write!(writer, ", {}: {:?}", Style::new().bold().paint(k), v)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_meta(&self, writer: &mut impl Write, meta: &tokio_trace::StaticMeta) -> io::Result<()> {
|
||||
write!(writer,
|
||||
fn print_meta(
|
||||
&self,
|
||||
writer: &mut impl Write,
|
||||
meta: &tokio_trace::StaticMeta,
|
||||
) -> io::Result<()> {
|
||||
write!(
|
||||
writer,
|
||||
"{level} {target} ",
|
||||
level = ColorLevel(meta.level),
|
||||
target = meta.target.unwrap_or(meta.module_path),
|
||||
@ -74,8 +95,12 @@ impl tokio_trace::Subscriber for SloggishSubscriber {
|
||||
let mut stderr = self.stderr.lock();
|
||||
self.print_meta(&mut stderr, event.static_meta).unwrap();
|
||||
self.print_indent(&mut stderr).unwrap();
|
||||
write!(&mut stderr, "{}, ", Style::new().bold().paint(format!("{}", event.message))).unwrap();
|
||||
self.print_kvs(&mut stderr, event.all_fields()).unwrap();
|
||||
write!(
|
||||
&mut stderr,
|
||||
"{}",
|
||||
Style::new().bold().paint(format!("{}", event.message))
|
||||
).unwrap();
|
||||
self.print_kvs(&mut stderr, event.fields(), ", ").unwrap();
|
||||
write!(&mut stderr, "\n").unwrap();
|
||||
}
|
||||
|
||||
@ -84,9 +109,10 @@ impl tokio_trace::Subscriber for SloggishSubscriber {
|
||||
let mut stderr = self.stderr.lock();
|
||||
self.print_meta(&mut stderr, span.meta()).unwrap();
|
||||
let indent = self.print_indent(&mut stderr).unwrap();
|
||||
self.print_kvs(&mut stderr, span.fields()).unwrap();
|
||||
self.print_kvs(&mut stderr, span.fields(), "").unwrap();
|
||||
write!(&mut stderr, "\n").unwrap();
|
||||
self.indent.compare_and_swap(indent, indent + self.indent_amount, Ordering::Release);
|
||||
self.indent
|
||||
.compare_and_swap(indent, indent + self.indent_amount, Ordering::Release);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -103,8 +129,31 @@ fn main() {
|
||||
let foo = 3;
|
||||
event!(Level::Info, { foo = foo, bar = "bar" }, "hello world");
|
||||
|
||||
let span = span!("my_great_span", foo = 4, baz = 5);
|
||||
span.enter(|| {
|
||||
event!(Level::Info, { yak_shaved = true }, "hi from inside my span");
|
||||
span!("", version = 5.0).enter(|| {
|
||||
span!("server", host = "localhost", port = 8080).enter(|| {
|
||||
event!(Level::Info, {}, "starting");
|
||||
event!(Level::Info, {}, "listening");
|
||||
let peer1 = span!("conn", peer_addr = "82.9.9.9", port = 42381);
|
||||
peer1.enter(|| {
|
||||
event!(Level::Debug, {}, "connected");
|
||||
event!(Level::Debug, { length = 2 }, "message received");
|
||||
});
|
||||
let peer2 = span!("conn", peer_addr = "8.8.8.8", port = 18230);
|
||||
peer2.enter(|| {
|
||||
event!(Level::Debug, {}, "connected");
|
||||
});
|
||||
peer1.enter(|| {
|
||||
event!(Level::Warn, { algo = "xor" }, "weak encryption requested");
|
||||
event!(Level::Debug, { length = 8 }, "response sent");
|
||||
event!(Level::Debug, { }, "disconnected");
|
||||
});
|
||||
peer2.enter(|| {
|
||||
event!(Level::Debug, { length = 5 }, "message received");
|
||||
event!(Level::Debug, { length = 8 }, "response sent");
|
||||
event!(Level::Debug, { }, "disconnected");
|
||||
});
|
||||
event!(Level::Error, {}, "internal error");
|
||||
event!(Level::Info, {}, "exit");
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use std::iter::Peekable;
|
||||
pub trait IteratorDedup: Iterator + Sized {
|
||||
fn dedup_by<F, K>(self, f: F) -> DedupBy<Self, F, K>
|
||||
where
|
||||
F: Fn(&Self::Item) -> K,
|
||||
F: Fn(&Self::Item) -> &K,
|
||||
K: PartialEq,
|
||||
{
|
||||
DedupBy {
|
||||
@ -19,16 +19,21 @@ where
|
||||
I: Iterator + Sized,
|
||||
{}
|
||||
|
||||
pub struct DedupBy<I: Iterator, F> {
|
||||
pub struct DedupBy<I: Iterator, F: Fn(&I::Item) -> &K, K> {
|
||||
f: F,
|
||||
inner: Peekable<I>,
|
||||
emit: bool,
|
||||
}
|
||||
|
||||
impl<I> Iterator for DedupBy<I>
|
||||
where I: Iterator, <I as Iterator>::Item: PartialEq {
|
||||
impl<I, F, K> Iterator for DedupBy<I, F, K>
|
||||
where
|
||||
I: Iterator,
|
||||
F: Fn(&I::Item) -> &K,
|
||||
K: PartialEq,
|
||||
{
|
||||
type Item = <I as Iterator>::Item;
|
||||
fn next(&mut self) -> Option<<I as Iterator>::Item> {
|
||||
let f = &self.f;
|
||||
let result =
|
||||
if self.emit {
|
||||
self.inner.next()
|
||||
@ -37,9 +42,9 @@ where I: Iterator, <I as Iterator>::Item: PartialEq {
|
||||
None => return None,
|
||||
Some(first) => first,
|
||||
};
|
||||
self.inner.find(|item| first != *item)
|
||||
self.inner.find(|item| (f)(&first) != (f)(item))
|
||||
};
|
||||
self.emit = result.as_ref() != self.inner.peek();
|
||||
self.emit = result.as_ref().map(f) != self.inner.peek().map(f);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user