kumo_server_common/
log.rs

1use std::fs::File;
2use std::path::PathBuf;
3use std::time::Instant;
4use zstd::stream::write::Encoder;
5
6/// Represents an opened log file
7pub struct OpenedFile {
8    pub file: Encoder<'static, File>,
9    pub name: PathBuf,
10    pub written: u64,
11    pub expires: Option<Instant>,
12}
13
14impl Drop for OpenedFile {
15    fn drop(&mut self) {
16        self.file.do_finish().ok();
17        mark_path_as_done(&self.name).ok();
18        tracing::debug!("Flushed {:?}", self.name);
19    }
20}
21
22pub fn mark_path_as_done(path: &PathBuf) -> std::io::Result<()> {
23    let meta = path.metadata()?;
24    // Remove the `w` bit to signal to the tailer that this
25    // file will not be written to any more and that it is
26    // now considered to be complete
27    let mut perms = meta.permissions();
28    perms.set_readonly(true);
29    std::fs::set_permissions(path, perms)
30}
31
32pub fn mark_existing_logs_as_done_in_dir(dir: &PathBuf) -> anyhow::Result<()> {
33    match std::fs::read_dir(dir) {
34        Ok(d) => {
35            for entry in d {
36                if let Ok(entry) = entry {
37                    match entry.file_name().to_str() {
38                        Some(name) if name.starts_with('.') => {
39                            continue;
40                        }
41                        None => continue,
42                        Some(_name) => {
43                            if let Ok(file_type) = entry.file_type() {
44                                if file_type.is_file() {
45                                    mark_path_as_done(&entry.path()).ok();
46                                }
47                            }
48                        }
49                    }
50                }
51            }
52            Ok(())
53        }
54        Err(err) => {
55            if err.kind() == std::io::ErrorKind::NotFound {
56                // If there's no dir, there's nothing to mark done!
57                Ok(())
58            } else {
59                anyhow::bail!(
60                    "failed to mark existing logs as done in {}: {err:#}",
61                    dir.display()
62                );
63            }
64        }
65    }
66}