Skip to content

Commit 5340233

Browse files
committed
subscriber: add with_binary_name and with_process_id options.
These options are useful when multiple processes are logging to the same destination (stderr, in the common case). This can happen when a process launches a child process or when a user simply launches multiple processes in the same terminal. Fixes #2447. Implement these two options.
1 parent 27f688e commit 5340233

File tree

3 files changed

+168
-0
lines changed

3 files changed

+168
-0
lines changed

tracing-subscriber/src/fmt/fmt_subscriber.rs

+30
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,36 @@ where
490490
}
491491
}
492492

493+
/// Sets whether or not the binary name of the process is displayed when
494+
/// formatting events. If binary_name is None, argv\[0\] will be used,
495+
/// otherwise the spcified string will be used.
496+
///
497+
/// [argv\[0\]]: std::env::args
498+
pub fn with_binary_name(
499+
self,
500+
display_binary_name: bool,
501+
binary_name: Option<&str>,
502+
) -> Subscriber<C, N, format::Format<L, T>, W> {
503+
Subscriber {
504+
fmt_event: self.fmt_event.with_binary_name(display_binary_name, binary_name),
505+
..self
506+
}
507+
}
508+
509+
/// Sets whether or not the [process ID] of the current thread is displayed
510+
/// when formatting events.
511+
///
512+
/// [process ID]: std::process::id
513+
pub fn with_process_id(
514+
self,
515+
display_process_id: bool,
516+
) -> Subscriber<C, N, format::Format<L, T>, W> {
517+
Subscriber {
518+
fmt_event: self.fmt_event.with_process_id(display_process_id),
519+
..self
520+
}
521+
}
522+
493523
/// Sets whether or not the [thread ID] of the current thread is displayed
494524
/// when formatting events.
495525
///

tracing-subscriber/src/fmt/format/mod.rs

