Skip to content

Commit

Permalink
fix #370
Browse files Browse the repository at this point in the history
  • Loading branch information
Dirreke committed May 3, 2024
1 parent 8ab1b34 commit 47c9cad
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 3 deletions.
File renamed without changes.
119 changes: 119 additions & 0 deletions examples/log_to_file_with_rolling_and_time_trigger.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
//! 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 2s which is very small and only for demo purposes
const TIME_TRIGGER_CONFIG: TimeTriggerConfig = TimeTriggerConfig {
interval: TimeTriggerInterval::Second(2),
max_random_delay: 0,
modulate: false,
};

/// 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(6);

/// 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::time::{TimeTrigger, TimeTriggerConfig, TimeTriggerInterval},
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 time_trigger_config = TimeTriggerConfig {
// interval: Duration::from_secs(1),
// delay: Duration::from_secs(0),
// modulate: false,
// };
let trigger = TimeTrigger::new(TIME_TRIGGER_CONFIG);
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(())
}
12 changes: 9 additions & 3 deletions src/append/rolling_file/policy/compound/trigger/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ use crate::config::{Deserialize, Deserializers};
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TimeTriggerConfig {
/// The date/time interval between log file rolls.
interval: TimeTriggerInterval,
/// Whether to modulate the interval.
#[serde(default)]
modulate: bool,
/// The maximum random delay in seconds.
#[serde(default)]
max_random_delay: u64,
}
Expand All @@ -34,9 +37,12 @@ pub struct TimeTriggerConfig {
/// Configuration for the time trigger.
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default)]
pub struct TimeTriggerConfig {
interval: TimeTriggerInterval,
modulate: bool,
max_random_delay: u64,
/// The date/time interval between log file rolls.Q
pub interval: TimeTriggerInterval,
/// Whether to modulate the interval.
pub modulate: bool,
/// The maximum random delay in seconds.
pub max_random_delay: u64,
}

/// A trigger which rolls the log once it has passed a certain time.
Expand Down

0 comments on commit 47c9cad

Please sign in to comment.