Skip to main content

LoggerBuilder

Struct LoggerBuilder 

Source
pub struct LoggerBuilder { /* private fields */ }
Expand description

Builder for configuring a Logger with custom appenders.

Construct one with Logger::builder, add appenders, then call LoggerBuilder::build to get the logger or LoggerBuilder::init to install it as the global logger.

Implementations§

Source§

impl LoggerBuilder

Source

pub fn level(self, level: LogLevel) -> Self

Set the log level. Defaults to the level passed to Logger::builder.

Source

pub fn appender(self, appender: Box<dyn Appender>) -> Self

Add an appender. May be called multiple times to add several appenders.

Examples found in repository?
examples/custom_appender.rs (line 49)
44fn main() {
45    let collector = VecAppender::new(Arc::new(KeyValueLayout));
46
47    // Build a logger with a custom appender and install it as the global logger.
48    Logger::builder(LogLevel::Info)
49        .appender(Box::new(collector.clone()))
50        .init();
51
52    log4rc::info!("Hello, appender!");
53    log4rc::debug!("This is filtered out at Info level");
54    log4rc::error!("Something went wrong");
55
56    // Only the Info and Error messages made it through the level filter.
57    for line in collector.messages() {
58        println!("captured: {line}");
59    }
60}
More examples
Hide additional examples
examples/file_appender.rs (line 12)
8fn main() {
9    let log_path = std::env::temp_dir().join("log4rc-file-appender.log");
10
11    Logger::builder(LogLevel::Info)
12        .appender(Box::new(ConsoleAppender::new(Box::new(SimpleLayout))))
13        .appender(Box::new(
14            FileAppender::open(&log_path, Box::new(SimpleLayout))
15                .expect("failed to open log file"),
16        ))
17        .init();
18
19    log4rc::info!("Writing to console and file");
20    log4rc::error!("An error also goes to both");
21    log4rc::debug!("Filtered out at Info level");
22
23    // Read the file back to prove the messages were written to disk.
24    let mut contents = String::new();
25    std::fs::File::open(&log_path)
26        .expect("failed to reopen log file")
27        .read_to_string(&mut contents)
28        .expect("failed to read log file");
29
30    println!("\n--- Contents of {} ---", log_path.display());
31    print!("{contents}");
32    let _ = std::fs::remove_file(&log_path);
33}
examples/rolling_file_appender.rs (lines 16-23)
10fn main() {
11    let dir = std::env::temp_dir();
12    let prefix = format!("log4rc-rolling-{}", std::process::id());
13    let log_path = dir.join(format!("{prefix}.log"));
14
15    Logger::builder(LogLevel::Info)
16        .appender(Box::new(
17            FileAppender::builder(&log_path, Box::new(SimpleLayout))
18                .max_size(100) // tiny limit so a few messages trigger a roll
19                .max_files(3) // keep only the 3 newest rotated files
20                .compressed() // gzip rotated files
21                .build()
22                .expect("failed to open log file"),
23        ))
24        .init();
25
26    for i in 0..10 {
27        log4rc::info!("This is message number {i:02} with some padding to grow the file");
28    }
29
30    // List the active file plus any rotated siblings.
31    let mut files: Vec<_> = std::fs::read_dir(&dir)
32        .unwrap()
33        .flatten()
34        .map(|e| e.path())
35        .filter(|p| {
36            p.file_name()
37                .and_then(|n| n.to_str())
38                .is_some_and(|n| n.starts_with(&prefix))
39        })
40        .collect();
41    files.sort();
42
43    println!("--- Log files ---");
44    let mut total_lines = 0;
45    for path in &files {
46        let contents = if path.to_string_lossy().ends_with(".gz") {
47            let mut contents = String::new();
48            let file = std::fs::File::open(path).expect("failed to open rotated file");
49            GzDecoder::new(file)
50                .read_to_string(&mut contents)
51                .expect("failed to decompress rotated file");
52            contents
53        } else {
54            std::fs::read_to_string(path).expect("failed to read log file")
55        };
56        let lines = contents.lines().count();
57        total_lines += lines;
58        println!("{} ({} lines):", path.display(), lines);
59    }
60    println!("total lines across files: {total_lines}");
61
62    for path in files {
63        let _ = std::fs::remove_file(path);
64    }
65}
Source