+108
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,9 @@ pub struct Format<F = Full, T = SystemTime> {
410410
pub(crate) display_timestamp: bool,
411411
pub(crate) display_target: bool,
412412
pub(crate) display_level: bool,
413+
pub(crate) display_binary_name: bool,
414+
pub(crate) binary_name: Option<String>,
415+
pub(crate) display_process_id: bool,
413416
pub(crate) display_thread_id: bool,
414417
pub(crate) display_thread_name: bool,
415418
pub(crate) display_filename: bool,
@@ -588,6 +591,9 @@ impl Default for Format<Full, SystemTime> {
588591
display_timestamp: true,
589592
display_target: true,
590593
display_level: true,
594+
display_binary_name: false,
595+
binary_name: None,
596+
display_process_id: false,
591597
display_thread_id: false,
592598
display_thread_name: false,
593599
display_filename: false,
@@ -608,6 +614,9 @@ impl<F, T> Format<F, T> {
608614
display_target: false,
609615
display_timestamp: self.display_timestamp,
610616
display_level: self.display_level,
617+
display_binary_name: self.display_binary_name,
618+
binary_name: self.binary_name,
619+
display_process_id: self.display_process_id,
611620
display_thread_id: self.display_thread_id,
612621
display_thread_name: self.display_thread_name,
613622
display_filename: self.display_filename,
@@ -647,6 +656,9 @@ impl<F, T> Format<F, T> {
647656
display_target: self.display_target,
648657
display_timestamp: self.display_timestamp,
649658
display_level: self.display_level,
659+
display_binary_name: self.display_binary_name,
660+
binary_name: self.binary_name,
661+
display_process_id: self.display_process_id,
650662
display_thread_id: self.display_thread_id,
651663
display_thread_name: self.display_thread_name,
652664
display_filename: true,
@@ -679,6 +691,9 @@ impl<F, T> Format<F, T> {
679691
display_target: self.display_target,
680692
display_timestamp: self.display_timestamp,
681693
display_level: self.display_level,
694+
display_binary_name: self.display_binary_name,
695+
binary_name: self.binary_name,
696+
display_process_id: self.display_process_id,
682697
display_thread_id: self.display_thread_id,
683698
display_thread_name: self.display_thread_name,
684699
display_filename: self.display_filename,
@@ -708,6 +723,9 @@ impl<F, T> Format<F, T> {
708723
display_target: self.display_target,
709724
display_timestamp: self.display_timestamp,
710725
display_level: self.display_level,
726+
display_binary_name: self.display_binary_name,
727+
binary_name: self.binary_name,
728+
display_process_id: self.display_process_id,
711729
display_thread_id: self.display_thread_id,
712730
display_thread_name: self.display_thread_name,
713731
display_filename: self.display_filename,
@@ -724,6 +742,9 @@ impl<F, T> Format<F, T> {
724742
display_timestamp: false,
725743
display_target: self.display_target,
726744
display_level: self.display_level,
745+
display_binary_name: self.display_binary_name,
746+
binary_name: self.binary_name,
747+
display_process_id: self.display_process_id,
727748
display_thread_id: self.display_thread_id,
728749
display_thread_name: self.display_thread_name,
729750
display_filename: self.display_filename,
@@ -755,6 +776,33 @@ impl<F, T> Format<F, T> {
755776
}
756777
}
757778

779+
/// Sets whether or not the binary name of the process is displayed when
780+
/// formatting events. If binary_name is None, argv\[0\] will be used,
781+
/// otherwise the spcified string will be used.
782+
///
783+
/// [argv\[0\]]: std::env::args
784+
pub fn with_binary_name(self,
785+
display_binary_name: bool,
786+
binary_name: Option<&str>,
787+
) -> Format<F, T> {
788+
Format {
789+
display_binary_name,
790+
binary_name: binary_name.map(str::to_string),
791+
..self
792+
}
793+
}
794+
795+
/// Sets whether or not the [process ID] of the current thread is displayed
796+
/// when formatting events.
797+
///
798+
/// [process ID]: std::process::id
799+
pub fn with_process_id(self, display_process_id: bool) -> Format<F, T> {
800+
Format {
801+
display_process_id,
802+
..self
803+
}
804+
}
805+
758806
/// Sets whether or not the [thread ID] of the current thread is displayed
759807
/// when formatting events.
760808
///
@@ -938,6 +986,21 @@ where
938986
}
939987

940988
self.format_timestamp(&mut writer)?;
989+
990+
if self.display_binary_name {
991+
if let Some(binary_name) = &self.binary_name {
992+
write!(writer, "{} ", binary_name)?;
993+
} else if let Some(argv0) = std::env::args().next() {
994+
write!(writer, "{} ", argv0)?;
995+
} else {
996+
write!(writer, "<missing_argv[0] ")?;
997+
}
998+
}
999+
1000+
if self.display_process_id {
1001+
write!(writer, "PID({}) ", std::process::id())?;
1002+
}
1003+
9411004
self.format_level(*meta.level(), &mut writer)?;
9421005

9431006
if self.display_thread_name {
@@ -1662,6 +1725,8 @@ pub(super) mod test {
16621725
.without_time()
16631726
.with_level(false)
16641727
.with_target(false)
1728+
.with_binary_name(false, None)
1729+
.with_process_id(false)
16651730
.with_thread_ids(false)
16661731
.with_thread_names(false);
16671732
#[cfg(feature = "ansi")]
@@ -1777,6 +1842,49 @@ pub(super) mod test {
17771842
assert_info_hello(subscriber, make_writer, expected);
17781843
}
17791844

1845+
#[test]
1846+
fn with_automatic_binary_name() {
1847+
let make_writer = MockMakeWriter::default();
1848+
let subscriber = crate::fmt::Collector::builder()
1849+
.with_writer(make_writer.clone())
1850+
.with_binary_name(true, None)
1851+
.with_ansi(false)
1852+
.with_timer(MockTime);
1853+
let expected =
1854+
format!("fake time {} INFO tracing_subscriber::fmt::format::test: hello\n",
1855+
std::env::args().next().unwrap());
1856+
1857+
assert_info_hello(subscriber, make_writer, &expected);
1858+
}
1859+
1860+
#[test]
1861+
fn with_manual_binary_name() {
1862+
let make_writer = MockMakeWriter::default();
1863+
let subscriber = crate::fmt::Collector::builder()
1864+
.with_writer(make_writer.clone())
1865+
.with_binary_name(true, Some("a_nice_rust_binary"))
1866+
.with_ansi(false)
1867+
.with_timer(MockTime);
1868+
let expected =
1869+
"fake time a_nice_rust_binary INFO tracing_subscriber::fmt::format::test: hello\n";
1870+
1871+
assert_info_hello(subscriber, make_writer, expected);
1872+
}
1873+
1874+
#[test]
1875+
fn with_process_id() {
1876+
let make_writer = MockMakeWriter::default();
1877+
let subscriber = crate::fmt::Collector::builder()
1878+
.with_writer(make_writer.clone())
1879+
.with_process_id(true)
1880+
.with_ansi(false)
1881+
.with_timer(MockTime);
1882+
let expected =
1883+
"fake time PID(NUMERIC) INFO tracing_subscriber::fmt::format::test: hello\n";
1884+
1885+
assert_info_hello_ignore_numeric(subscriber, make_writer, expected);
1886+
}
1887+
17801888
#[test]
17811889
fn with_thread_ids() {
17821890
let make_writer = MockMakeWriter::default();

tracing-subscriber/src/fmt/mod.rs

+30
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,36 @@ where
703703
}
704704
}
705705

706+
/// Sets whether or not the binary name of the process is displayed when
707+
/// formatting events. If binary_name is None, argv\[0\] will be used,
708+
/// otherwise the spcified string will be used.
709+
///
710+
/// [argv\[0\]]: std::env::args
711+
pub fn with_binary_name(
712+
self,
713+
display_binary_name: bool,
714+
binary_name: Option<&str>,
715+
) -> CollectorBuilder<N, format::Format<L, T>, F, W> {
716+
CollectorBuilder {
717+
inner: self.inner.with_binary_name(display_binary_name, binary_name),
718+
..self
719+
}
720+
}
721+
722+
/// Sets whether or not the [process ID] of the current thread is displayed
723+
/// when formatting events.
724+
///
725+
/// [process ID]: std::process::id
726+
pub fn with_process_id(
727+
self,
728+
display_process_id: bool,
729+
) -> CollectorBuilder<N, format::Format<L, T>, F, W> {
730+
CollectorBuilder {
731+
inner: self.inner.with_process_id(display_process_id),
732+
..self
733+
}
734+
}
735+
706736
/// Sets whether or not the [name] of the current thread is displayed
707737
/// when formatting events.
708738
///

0 commit comments

Comments
 (0)