Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show thread ids and names #12

Merged
merged 3 commits into from
Aug 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ fn main() {
let layer = HierarchicalLayer::default()
.with_indent_lines(true)
.with_indent_amount(2)
.with_thread_names(true)
.with_thread_ids(true)
.with_targets(true);

let subscriber = Registry::default().with(layer);
Expand Down
69 changes: 58 additions & 11 deletions src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ pub struct Config {
pub indent_amount: usize,
/// Whether to show the module paths.
pub targets: bool,
/// Whether to show thread ids.
pub render_thread_ids: bool,
/// Whether to show thread names.
pub render_thread_names: bool,
}

impl Config {
Expand All @@ -39,6 +43,42 @@ impl Config {
pub fn with_targets(self, targets: bool) -> Self {
Self { targets, ..self }
}

pub fn with_thread_ids(self, render_thread_ids: bool) -> Self {
Self {
render_thread_ids,
..self
}
}

pub fn with_thread_names(self, render_thread_names: bool) -> Self {
Self {
render_thread_names,
..self
}
}

pub(crate) fn prefix(&self) -> String {
let mut buf = String::new();
if self.render_thread_ids {
write!(buf, "{:?}", std::thread::current().id()).unwrap();
if buf.ends_with(')') {
buf.truncate(buf.len() - 1);
}
if buf.starts_with("ThreadId(") {
buf.drain(0.."ThreadId(".len());
}
}
if self.render_thread_names {
if let Some(name) = std::thread::current().name() {
if self.render_thread_ids {
buf.push(':');
}
buf.push_str(name);
}
}
buf
}
}

impl Default for Config {
Expand All @@ -48,6 +88,8 @@ impl Default for Config {
indent_lines: false,
indent_amount: 2,
targets: false,
render_thread_ids: false,
render_thread_names: false,
}
}
}
Expand Down Expand Up @@ -77,14 +119,17 @@ impl Buffers {
}

pub fn indent_current(&mut self, indent: usize, config: &Config) {
self.current_buf.push('\n');
indent_block(
&mut self.current_buf,
&mut self.indent_buf,
indent,
config.indent_amount,
config.indent_lines,
&config.prefix(),
);
self.current_buf.clear();
self.flush_indent_buf();
}
}

Expand All @@ -108,14 +153,6 @@ impl<'a> Visit for FmtEvent<'a> {
}
}

impl<'a> FmtEvent<'a> {
pub fn finish(&mut self, indent: usize, config: &Config) {
self.bufs.current_buf.push('\n');
self.bufs.indent_current(indent, config);
self.bufs.flush_indent_buf();
}
}

pub struct ColorLevel<'a>(pub &'a Level);

impl<'a> fmt::Display for ColorLevel<'a> {
Expand All @@ -131,18 +168,26 @@ impl<'a> fmt::Display for ColorLevel<'a> {
}
}

fn indent_block_with_lines(lines: &[&str], buf: &mut String, indent: usize, indent_amount: usize) {
fn indent_block_with_lines(
lines: &[&str],
buf: &mut String,
indent: usize,
indent_amount: usize,
prefix: &str,
) {
let indent_spaces = indent * indent_amount;
if lines.is_empty() {
return;
} else if indent_spaces == 0 {
for line in lines {
buf.push_str(prefix);
buf.push_str(line);
buf.push('\n');
}
return;
}
let mut s = String::with_capacity(indent_spaces);
let mut s = String::with_capacity(indent_spaces + prefix.len());
s.push_str(prefix);

// instead of using all spaces to indent, draw a vertical line at every indent level
// up until the last indent
Expand Down Expand Up @@ -189,15 +234,17 @@ fn indent_block(
indent: usize,
indent_amount: usize,
indent_lines: bool,
prefix: &str,
) {
let lines: Vec<&str> = block.lines().collect();
let indent_spaces = indent * indent_amount;
buf.reserve(block.len() + (lines.len() * indent_spaces));
if indent_lines {
indent_block_with_lines(&lines, buf, indent, indent_amount);
indent_block_with_lines(&lines, buf, indent, indent_amount, prefix);
} else {
let indent_str = String::from(" ").repeat(indent_spaces);
for line in lines {
buf.push_str(prefix);
buf.push_str(&indent_str);
buf.push_str(line);
buf.push('\n');
Expand Down
38 changes: 22 additions & 16 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,7 @@ where

impl Default for HierarchicalLayer {
fn default() -> Self {
let ansi = atty::is(atty::Stream::Stdout);
let indent_amount = 2;
let config = Config {
ansi,
indent_amount,
targets: false,
..Default::default()
};
Self {
make_writer: io::stdout,
bufs: Mutex::new(Buffers::new()),
config,
}
Self::new(2)
}
}

Expand Down Expand Up @@ -133,6 +121,24 @@ where
}
}

/// Whether to render the thread id in the beginning of every line. This is helpful to
/// untangle the tracing statements emitted by each thread.
pub fn with_thread_ids(self, thread_ids: bool) -> Self {
Self {
config: self.config.with_thread_ids(thread_ids),
..self
}
}

/// Whether to render the thread name in the beginning of every line. Not all threads have
/// names, but if they do, this may be more helpful than the generic thread ids.
pub fn with_thread_names(self, thread_names: bool) -> Self {
Self {
config: self.config.with_thread_names(thread_names),
..self
}
}

fn styled(&self, style: Style, text: impl AsRef<str>) -> String {
if self.config.ansi {
style.paint(text.as_ref()).to_string()
Expand Down Expand Up @@ -209,15 +215,14 @@ where
.unwrap();
self.print_kvs(&mut current_buf, data.kvs.iter().map(|(k, v)| (k, v)), "")
.unwrap();
writeln!(
write!(
current_buf,
"{}",
self.styled(Style::new().fg(Color::Green).bold(), "}") // Style::new().dimmed().paint("}")
)
.unwrap();

bufs.indent_current(indent, &self.config);
bufs.flush_indent_buf();
let writer = self.make_writer.make_writer();
bufs.flush_current_buf(writer)
}
Expand All @@ -226,6 +231,7 @@ where
let mut guard = self.bufs.lock().unwrap();
let mut bufs = &mut *guard;
let mut event_buf = &mut bufs.current_buf;

// printing the indentation
let indent = if ctx.current_span().id().is_some() {
// size hint isn't implemented on Scope.
Expand Down Expand Up @@ -287,7 +293,7 @@ where
bufs: &mut bufs,
};
event.record(&mut visitor);
visitor.finish(indent, &self.config);
visitor.bufs.indent_current(indent, &self.config);
let writer = self.make_writer.make_writer();
bufs.flush_current_buf(writer)
}
Expand Down