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"
byte-unit = "4.0"
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"
[target."cfg(target_os = \"android\")".dependencies]

@ -73,6 +73,7 @@ const DEFAULT_LOG_TARGETS: [Target; 2] = [
Target::new(TargetKind::Stdout),
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.
///
@ -127,8 +128,12 @@ impl From<log::Level> for LogLevel {
}
pub enum RotationStrategy {
// Will keep all the logs, renaming them to include the date
KeepAll,
// Will only keep the most recent log up to its maximal size
KeepOne,
// Will keep some of the most recent logs, renaming them to include the date.
KeepSome(usize),
}
#[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>,
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 => {
) -> Result<(), Box<dyn std::error::Error>> {
let to = dir.as_ref().join(format!(
"{}_{}.log",
file_name,
timezone_strategy
.get_now()
.format(
&time::format_description::parse(
"[year]-[month]-[day]_[hour]-[minute]-[second]"
)
.unwrap()
)
.format(&time::format_description::parse(LOG_DATE_FORMAT).unwrap())
.unwrap(),
));
if to.is_file() {
@ -530,7 +523,53 @@ fn get_log_file_path(
));
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 => {
fs::remove_file(&path)?;
@ -538,6 +577,5 @@ fn get_log_file_path(
}
}
}
Ok(path)
}

Loading…
Cancel
Save