Skip to content

Commit e4744ff

Browse files
authored
Merge pull request #209 from gtsiam/main
2 parents 34574df + c5fa7a2 commit e4744ff

File tree

3 files changed

+146
-25
lines changed

3 files changed

+146
-25
lines changed

src/filter/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ impl Builder {
238238
});
239239
} else {
240240
// Consume map of directives.
241-
let directives_map = mem::replace(&mut self.directives, HashMap::new());
241+
let directives_map = mem::take(&mut self.directives);
242242
directives = directives_map
243243
.into_iter()
244244
.map(|(name, level)| Directive { name, level })
@@ -253,7 +253,7 @@ impl Builder {
253253
}
254254

255255
Filter {
256-
directives: mem::replace(&mut directives, Vec::new()),
256+
directives: mem::take(&mut directives),
257257
filter: mem::replace(&mut self.filter, None),
258258
}
259259
}

src/fmt/mod.rs

Lines changed: 115 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ pub(crate) type FormatFn = Box<dyn Fn(&mut Formatter, &Record) -> io::Result<()>
141141
pub(crate) struct Builder {
142142
pub format_timestamp: Option<TimestampPrecision>,
143143
pub format_module_path: bool,
144+
pub format_target: bool,
144145
pub format_level: bool,
145146
pub format_indent: Option<usize>,
146147
pub custom_format: Option<FormatFn>,
@@ -152,7 +153,8 @@ impl Default for Builder {
152153
fn default() -> Self {
153154
Builder {
154155
format_timestamp: Some(Default::default()),
155-
format_module_path: true,
156+
format_module_path: false,
157+
format_target: true,
156158
format_level: true,
157159
format_indent: Some(4),
158160
custom_format: None,
@@ -186,6 +188,7 @@ impl Builder {
186188
let fmt = DefaultFormat {
187189
timestamp: built.format_timestamp,
188190
module_path: built.format_module_path,
191+
target: built.format_target,
189192
level: built.format_level,
190193
written_header_value: false,
191194
indent: built.format_indent,
@@ -210,6 +213,7 @@ type SubtleStyle = &'static str;
210213
struct DefaultFormat<'a> {
211214
timestamp: Option<TimestampPrecision>,
212215
module_path: bool,
216+
target: bool,
213217
level: bool,
214218
written_header_value: bool,
215219
indent: Option<usize>,
@@ -222,6 +226,7 @@ impl<'a> DefaultFormat<'a> {
222226
self.write_timestamp()?;
223227
self.write_level(record)?;
224228
self.write_module_path(record)?;
229+
self.write_target(record)?;
225230
self.finish_header()?;
226231

227232
self.write_args(record)
@@ -311,6 +316,17 @@ impl<'a> DefaultFormat<'a> {
311316
}
312317
}
313318

319+
fn write_target(&mut self, record: &Record) -> io::Result<()> {
320+
if !self.target {
321+
return Ok(());
322+
}
323+
324+
match record.target() {
325+
"" => Ok(()),
326+
target => self.write_header_value(target),
327+
}
328+
}
329+
314330
fn finish_header(&mut self) -> io::Result<()> {
315331
if self.written_header_value {
316332
let close_brace = self.subtle_style("]");
@@ -381,23 +397,33 @@ mod tests {
381397

382398
use log::{Level, Record};
383399

384-
fn write(fmt: DefaultFormat) -> String {
400+
fn write_record(record: Record, fmt: DefaultFormat) -> String {
385401
let buf = fmt.buf.buf.clone();
386402

387-
let record = Record::builder()
388-
.args(format_args!("log\nmessage"))
389-
.level(Level::Info)
390-
.file(Some("test.rs"))
391-
.line(Some(144))
392-
.module_path(Some("test::path"))
393-
.build();
394-
395403
fmt.write(&record).expect("failed to write record");
396404

397405
let buf = buf.borrow();
398406
String::from_utf8(buf.bytes().to_vec()).expect("failed to read record")
399407
}
400408

409+
fn write_target<'a>(target: &'a str, fmt: DefaultFormat) -> String {
410+
write_record(
411+
Record::builder()
412+
.args(format_args!("log\nmessage"))
413+
.level(Level::Info)
414+
.file(Some("test.rs"))
415+
.line(Some(144))
416+
.module_path(Some("test::path"))
417+
.target(target)
418+
.build(),
419+
fmt,
420+
)
421+
}
422+
423+
fn write(fmt: DefaultFormat) -> String {
424+
write_target("", fmt)
425+
}
426+
401427
#[test]
402428
fn format_with_header() {
403429
let writer = writer::Builder::new()
@@ -409,6 +435,7 @@ mod tests {
409435
let written = write(DefaultFormat {
410436
timestamp: None,
411437
module_path: true,
438+
target: false,
412439
level: true,
413440
written_header_value: false,
414441
indent: None,
@@ -430,6 +457,7 @@ mod tests {
430457
let written = write(DefaultFormat {
431458
timestamp: None,
432459
module_path: false,
460+
target: false,
433461
level: false,
434462
written_header_value: false,
435463
indent: None,
@@ -451,6 +479,7 @@ mod tests {
451479
let written = write(DefaultFormat {
452480
timestamp: None,
453481
module_path: true,
482+
target: false,
454483
level: true,
455484
written_header_value: false,
456485
indent: Some(4),
@@ -472,6 +501,7 @@ mod tests {
472501
let written = write(DefaultFormat {
473502
timestamp: None,
474503
module_path: true,
504+
target: false,
475505
level: true,
476506
written_header_value: false,
477507
indent: Some(0),
@@ -493,6 +523,7 @@ mod tests {
493523
let written = write(DefaultFormat {
494524
timestamp: None,
495525
module_path: false,
526+
target: false,
496527
level: false,
497528
written_header_value: false,
498529
indent: Some(4),
@@ -514,6 +545,7 @@ mod tests {
514545
let written = write(DefaultFormat {
515546
timestamp: None,
516547
module_path: false,
548+
target: false,
517549
level: false,
518550
written_header_value: false,
519551
indent: None,
@@ -535,6 +567,7 @@ mod tests {
535567
let written = write(DefaultFormat {
536568
timestamp: None,
537569
module_path: false,
570+
target: false,
538571
level: false,
539572
written_header_value: false,
540573
indent: Some(4),
@@ -544,4 +577,76 @@ mod tests {
544577

545578
assert_eq!("log\n\n message\n\n", written);
546579
}
580+
581+
#[test]
582+
fn format_target() {
583+
let writer = writer::Builder::new()
584+
.write_style(WriteStyle::Never)
585+
.build();
586+
587+
let mut f = Formatter::new(&writer);
588+
589+
let written = write_target(
590+
"target",
591+
DefaultFormat {
592+
timestamp: None,
593+
module_path: true,
594+
target: true,
595+
level: true,
596+
written_header_value: false,
597+
indent: None,
598+
suffix: "\n",
599+
buf: &mut f,
600+
},
601+
);
602+
603+
assert_eq!("[INFO test::path target] log\nmessage\n", written);
604+
}
605+
606+
#[test]
607+
fn format_empty_target() {
608+
let writer = writer::Builder::new()
609+
.write_style(WriteStyle::Never)
610+
.build();
611+
612+
let mut f = Formatter::new(&writer);
613+
614+
let written = write(DefaultFormat {
615+
timestamp: None,
616+
module_path: true,
617+
target: true,
618+
level: true,
619+
written_header_value: false,
620+
indent: None,
621+
suffix: "\n",
622+
buf: &mut f,
623+
});
624+
625+
assert_eq!("[INFO test::path] log\nmessage\n", written);
626+
}
627+
628+
#[test]
629+
fn format_no_target() {
630+
let writer = writer::Builder::new()
631+
.write_style(WriteStyle::Never)
632+
.build();
633+
634+
let mut f = Formatter::new(&writer);
635+
636+
let written = write_target(
637+
"target",
638+
DefaultFormat {
639+
timestamp: None,
640+
module_path: true,
641+
target: false,
642+
level: true,
643+
written_header_value: false,
644+
indent: None,
645+
suffix: "\n",
646+
buf: &mut f,
647+
},
648+
);
649+
650+
assert_eq!("[INFO test::path] log\nmessage\n", written);
651+
}
547652
}

src/lib.rs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -97,28 +97,38 @@
9797
//! directives*. A logging directive is of the form:
9898
//!
9999
//! ```text
100-
//! path::to::module=level
100+
//! example::log::target=level
101101
//! ```
102102
//!
103-
//! The path to the module is rooted in the name of the crate it was compiled
104-
//! for, so if your program is contained in a file `hello.rs`, for example, to
105-
//! turn on logging for this file you would use a value of `RUST_LOG=hello`.
106-
//! Furthermore, this path is a prefix-search, so all modules nested in the
107-
//! specified module will also have logging enabled.
103+
//! The log target is typically equal to the path of the module the message
104+
//! in question originated from, though it can be overriden.
105+
//!
106+
//! The path is rooted in the name of the crate it was compiled for, so if
107+
//! your program is in a file called, for example, `hello.rs`, the path would
108+
//! simply be be `hello`.
109+
//!
110+
//! Furthermore, the the log can be filtered using prefix-search based on the
111+
//! specified log target. A value of, for example, `RUST_LOG=example`, would
112+
//! match all of the messages with targets:
113+
//!
114+
//! * `example`
115+
//! * `example::test`
116+
//! * `example::test::module::submodule`
117+
//! * `examples::and_more_examples`
108118
//!
109119
//! When providing the crate name or a module path, explicitly specifying the
110-
//! log level is optional. If omitted, all logging for the item (and its
111-
//! children) will be enabled.
120+
//! log level is optional. If omitted, all logging for the item will be
121+
//! enabled.
112122
//!
113123
//! The names of the log levels that may be specified correspond to the
114124
//! variations of the [`log::Level`][level-enum] enum from the `log`
115125
//! crate. They are:
116126
//!
117-
//! * `error`
118-
//! * `warn`
119-
//! * `info`
120-
//! * `debug`
121-
//! * `trace`
127+
//! * `error`
128+
//! * `warn`
129+
//! * `info`
130+
//! * `debug`
131+
//! * `trace`
122132
//!
123133
//! There is also a pseudo logging level, `off`, which may be specified to
124134
//! disable all logging for a given module or for the entire application. As
@@ -598,6 +608,12 @@ impl Builder {
598608
self
599609
}
600610

611+
/// Whether or not to write the target in the default format.
612+
pub fn format_target(&mut self, write: bool) -> &mut Self {
613+
self.format.format_target = write;
614+
self
615+
}
616+
601617
/// Configures the amount of spaces to use to indent multiline log records.
602618
/// A value of `None` disables any kind of indentation.
603619
pub fn format_indent(&mut self, indent: Option<usize>) -> &mut Self {

0 commit comments

Comments
 (0)