diff --git a/Cargo.toml b/Cargo.toml index 5150c0b..69db617 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,8 @@ clap = { version = "4.4.2", features = ["derive"] } xkbcommon = "0.6.0" xdg = "2.5.2" lazy_static = "1.4.0" +tracing-appender = "0.2.2" +walkdir = "2.4.0" [features] default = ["egl", "winit", "udev", "xwayland"] diff --git a/src/main.rs b/src/main.rs index f306c13..a80581f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,12 @@ // #![deny(unused_imports)] // gonna force myself to keep stuff clean #![warn(clippy::unwrap_used)] +use std::path::Path; + use clap::Parser; +use tracing_subscriber::{fmt::writer::MakeWriterExt, EnvFilter}; +use walkdir::WalkDir; +use xdg::BaseDirectories; mod api; mod backend; @@ -29,6 +34,11 @@ mod state; mod tag; mod window; +lazy_static::lazy_static! { + pub static ref XDG_BASE_DIRS: BaseDirectories = + BaseDirectories::with_prefix("pinnacle").expect("couldn't create xdg BaseDirectories"); +} + #[derive(clap::Args, Debug)] #[group(id = "backend", required = false, multiple = false)] struct Backends { @@ -53,18 +63,24 @@ struct Args { force: bool, } +const PINNACLE_LOG_PREFIX: &str = "pinnacle.log"; + fn main() -> anyhow::Result<()> { - match tracing_subscriber::EnvFilter::try_from_default_env() { - Ok(env_filter) => { - tracing_subscriber::fmt() - .compact() - .with_env_filter(env_filter) - .init(); - } - Err(_) => { - tracing_subscriber::fmt().compact().init(); - } - } + let xdg_state_dir = XDG_BASE_DIRS.get_state_home(); + + trim_logs(&xdg_state_dir); + + let appender = tracing_appender::rolling::hourly(xdg_state_dir, PINNACLE_LOG_PREFIX); + let (appender, _guard) = tracing_appender::non_blocking(appender); + let writer = appender.and(std::io::stdout); + + let env_filter = EnvFilter::try_from_default_env().unwrap_or(EnvFilter::new("debug")); + + tracing_subscriber::fmt() + .compact() + .with_env_filter(env_filter) + .with_writer(writer) + .init(); let args = Args::parse(); @@ -124,3 +140,38 @@ fn main() -> anyhow::Result<()> { Ok(()) } + +fn trim_logs(log_path: impl AsRef) { + let logs = WalkDir::new(log_path) + .sort_by(|a, b| { + let a_creation_time = a + .metadata() + .expect("failed to get log metadata") + .created() + .expect("failed to get log creation time"); + let b_creation_time = b + .metadata() + .expect("failed to get log metadata") + .created() + .expect("failed to get log creation time"); + + a_creation_time.cmp(&b_creation_time) + }) + .into_iter() + .filter_entry(|entry| { + entry.file_type().is_file() + && entry + .file_name() + .to_string_lossy() + .starts_with(PINNACLE_LOG_PREFIX) + }) + .filter_map(|dir| dir.ok()) + .collect::>(); + + // If there are more than 3 logs, delete the oldest ones + let num_to_delete = logs.len().saturating_sub(3); + + for entry in logs.into_iter().take(num_to_delete) { + std::fs::remove_file(entry.path()).expect("failed to remove oldest log file"); + } +} diff --git a/src/state.rs b/src/state.rs index 645366e..a219b35 100644 --- a/src/state.rs +++ b/src/state.rs @@ -65,15 +65,9 @@ use smithay::{ }, xwayland::{X11Surface, X11Wm, XWayland, XWaylandEvent}, }; -use xdg::BaseDirectories; use crate::input::InputState; -lazy_static::lazy_static! { - static ref XDG_BASE_DIRS: BaseDirectories = - BaseDirectories::with_prefix("pinnacle").expect("couldn't create xdg BaseDirectories"); -} - pub enum Backend { Winit(Winit), Udev(Udev), @@ -412,7 +406,7 @@ fn get_config_dir() -> PathBuf { .ok() .and_then(|s| Some(PathBuf::from(shellexpand::full(&s).ok()?.to_string()))); - config_dir.unwrap_or(XDG_BASE_DIRS.get_config_home()) + config_dir.unwrap_or(crate::XDG_BASE_DIRS.get_config_home()) } /// This should be called *after* you have created the [`PinnacleSocketSource`] to ensure @@ -460,6 +454,8 @@ fn start_config(metaconfig: Metaconfig, config_dir: &Path) -> anyhow::Result