pub fn build(self) -> Logger

Build the configured logger.

Source

pub fn init(self)

Build the logger and install it as the global logger, replacing any previously configured logger.

Examples found in repository?
examples/custom_appender.rs (line 50)
44fn main() {
45    let collector = VecAppender::new(Arc::new(KeyValueLayout));
46
47    // Build a logger with a custom appender and install it as the global logger.
48    Logger::builder(LogLevel::Info)
49        .appender(Box::new(collector.clone()))
50        .init();
51
52    log4rc::info!("Hello, appender!");
53    log4rc::debug!("This is filtered out at Info level");
54    log4rc::error!("Something went wrong");
55
56    // Only the Info and Error messages made it through the level filter.
57    for line in collector.messages() {
58        println!("captured: {line}");
59    }
60}
More examples
Hide additional examples
examples/file_appender.rs (line 17)
8fn main() {
9    let log_path = std::env::temp_dir().join("log4rc-file-appender.log");
10
11    Logger::builder(LogLevel::Info)
12        .appender(Box::new(ConsoleAppender::new(Box::new(SimpleLayout))))
13        .appender(Box::new(
14            FileAppender::open(&log_path, Box::new(SimpleLayout))
15                .expect("failed to open log file"),
16        ))
17        .init();
18
19    log4rc::info!("Writing to console and file");
20    log4rc::error!("An error also goes to both");
21    log4rc::debug!("Filtered out at Info level");
22
23    // Read the file back to prove the messages were written to disk.
24    let mut contents = String::new();
25    std::fs::File::open(&log_path)
26        .expect("failed to reopen log file")
27        .read_to_string(&mut contents)
28        .expect("failed to read log file");
29
30    println!("\n--- Contents of {} ---", log_path.display());
31    print!("{contents}");
32    let _ = std::fs::remove_file(&log_path);
33}
examples/rolling_file_appender.rs (line 24)
10fn main() {
11    let dir = std::env::temp_dir();
12    let prefix = format!("log4rc-rolling-{}", std::process::id());
13    let log_path = dir.join(format!("{prefix}.log"));
14
15    Logger::builder(LogLevel::Info)
16        .appender(Box::new(
17            FileAppender::builder(&log_path, Box::new(SimpleLayout))
18                .max_size(100) // tiny limit so a few messages trigger a roll
19                .max_files(3) // keep only the 3 newest rotated files
20                .compressed() // gzip rotated files
21                .build()
22                .expect("failed to open log file"),
23        ))
24        .init();
25
26    for i in 0..10 {
27        log4rc::info!("This is message number {i:02} with some padding to grow the file");
28    }
29
30    // List the active file plus any rotated siblings.
31    let mut files: Vec<_> = std::fs::read_dir(&dir)
32        .unwrap()
33        .flatten()
34        .map(|e| e.path())
35        .filter(|p| {
36            p.file_name()
37                .and_then(|n| n.to_str())
38                .is_some_and(|n| n.starts_with(&prefix))
39        })
40        .collect();
41    files.sort();
42
43    println!("--- Log files ---");
44    let mut total_lines = 0;
45    for path in &files {
46        let contents = if path.to_string_lossy().ends_with(".gz") {
47            let mut contents = String::new();
48            let file = std::fs::File::open(path).expect("failed to open rotated file");
49            GzDecoder::new(file)
50                .read_to_string(&mut contents)
51                .expect("failed to decompress rotated file");
52            contents
53        } else {
54            std::fs::read_to_string(path).expect("failed to read log file")
55        };
56        let lines = contents.lines().count();
57        total_lines += lines;
58        println!("{} ({} lines):", path.display(), lines);
59    }
60    println!("total lines across files: {total_lines}");
61
62    for path in files {
63        let _ = std::fs::remove_file(path);
64    }
65}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.