Skip to content

Commit

Permalink
Create an example of logging with file rotation (estk#295)
Browse files Browse the repository at this point in the history
* Create an example of logging with file rotation

* Fix filename extension

* Add example to Cargo.toml

* Move configuration values out of main to top

* Correct Merge Conflict Correctly

Co-authored-by: Bryan Conn <[email protected]>

* Use rustfmt on nightly

---------

Co-authored-by: Bryan Conn <[email protected]>
  • Loading branch information
c-git and bconn98 authored Feb 2, 2024
1 parent b0ad8ba commit a898a07
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ required-features = ["console_appender", "file_appender", "rolling_file_appender
name = "compile_time_config"
required-features = ["yaml_format", "config_parsing"]

[[example]]
name = "log_to_file_with_rolling"
required-features = ["file_appender", "rolling_file_appender", "size_trigger"]

[[example]]
name = "multi_logger_config"
required-features = ["yaml_format", "config_parsing"]
108 changes: 108 additions & 0 deletions examples/log_to_file_with_rolling.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
//! Example showing how to use logging with a rolling trigger based on size
//!
//! NB: The size used in the example is intentionally small so multiple file
//! will be created in the 2 seconds that the example is set to run and is not
//! intended for practical for usage

/// This is the size at which a new file should be created. For the demo it is
/// set to 2KB which is very small and only for demo purposes
const TRIGGER_FILE_SIZE: u64 = 2 * 1024;

/// Delay between log messages for demo purposes
const TIME_BETWEEN_LOG_MESSAGES: Duration = Duration::from_millis(10);

/// Number of archive log files to keep
const LOG_FILE_COUNT: u32 = 3;

/// Time demo is set to run for (Set to be long enough for multiple files to be created)
const RUN_TIME: Duration = Duration::from_secs(2);

/// Location where logs will be written to
const FILE_PATH: &str = "/tmp/foo.log";

/// Location where log archives will be moved to
/// For Pattern info See:
/// https://docs.rs/log4rs/*/log4rs/append/rolling_file/policy/compound/roll/fixed_window/struct.FixedWindowRollerBuilder.html#method.build
const ARCHIVE_PATTERN: &str = "/tmp/archive/foo.{}.log";

use std::{
thread::sleep,
time::{Duration, Instant},
};

use log::{debug, error, info, trace, warn, LevelFilter, SetLoggerError};
use log4rs::{
append::{
console::{ConsoleAppender, Target},
rolling_file::policy::compound::{
roll::fixed_window::FixedWindowRoller, trigger::size::SizeTrigger, CompoundPolicy,
},
},
config::{Appender, Config, Root},
encode::pattern::PatternEncoder,
filter::threshold::ThresholdFilter,
};

fn main() -> Result<(), SetLoggerError> {
let level = log::LevelFilter::Info;

// Build a stderr logger.
let stderr = ConsoleAppender::builder().target(Target::Stderr).build();

// Create a policy to use with the file logging
let trigger = SizeTrigger::new(TRIGGER_FILE_SIZE);
let roller = FixedWindowRoller::builder()
.base(0) // Default Value (line not needed unless you want to change from 0 (only here for demo purposes)
.build(ARCHIVE_PATTERN, LOG_FILE_COUNT) // Roll based on pattern and max 3 archive files
.unwrap();
let policy = CompoundPolicy::new(Box::new(trigger), Box::new(roller));

// Logging to log file. (with rolling)
let logfile = log4rs::append::rolling_file::RollingFileAppender::builder()
// Pattern: https://docs.rs/log4rs/*/log4rs/encode/pattern/index.html
.encoder(Box::new(PatternEncoder::new("{l} - {m}\n")))
.build(FILE_PATH, Box::new(policy))
.unwrap();

// Log Trace level output to file where trace is the default level
// and the programmatically specified level to stderr.
let config = Config::builder()
.appender(Appender::builder().build("logfile", Box::new(logfile)))
.appender(
Appender::builder()
.filter(Box::new(ThresholdFilter::new(level)))
.build("stderr", Box::new(stderr)),
)
.build(
Root::builder()
.appender("logfile")
.appender("stderr")
.build(LevelFilter::Trace),
)
.unwrap();

// Use this to change log levels at runtime.
// This means you can change the default log level to trace
// if you are trying to debug an issue and need more logs on then turn it off
// once you are done.
let _handle = log4rs::init_config(config)?;

error!("Goes to stderr and file");
warn!("Goes to stderr and file");
info!("Goes to stderr and file");
debug!("Goes to file only");
trace!("Goes to file only");

// Generate some log messages to trigger rolling
let instant = Instant::now();
while instant.elapsed() < RUN_TIME {
info!("Running for {:?}", instant.elapsed());
sleep(TIME_BETWEEN_LOG_MESSAGES);
}
info!(
"See '{}' for log and '{}' for archived logs",
FILE_PATH, ARCHIVE_PATTERN
);

Ok(())
}

0 comments on commit a898a07

Please sign in to comment.