Skip to content

Commit 6a8c7fd

Browse files
authored
Show thread ids and names (#12)
1 parent 36bf36c commit 6a8c7fd

File tree

3 files changed

+82
-27
lines changed

3 files changed

+82
-27
lines changed

examples/basic.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ fn main() {
66
let layer = HierarchicalLayer::default()
77
.with_indent_lines(true)
88
.with_indent_amount(2)
9+
.with_thread_names(true)
10+
.with_thread_ids(true)
911
.with_targets(true);
1012

1113
let subscriber = Registry::default().with(layer);

src/format.rs

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ pub struct Config {
2222
pub indent_amount: usize,
2323
/// Whether to show the module paths.
2424
pub targets: bool,
25+
/// Whether to show thread ids.
26+
pub render_thread_ids: bool,
27+
/// Whether to show thread names.
28+
pub render_thread_names: bool,
2529
}
2630

2731
impl Config {
@@ -39,6 +43,42 @@ impl Config {
3943
pub fn with_targets(self, targets: bool) -> Self {
4044
Self { targets, ..self }
4145
}
46+
47+
pub fn with_thread_ids(self, render_thread_ids: bool) -> Self {
48+
Self {
49+
render_thread_ids,
50+
..self
51+
}
52+
}
53+
54+
pub fn with_thread_names(self, render_thread_names: bool) -> Self {
55+
Self {
56+
render_thread_names,
57+
..self
58+
}
59+
}
60+
61+
pub(crate) fn prefix(&self) -> String {
62+
let mut buf = String::new();
63+
if self.render_thread_ids {
64+
write!(buf, "{:?}", std::thread::current().id()).unwrap();
65+
if buf.ends_with(')') {
66+
buf.truncate(buf.len() - 1);
67+
}
68+
if buf.starts_with("ThreadId(") {
69+
buf.drain(0.."ThreadId(".len());
70+
}
71+
}
72+
if self.render_thread_names {
73+
if let Some(name) = std::thread::current().name() {
74+
if self.render_thread_ids {
75+
buf.push(':');
76+
}
77+
buf.push_str(name);
78+
}
79+
}
80+
buf
81+
}
4282
}
4383

4484
impl Default for Config {
@@ -48,6 +88,8 @@ impl Default for Config {
4888
indent_lines: false,
4989
indent_amount: 2,
5090
targets: false,
91+
render_thread_ids: false,
92+
render_thread_names: false,
5193
}
5294
}
5395
}
@@ -77,14 +119,17 @@ impl Buffers {
77119
}
78120

79121
pub fn indent_current(&mut self, indent: usize, config: &Config) {
122+
self.current_buf.push('\n');
80123
indent_block(
81124
&mut self.current_buf,
82125
&mut self.indent_buf,
83126
indent,
84127
config.indent_amount,
85128
config.indent_lines,
129+
&config.prefix(),
86130
);
87131
self.current_buf.clear();
132+
self.flush_indent_buf();
88133
}
89134
}
90135

@@ -108,14 +153,6 @@ impl<'a> Visit for FmtEvent<'a> {
108153
}
109154
}
110155

111-
impl<'a> FmtEvent<'a> {
112-
pub fn finish(&mut self, indent: usize, config: &Config) {
113-
self.bufs.current_buf.push('\n');
114-
self.bufs.indent_current(indent, config);
115-
self.bufs.flush_indent_buf();
116-
}
117-
}
118-
119156
pub struct ColorLevel<'a>(pub &'a Level);
120157

121158
impl<'a> fmt::Display for ColorLevel<'a> {
@@ -131,18 +168,26 @@ impl<'a> fmt::Display for ColorLevel<'a> {
131168
}
132169
}
133170

