1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 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(())
}
|