diff --git a/crates/xy-supervisor/src/logs.rs b/crates/xy-supervisor/src/logs.rs index f80276a..40427a0 100644 --- a/crates/xy-supervisor/src/logs.rs +++ b/crates/xy-supervisor/src/logs.rs @@ -69,6 +69,24 @@ impl RotatingLogWriter { } } +impl std::io::Write for RotatingLogWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.file.write_all(buf)?; + + self.written += buf.len() as u64; + + if self.written >= self.max_bytes { + self.rotate()?; + } + + Ok(buf.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + self.file.flush() + } +} + #[derive(Clone)] pub struct RingBuffer { inner: Arc>, @@ -260,4 +278,39 @@ mod tests { assert_eq!(got.stream, LogStream::Stdout); assert_eq!(sink.ring.snapshot_tail(None).len(), 1); } + + #[test] + fn write_trait_appends_bytes() { + use std::io::Write; + + let tmp = tempfile::tempdir().unwrap(); + let base = tmp.path().join("daemon.log"); + + let mut writer = RotatingLogWriter::open(&base, 1024, 3).unwrap(); + + writer.write_all(b"hello\n").unwrap(); + writer.flush().unwrap(); + + let contents = std::fs::read_to_string(&base).unwrap(); + assert_eq!(contents, "hello\n"); + } + + #[test] + fn write_trait_rotates_at_threshold() { + use std::io::Write; + + let tmp = tempfile::tempdir().unwrap(); + let base = tmp.path().join("daemon.log"); + + let mut writer = RotatingLogWriter::open(&base, 8, 3).unwrap(); + + writer.write_all(b"0123456789").unwrap(); + writer.write_all(b"after\n").unwrap(); + writer.flush().unwrap(); + + let rotated = tmp.path().join("daemon.log.1"); + assert!(rotated.exists()); + assert_eq!(std::fs::read_to_string(&rotated).unwrap(), "0123456789"); + assert_eq!(std::fs::read_to_string(&base).unwrap(), "after\n"); + } }