Merge pull request #4255 from Byron/log-retention

better logs
This commit is contained in:
Kiril Videlov 2024-07-09 13:28:40 +02:00 committed by GitHub
commit 164ca5ed85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 133 additions and 31 deletions

54
Cargo.lock generated
View File

@ -137,9 +137,9 @@ dependencies = [
[[package]]
name = "anstyle-wincon"
version = "3.0.3"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
@ -390,7 +390,7 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps 6.2.2",
"system-deps 6.2.0",
]
[[package]]
@ -740,7 +740,7 @@ checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8"
dependencies = [
"glib-sys",
"libc",
"system-deps 6.2.2",
"system-deps 6.2.0",
]
[[package]]
@ -1926,7 +1926,7 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps 6.2.2",
"system-deps 6.2.0",
]
[[package]]
@ -1943,7 +1943,7 @@ dependencies = [
"libc",
"pango-sys",
"pkg-config",
"system-deps 6.2.2",
"system-deps 6.2.0",
]
[[package]]
@ -1957,7 +1957,7 @@ dependencies = [
"gobject-sys",
"libc",
"pkg-config",
"system-deps 6.2.2",
"system-deps 6.2.0",
]
[[package]]
@ -1969,7 +1969,7 @@ dependencies = [
"gdk-sys",
"glib-sys",
"libc",
"system-deps 6.2.2",
"system-deps 6.2.0",
"x11",
]
@ -2061,7 +2061,7 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps 6.2.2",
"system-deps 6.2.0",
"winapi",
]
@ -3253,7 +3253,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4"
dependencies = [
"libc",
"system-deps 6.2.2",
"system-deps 6.2.0",
]
[[package]]
@ -3283,7 +3283,7 @@ checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a"
dependencies = [
"glib-sys",
"libc",
"system-deps 6.2.2",
"system-deps 6.2.0",
]
[[package]]
@ -3335,7 +3335,7 @@ dependencies = [
"gobject-sys",
"libc",
"pango-sys",
"system-deps 6.2.2",
"system-deps 6.2.0",
]
[[package]]
@ -4843,7 +4843,7 @@ dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps 6.2.2",
"system-deps 6.2.0",
]
[[package]]
@ -6667,15 +6667,15 @@ dependencies = [
[[package]]
name = "system-deps"
version = "6.2.2"
version = "6.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
checksum = "2a2d580ff6a20c55dfb86be5f9c238f67835d0e81cbdea8bf5680e0897320331"
dependencies = [
"cfg-expr 0.15.8",
"heck 0.5.0",
"heck 0.4.1",
"pkg-config",
"toml 0.8.14",
"version-compare 0.2.0",
"version-compare 0.1.1",
]
[[package]]
@ -7585,9 +7585,9 @@ checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b"
[[package]]
name = "version-compare"
version = "0.2.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
[[package]]
name = "version_check"
@ -7794,7 +7794,7 @@ dependencies = [
"pango-sys",
"pkg-config",
"soup2-sys",
"system-deps 6.2.2",
"system-deps 6.2.0",
]
[[package]]
@ -7999,9 +7999,9 @@ checksum = "9ee5e275231f07c6e240d14f34e1b635bf1faa1c76c57cfd59a5cdb9848e4278"
[[package]]
name = "windows-result"
version = "0.1.2"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
checksum = "749f0da9cc72d82e600d8d2e44cadd0b9eedb9038f71a1c58556ac1c5791813b"
dependencies = [
"windows-targets 0.52.5",
]
@ -8102,9 +8102,9 @@ checksum = "f838de2fe15fe6bac988e74b798f26499a8b21a9d97edec321e79b28d1d7f597"
[[package]]
name = "windows-version"
version = "0.1.1"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6998aa457c9ba8ff2fb9f13e9d2a930dabcea28f1d0ab94d687d8b3654844515"
checksum = "75aa004c988e080ad34aff5739c39d0312f4684699d6d71fc8a198d057b8b9b4"
dependencies = [
"windows-targets 0.52.5",
]
@ -8420,12 +8420,12 @@ dependencies = [
[[package]]
name = "xdg-home"
version = "1.2.0"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8"
checksum = "21e5a325c3cb8398ad6cf859c1135b25dd29e186679cf2da7581d9679f63b38e"
dependencies = [
"libc",
"windows-sys 0.52.0",
"winapi",
]
[[package]]

View File

@ -1,7 +1,7 @@
use std::path::Path;
use std::{fs, net::Ipv4Addr, time::Duration};
use tauri::{AppHandle, Manager};
use tracing::{metadata::LevelFilter, subscriber::set_global_default};
use tracing::{instrument, metadata::LevelFilter, subscriber::set_global_default};
use tracing_appender::rolling::{RollingFileAppender, Rotation};
use tracing_subscriber::{fmt::format::FmtSpan, layer::SubscriberExt, Layer};
@ -12,13 +12,22 @@ pub fn init(app_handle: &AppHandle) {
.expect("failed to get logs dir");
fs::create_dir_all(&logs_dir).expect("failed to create logs dir");
let log_prefix = "GitButler";
let log_suffix = "log";
let max_log_files = 14;
remove_old_logs(&logs_dir).ok();
let file_appender = RollingFileAppender::builder()
.rotation(Rotation::DAILY)
.max_log_files(14)
.filename_prefix("GitButler.log")
.max_log_files(max_log_files)
.filename_prefix(log_prefix)
.filename_suffix(log_suffix)
.build(&logs_dir)
.expect("initializing rolling file appender failed");
let (file_writer, guard) = tracing_appender::non_blocking(file_appender);
// As the file-writer only checks `max_log_files` on file rotation, it bascially never happens.
// Run it now.
prune_old_logs(&logs_dir, Some(log_prefix), Some(log_suffix), max_log_files).ok();
app_handle.manage(guard); // keep the guard alive for the lifetime of the app
let format_for_humans = tracing_subscriber::fmt::format()
@ -81,3 +90,96 @@ fn get_server_addr(app_handle: &AppHandle) -> (Ipv4Addr, u16) {
};
(Ipv4Addr::LOCALHOST, port)
}
/// Originally based on https://github.com/tokio-rs/tracing/blob/44861cad7a821f08b3c13aba14bb8ddf562b7053/tracing-appender/src/rolling.rs#L571
#[instrument(err(Debug))]
fn prune_old_logs(
log_directory: &Path,
log_filename_prefix: Option<&str>,
log_filename_suffix: Option<&str>,
max_files: usize,
) -> anyhow::Result<()> {
let mut files: Vec<_> = {
let dir = fs::read_dir(log_directory)?;
dir.filter_map(|entry| {
let entry = entry.ok()?;
let metadata = entry.metadata().ok()?;
// the appender only creates files, not directories or symlinks,
// so we should never delete a dir or symlink.
if !metadata.is_file() {
return None;
}
let filename = entry.file_name();
let filename = filename.to_str()?;
if let Some(prefix) = log_filename_prefix {
if !filename.starts_with(prefix) {
return None;
}
}
if let Some(suffix) = log_filename_suffix {
if !filename.ends_with(suffix) {
return None;
}
}
let created = metadata.created().ok()?;
Some((entry, created))
})
.collect()
};
if files.len() < max_files {
return Ok(());
}
// sort the files by their creation timestamps.
files.sort_by_key(|(_, created_at)| *created_at);
// delete files, so that (n-1) files remain, because we will create another log file
for (file, _) in files.iter().take(files.len() - (max_files - 1)) {
if let Err(err) = fs::remove_file(file.path()) {
tracing::warn!(
"Failed to remove extra log file {}: {}",
file.path().display(),
err,
);
}
}
Ok(())
}
#[instrument(err(Debug))]
fn remove_old_logs(log_directory: &Path) -> anyhow::Result<()> {
let dir = fs::read_dir(log_directory)?;
let old_log_files = dir.filter_map(|entry| {
let entry = entry.ok()?;
let metadata = entry.metadata().ok()?;
if !metadata.is_file() {
return None;
}
let filename = entry.file_name();
let filename = filename.to_str()?;
if !filename.starts_with("GitButler.log") {
return None;
}
Some(entry.path())
});
for file_path in old_log_files {
if let Err(err) = fs::remove_file(&file_path) {
tracing::warn!(
"Failed to remove old log file {}: {}",
file_path.display(),
err,
);
}
}
Ok(())
}