Skip to content

Commit

Permalink
Respect local timezone when rotating files daily
Browse files Browse the repository at this point in the history
  • Loading branch information
SpriteOvO committed Aug 28, 2024
1 parent adf6c0d commit 70901db
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 40 deletions.
172 changes: 133 additions & 39 deletions spdlog/src/sink/rotating_file_sink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,8 +500,8 @@ impl RotatorTimePoint {
// constructor.
#[must_use]
fn next_rotation_time_point(time_point: TimePoint, now: SystemTime) -> SystemTime {
let now: DateTime<Utc> = now.into();
let mut rotation_time: DateTime<Utc> = now;
let now: DateTime<Local> = now.into();
let mut rotation_time = now;

match time_point {
TimePoint::Daily { hour, minute } => {
Expand Down Expand Up @@ -806,12 +806,14 @@ impl RotatingFileSinkBuilder<PathBuf, RotationPolicy> {

#[cfg(test)]
mod tests {
use chrono::FixedOffset;

use super::*;
use crate::{prelude::*, test_utils::*, Level, Record};

static BASE_LOGS_PATH: Lazy<PathBuf> = Lazy::new(|| {
let path = TEST_LOGS_PATH.join("rotating_file_sink");
fs::create_dir(&path).unwrap();
_ = fs::create_dir(&path);
path
});

Expand Down Expand Up @@ -1040,6 +1042,29 @@ mod tests {
path
});

const SECOND_1: Duration = Duration::from_secs(1);
const HOUR_1: Duration = Duration::from_secs(60 * 60);
const DAY_1: Duration = Duration::from_secs(60 * 60 * 24);

#[track_caller]
fn assert_files_count(file_name_prefix: &str, expected: usize) {
let paths = fs::read_dir(LOGS_PATH.clone()).unwrap();

let actual = paths.fold(0_usize, |count, entry| {
if entry
.unwrap()
.file_name()
.to_string_lossy()
.starts_with(file_name_prefix)
{
count + 1
} else {
count
}
});
assert_eq!(actual, expected)
}

#[test]
fn calc_file_path() {
let system_time = Local.with_ymd_and_hms(2012, 3, 4, 5, 6, 7).unwrap().into();
Expand Down Expand Up @@ -1114,61 +1139,130 @@ mod tests {
logger
};

let exist_files = |file_name_prefix| {
let paths = fs::read_dir(LOGS_PATH.clone()).unwrap();

paths.fold(0_usize, |count, entry| {
if entry
.unwrap()
.file_name()
.to_string_lossy()
.starts_with(file_name_prefix)
{
count + 1
} else {
count
}
})
};

let exist_hourly_files = || exist_files("hourly");
let exist_daily_files = || exist_files("daily");

const SECOND_1: Duration = Duration::from_secs(1);
const HOUR_1: Duration = Duration::from_secs(60 * 60);
const DAY_1: Duration = Duration::from_secs(60 * 60 * 24);

{
let logger = build(true);
let mut record = Record::new(Level::Info, "test log message");
let initial_time = record.time();

assert_eq!(exist_hourly_files(), 1);
assert_eq!(exist_daily_files(), 1);
assert_files_count("hourly", 1);
assert_files_count("daily", 1);

logger.log(&record);
assert_eq!(exist_hourly_files(), 1);
assert_eq!(exist_daily_files(), 1);
assert_files_count("hourly", 1);
assert_files_count("daily", 1);

record.set_time(record.time() + HOUR_1 + SECOND_1);
logger.log(&record);
assert_eq!(exist_hourly_files(), 2);
assert_eq!(exist_daily_files(), 1);
assert_files_count("hourly", 2);
assert_files_count("daily", 1);

record.set_time(record.time() + HOUR_1 + SECOND_1);
logger.log(&record);
assert_eq!(exist_hourly_files(), 3);
assert_eq!(exist_daily_files(), 1);
assert_files_count("hourly", 3);
assert_files_count("daily", 1);

record.set_time(record.time() + SECOND_1);
logger.log(&record);
assert_eq!(exist_hourly_files(), 3);
assert_eq!(exist_daily_files(), 1);
assert_files_count("hourly", 3);
assert_files_count("daily", 1);

record.set_time(initial_time + DAY_1 + SECOND_1);
logger.log(&record);
assert_eq!(exist_hourly_files(), 4);
assert_eq!(exist_daily_files(), 2);
assert_files_count("hourly", 4);
assert_files_count("daily", 2);
}
}

#[test]
fn respect_local_tz() {
let prefix = "respect_local_tz";

let logger = {
fs::remove_dir_all(LOGS_PATH.as_path()).unwrap();
fs::create_dir(LOGS_PATH.as_path()).unwrap();

let daily_sink = RotatingFileSink::builder()
.base_path(LOGS_PATH.join(format!("{prefix}.log")))
.rotation_policy(RotationPolicy::Daily { hour: 0, minute: 0 })
.rotate_on_open(true)
.build()
.unwrap();

build_test_logger(|b| b.sink(Arc::new(daily_sink)).level_filter(LevelFilter::All))
};

{
let mut record = Record::new(Level::Info, "test log message");
let initial_time = FixedOffset::east_opt(8 * 3600)
.unwrap()
.with_ymd_and_hms(2024, 8, 29, 11, 45, 14)
.unwrap();

assert_files_count(prefix, 1);

record.set_time(initial_time.to_utc().into());
logger.log(&record);
assert_files_count(prefix, 1);

record.set_time(record.time() + HOUR_1 + SECOND_1);
logger.log(&record);
assert_files_count(prefix, 1);

record.set_time(record.time() + HOUR_1 + SECOND_1);
logger.log(&record);
assert_files_count(prefix, 1);

record.set_time(
initial_time
.with_day(30)
.unwrap()
.with_hour(0)
.unwrap()
.with_minute(1)
.unwrap()
.to_utc()
.into(),
);
logger.log(&record);
assert_files_count(prefix, 2);

record.set_time(record.time() + HOUR_1 + SECOND_1);
logger.log(&record);
assert_files_count(prefix, 2);

record.set_time(
initial_time
.with_day(30)
.unwrap()
.with_hour(8)
.unwrap()
.with_minute(2)
.unwrap()
.to_utc()
.into(),
);
logger.log(&record);
assert_files_count(prefix, 2);

record.set_time(record.time() + HOUR_1 + SECOND_1);
logger.log(&record);
assert_files_count(prefix, 2);

record.set_time(
initial_time
.with_day(31)
.unwrap()
.with_hour(0)
.unwrap()
.to_utc()
.into(),
);
logger.log(&record);
assert_files_count(prefix, 3);

record.set_time(record.time() + HOUR_1 + SECOND_1);
logger.log(&record);
assert_files_count(prefix, 3);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion spdlog/src/test_utils/unit_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ use crate::sync::*;

pub static TEST_LOGS_PATH: Lazy<PathBuf> = Lazy::new(|| {
let path = Path::new(env!("OUT_DIR")).join("test_logs");
fs::create_dir(&path).unwrap();
_ = fs::create_dir(&path);
path
});

0 comments on commit 70901db

Please sign in to comment.