KeepSome first version

pull/677/head
Krzysztof Krolak 2 years ago committed by Kris Krolak
parent beb6b139eb
commit 262a6fdbd0
No known key found for this signature in database
GPG Key ID: 826FEC66DB190372

@ -20,7 +20,7 @@ tauri = { workspace = true }
serde_repr = "0.1" serde_repr = "0.1"
byte-unit = "4.0" byte-unit = "4.0"
log = { workspace = true, features = [ "kv_unstable" ] } log = { workspace = true, features = [ "kv_unstable" ] }
time = { version = "0.3", features = [ "formatting", "local-offset" ] } time = { version = "0.3", features = [ "formatting", "local-offset", "parsing" ] }
fern = "0.6" fern = "0.6"
[target."cfg(target_os = \"android\")".dependencies] [target."cfg(target_os = \"android\")".dependencies]

@ -73,6 +73,7 @@ const DEFAULT_LOG_TARGETS: [Target; 2] = [
Target::new(TargetKind::Stdout), Target::new(TargetKind::Stdout),
Target::new(TargetKind::LogDir { file_name: None }), Target::new(TargetKind::LogDir { file_name: None }),
]; ];
const LOG_DATE_FORMAT: &str = "[year]-[month]-[day]_[hour]-[minute]-[second]";
/// An enum representing the available verbosity levels of the logger. /// An enum representing the available verbosity levels of the logger.
/// ///
@ -127,8 +128,12 @@ impl From<log::Level> for LogLevel {
} }
pub enum RotationStrategy { pub enum RotationStrategy {
// Will keep all the logs, renaming them to include the date
KeepAll, KeepAll,
// Will only keep the most recent log up to its maximal size
KeepOne, KeepOne,
// Will keep some of the most recent logs, renaming them to include the date.
KeepSome(usize),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -493,31 +498,19 @@ impl Builder {
} }
} }
fn get_log_file_path(
fn rename_file_to_dated(
path: &impl AsRef<Path>,
dir: &impl AsRef<Path>, dir: &impl AsRef<Path>,
file_name: &str, file_name: &str,
rotation_strategy: &RotationStrategy,
timezone_strategy: &TimezoneStrategy, timezone_strategy: &TimezoneStrategy,
max_file_size: u128, ) -> Result<(), Box<dyn std::error::Error>> {
) -> Result<PathBuf, Box<dyn std::error::Error>> {
let path = dir.as_ref().join(format!("{file_name}.log"));
if path.exists() {
let log_size = File::open(&path)?.metadata()?.len() as u128;
if log_size > max_file_size {
match rotation_strategy {
RotationStrategy::KeepAll => {
let to = dir.as_ref().join(format!( let to = dir.as_ref().join(format!(
"{}_{}.log", "{}_{}.log",
file_name, file_name,
timezone_strategy timezone_strategy
.get_now() .get_now()
.format( .format(&time::format_description::parse(LOG_DATE_FORMAT).unwrap())
&time::format_description::parse(
"[year]-[month]-[day]_[hour]-[minute]-[second]"
)
.unwrap()
)
.unwrap(), .unwrap(),
)); ));
if to.is_file() { if to.is_file() {
@ -530,7 +523,53 @@ fn get_log_file_path(
)); ));
fs::rename(&to, to_bak)?; fs::rename(&to, to_bak)?;
} }
fs::rename(&path, to)?; fs::rename(path, to)?;
Ok(())
}
fn get_log_file_path(
dir: &impl AsRef<Path>,
file_name: &str,
rotation_strategy: &RotationStrategy,
timezone_strategy: &TimezoneStrategy,
max_file_size: u128,
) -> Result<PathBuf, Box<dyn std::error::Error>> {
let path = dir.as_ref().join(format!("{file_name}.log"));
if path.exists() {
let log_size = File::open(&path)?.metadata()?.len() as u128;
if log_size > max_file_size {
match rotation_strategy {
RotationStrategy::KeepAll => {
rename_file_to_dated(&path, dir, file_name, timezone_strategy)?;
}
RotationStrategy::KeepSome(how_many) => {
let mut files = fs::read_dir(dir)?
.filter_map(|entry| {
let entry = entry.ok()?;
let path = entry.path();
let old_file_name = path.file_name()?.to_string_lossy().into_owned();
if old_file_name.starts_with(&file_name) {
let date =
old_file_name.strip_prefix(&file_name)?.strip_prefix("_")?.strip_suffix(".log")?;
Some((path, date.to_string()))
} else {
None
}
})
.collect::<Vec<_>>();
// Regular sorting, so the oldest files are first. Lexicographical
// sorting is fine due to the date format.
files.sort_by(|a, b| a.1.cmp(&b.1));
// We want to make space for the file we will be soon renaming, AND
// the file we will be creating. Thus we need to keep how_many - 2 files.
if files.len() > (*how_many - 2) {
files.truncate(files.len() + 2 - *how_many);
for (old_log_path, _) in files {
fs::remove_file(old_log_path)?;
}
}
rename_file_to_dated(&path, dir, file_name, timezone_strategy)?;
} }
RotationStrategy::KeepOne => { RotationStrategy::KeepOne => {
fs::remove_file(&path)?; fs::remove_file(&path)?;
@ -538,6 +577,5 @@ fn get_log_file_path(
} }
} }
} }
Ok(path) Ok(path)
} }

Loading…
Cancel
Save