Skip to content

Commit b96a595

Browse files
committed
Merge branch 'samantehrani-trc-envfilter'
2 parents 84ba821 + 0714303 commit b96a595

File tree

6 files changed

+128
-30
lines changed

6 files changed

+128
-30
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,17 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this
66
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.31.6] - 2025-10-08
9+
10+
Make sure that `tracing` does not get confused with blanks that are normally printed into
11+
`LogSpecification`'s `Display` String (issue [#200](https://github.com/emabee/flexi_logger/pull/200)),
12+
by providing a dedicated method.
13+
Kudos goes to [samantehrani](https://github.com/samantehrani).
14+
815
## [0.31.5] - 2025-10-06
916

1017
Fix [issue #198](https://github.com/emabee/flexi_logger/issues/198).
18+
Kudos goes to [hasezoey](https://github.com/hasezoey).
1119

1220
## [0.31.4] - 2025-09-23
1321

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "flexi_logger"
3-
version = "0.31.5"
3+
version = "0.31.6"
44
authors = ["emabee <[email protected]>"]
55
categories = ["development-tools::debugging"]
66
description = """

src/log_specification.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ use std::{collections::HashMap, env};
5454
/// rustc (“extern crate” does not allow hyphens).
5555
#[derive(Clone, Debug, Default)]
5656
pub struct LogSpecification {
57-
module_filters: Vec<ModuleFilter>,
57+
/// List of module filters.
58+
pub module_filters: Vec<ModuleFilter>,
5859
#[cfg(feature = "textfilter")]
5960
textfilter: Option<Box<Regex>>,
6061
}
@@ -429,10 +430,12 @@ impl LogSpecification {
429430
.find(|mod_filter| mod_filter.module_name.as_deref() == module)
430431
.map(|found_filter| found_filter.level_filter)
431432
}
432-
}
433433

434-
impl std::fmt::Display for LogSpecification {
435-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
434+
pub(crate) fn to_string_int(
435+
&self,
436+
f: &mut std::fmt::Formatter<'_>,
437+
space: Space,
438+
) -> std::fmt::Result {
436439
let mut write_comma = false;
437440
// Optional: Default log level
438441
if let Some(last) = self.module_filters.last() {
@@ -442,24 +445,52 @@ impl std::fmt::Display for LogSpecification {
442445
}
443446
}
444447

445-
// TODO: global_pattern is not modelled into String representation, only into yaml file
448+
// TODO: global_pattern (feature text_filter) is not modelled into String representation,
449+
// only into yaml file
446450
// Optional: specify a regular expression to suppress all messages that don't match
447451
// w.write_all(b"#global_pattern = 'foo'\n")?;
448452

449453
// Specific log levels per module
450454
for mf in &self.module_filters {
451455
if let Some(ref name) = mf.module_name {
452456
if write_comma {
453-
write!(f, ", ")?;
457+
write!(f, ",{}", space.as_str())?;
454458
}
455-
write!(f, "{name} = {}", mf.level_filter.to_string().to_lowercase())?;
459+
write!(
460+
f,
461+
"{name}{}={}{}",
462+
space.as_str(),
463+
space.as_str(),
464+
mf.level_filter.to_string().to_lowercase()
465+
)?;
456466
write_comma = true;
457467
}
458468
}
459469
Ok(())
460470
}
461471
}
462472

473+
#[derive(Clone, Copy, Debug)]
474+
pub(crate) enum Space {
475+
Yes,
476+
#[cfg(feature = "trc")]
477+
No,
478+
}
479+
impl Space {
480+
fn as_str(&self) -> &str {
481+
match self {
482+
Space::Yes => " ",
483+
#[cfg(feature = "trc")]
484+
Space::No => "",
485+
}
486+
}
487+
}
488+
impl std::fmt::Display for LogSpecification {
489+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
490+
self.to_string_int(f, Space::Yes)
491+
}
492+
}
493+
463494
impl std::convert::TryFrom<&str> for LogSpecification {
464495
type Error = FlexiLoggerError;
465496
fn try_from(value: &str) -> Result<Self, Self::Error> {

src/trc.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
1212
pub use crate::logger_handle::LogSpecSubscriber;
1313
use crate::{
14+
log_specification::Space,
1415
logger::{create_specfile_watcher, synchronize_subscriber_with_specfile},
1516
writers::{FileLogWriterBuilder, FileLogWriterHandle},
1617
};
@@ -229,7 +230,12 @@ pub fn setup_tracing(
229230
struct LogSpecAsFilter(pub LogSpecification);
230231
impl From<LogSpecAsFilter> for EnvFilter {
231232
fn from(wrapped_logspec: LogSpecAsFilter) -> Self {
232-
Self::new(wrapped_logspec.0.to_string())
233+
Self::new(wrapped_logspec.to_string())
234+
}
235+
}
236+
impl std::fmt::Display for LogSpecAsFilter {
237+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
238+
self.0.to_string_int(f, Space::No)
233239
}
234240
}
235241

src/writers/file_log_writer/builder.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::{
22
default_format,
33
writers::{FileLogWriter, FileLogWriterConfig, LogWriter},
4-
Cleanup, Criterion, FileSpec, FlexiLoggerError, FormatFunction, Naming, WriteMode,
4+
Cleanup, Criterion, FileSpec, FlexiLoggerError, FormatFunction, LogfileSelector, Naming,
5+
WriteMode,
56
};
67
use std::{path::PathBuf, sync::Arc};
78

@@ -348,3 +349,25 @@ impl Drop for FileLogWriterHandle {
348349
self.0.shutdown();
349350
}
350351
}
352+
impl FileLogWriterHandle {
353+
/// Returns the list of existing log files according to the current `FileSpec`.
354+
///
355+
/// Depending on the given selector, the list may include the CURRENT log file
356+
/// and the compressed files, if they exist.
357+
///
358+
/// # Errors
359+
///
360+
/// `FlexiLoggerError::Poison` if some mutex is poisoned.
361+
pub fn existing_log_files(
362+
&self,
363+
selector: &LogfileSelector,
364+
) -> Result<Vec<PathBuf>, FlexiLoggerError> {
365+
self.0.existing_log_files(selector)
366+
}
367+
368+
// Allows checking the logs written so far to the writer
369+
#[doc(hidden)]
370+
pub fn validate_logs(&self, expected: &[(&'static str, &'static str, &'static str)]) {
371+
self.0.validate_logs(expected);
372+
}
373+
}

tests/test_trc.rs

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,16 @@ mod a {
99
use std::io::Write;
1010
use tracing::{debug, error, info, trace, warn};
1111

12-
const WAIT_MILLIS: u64 = 2000;
12+
const WAIT_MILLIS: u64 = 1_500;
1313

14-
/// Test of the specfile feature
1514
#[test]
1615
fn test_specfile() {
1716
let specfile = super::test_utils::file("logspec.toml");
1817

1918
std::fs::remove_file(&specfile).ok();
2019
assert!(!specfile.exists());
2120

22-
let _keep_alive_handles = flexi_logger::trc::setup_tracing(
21+
let keep_alive_handles = flexi_logger::trc::setup_tracing(
2322
LogSpecification::info(),
2423
Some(&specfile),
2524
FileLogWriter::builder(FileSpec::default().directory(super::test_utils::dir()))
@@ -39,11 +38,8 @@ mod a {
3938

4039
assert!(specfile.exists());
4140

42-
error!("This is an error-0");
43-
warn!("This is a warning-0");
44-
info!("This is an info-0");
45-
debug!("This is a debug-0");
46-
trace!("This is a trace-0");
41+
write_logs(0);
42+
super::b::write_logs(0);
4743

4844
eprintln!(
4945
"[{}] ===== behave like many editors: rename and recreate; set to warn",
@@ -60,20 +56,18 @@ mod a {
6056
.unwrap();
6157
file.write_all(
6258
b"
63-
global_level = 'warn'
64-
[modules]
59+
global_level = 'warn'\n\
60+
[modules]\n\
61+
'test_trc::b' = 'error'\n\
6562
",
6663
)
6764
.unwrap();
6865
}
6966

7067
std::thread::sleep(std::time::Duration::from_millis(WAIT_MILLIS));
7168

72-
error!("This is an error-1");
73-
warn!("This is a warning-1");
74-
info!("This is an info-1");
75-
debug!("This is a debug-1");
76-
trace!("This is a trace-1");
69+
write_logs(1);
70+
super::b::write_logs(1);
7771

7872
eprintln!(
7973
"[{}] ===== truncate and rewrite; set to error",
@@ -89,6 +83,7 @@ mod a {
8983
"\
9084
global_level = 'error'\n\
9185
[modules]\n\
86+
'test_trc::b' = 'debug'\n\
9287
"
9388
.as_bytes(),
9489
)
@@ -97,10 +92,45 @@ mod a {
9792

9893
std::thread::sleep(std::time::Duration::from_millis(WAIT_MILLIS));
9994

100-
error!("This is an error-2");
101-
warn!("This is a warning-2");
102-
info!("This is an info-2");
103-
debug!("This is a debug-2");
104-
trace!("This is a trace-2");
95+
write_logs(2);
96+
super::b::write_logs(2);
97+
98+
std::thread::sleep(std::time::Duration::from_millis(WAIT_MILLIS));
99+
100+
keep_alive_handles.0.validate_logs(&[
101+
("ERROR", "test_trc::a", "0"),
102+
("WARN", "test_trc::a", "0"),
103+
("INFO", "test_trc::a", "0"),
104+
("ERROR", "test_trc::b", "0"),
105+
("WARN", "test_trc::b", "0"),
106+
("INFO", "test_trc::b", "0"),
107+
("ERROR", "test_trc::a:", "1"),
108+
("WARN", "test_trc::a:", "1"),
109+
("ERROR", "test_trc::b:", "1"),
110+
("ERROR", "test_trc::a:", "2"),
111+
("ERROR", "test_trc::b:", "2"),
112+
("WARN", "test_trc::b:", "2"),
113+
("INFO", "test_trc::b:", "2"),
114+
("DEBUG", "test_trc::b:", "2"),
115+
]);
116+
}
117+
118+
pub(crate) fn write_logs(idx: u8) {
119+
error!("Error from a::write_logs {idx}");
120+
warn!("Warning from a::write_logs {idx}");
121+
info!("Info from a::write_logs {idx}");
122+
debug!("Debug from a::write_logs {idx}");
123+
trace!("Trace from a::write_logs {idx}");
124+
}
125+
}
126+
mod b {
127+
use tracing::{debug, error, info, trace, warn};
128+
129+
pub(crate) fn write_logs(idx: u8) {
130+
error!("Error from b::write_logs {idx}");
131+
warn!("Warning from b::write_logs {idx}");
132+
info!("Info from b::write_logs {idx}");
133+
debug!("Debug from b::write_logs {idx}");
134+
trace!("Trace from b::write_logs {idx}");
105135
}
106136
}

0 commit comments

Comments
 (0)