134-
fn indent_block_with_lines(lines: &[&str], buf: &mut String, indent: usize, indent_amount: usize) {
171+
fn indent_block_with_lines(
172+
lines: &[&str],
173+
buf: &mut String,
174+
indent: usize,
175+
indent_amount: usize,
176+
prefix: &str,
177+
) {
135178
let indent_spaces = indent * indent_amount;
136179
if lines.is_empty() {
137180
return;
138181
} else if indent_spaces == 0 {
139182
for line in lines {
183+
buf.push_str(prefix);
140184
buf.push_str(line);
141185
buf.push('\n');
142186
}
143187
return;
144188
}
145-
let mut s = String::with_capacity(indent_spaces);
189+
let mut s = String::with_capacity(indent_spaces + prefix.len());
190+
s.push_str(prefix);
146191

147192
// instead of using all spaces to indent, draw a vertical line at every indent level
148193
// up until the last indent
@@ -189,15 +234,17 @@ fn indent_block(
189234
indent: usize,
190235
indent_amount: usize,
191236
indent_lines: bool,
237+
prefix: &str,
192238
) {
193239
let lines: Vec<&str> = block.lines().collect();
194240
let indent_spaces = indent * indent_amount;
195241
buf.reserve(block.len() + (lines.len() * indent_spaces));
196242
if indent_lines {
197-
indent_block_with_lines(&lines, buf, indent, indent_amount);
243+
indent_block_with_lines(&lines, buf, indent, indent_amount, prefix);
198244
} else {
199245
let indent_str = String::from(" ").repeat(indent_spaces);
200246
for line in lines {
247+
buf.push_str(prefix);
201248
buf.push_str(&indent_str);
202249
buf.push_str(line);
203250
buf.push('\n');

src/lib.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,7 @@ where
5353

5454
impl Default for HierarchicalLayer {
5555
fn default() -> Self {
56-
let ansi = atty::is(atty::Stream::Stdout);
57-
let indent_amount = 2;
58-
let config = Config {
59-
ansi,
60-
indent_amount,
61-
targets: false,
62-
..Default::default()
63-
};
64-
Self {
65-
make_writer: io::stdout,
66-
bufs: Mutex::new(Buffers::new()),
67-
config,
68-
}
56+
Self::new(2)
6957
}
7058
}
7159

@@ -133,6 +121,24 @@ where
133121
}
134122
}
135123

124+
/// Whether to render the thread id in the beginning of every line. This is helpful to
125+
/// untangle the tracing statements emitted by each thread.
126+
pub fn with_thread_ids(self, thread_ids: bool) -> Self {
127+
Self {
128+
config: self.config.with_thread_ids(thread_ids),
129+
..self
130+
}
131+
}
132+
133+
/// Whether to render the thread name in the beginning of every line. Not all threads have
134+
/// names, but if they do, this may be more helpful than the generic thread ids.
135+
pub fn with_thread_names(self, thread_names: bool) -> Self {
136+
Self {
137+
config: self.config.with_thread_names(thread_names),
138+
..self
139+
}
140+
}
141+
136142
fn styled(&self, style: Style, text: impl AsRef<str>) -> String {
137143
if self.config.ansi {
138144
style.paint(text.as_ref()).to_string()
@@ -209,15 +215,14 @@ where
209215
.unwrap();
210216
self.print_kvs(&mut current_buf, data.kvs.iter().map(|(k, v)| (k, v)), "")
211217
.unwrap();
212-
writeln!(
218+
write!(
213219
current_buf,
214220
"{}",
215221
self.styled(Style::new().fg(Color::Green).bold(), "}") // Style::new().dimmed().paint("}")
216222
)
217223
.unwrap();
218224

219225
bufs.indent_current(indent, &self.config);
220-
bufs.flush_indent_buf();
221226
let writer = self.make_writer.make_writer();
222227
bufs.flush_current_buf(writer)
223228
}
@@ -226,6 +231,7 @@ where
226231
let mut guard = self.bufs.lock().unwrap();
227232
let mut bufs = &mut *guard;
228233
let mut event_buf = &mut bufs.current_buf;
234+
229235
// printing the indentation
230236
let indent = if ctx.current_span().id().is_some() {
231237
// size hint isn't implemented on Scope.
@@ -287,7 +293,7 @@ where
287293
bufs: &mut bufs,
288294
};
289295
event.record(&mut visitor);
290-
visitor.finish(indent, &self.config);
296+
visitor.bufs.indent_current(indent, &self.config);
291297
let writer = self.make_writer.make_writer();
292298
bufs.flush_current_buf(writer)
293299
}

0 commit comments

Comments
 (0)