Nothing to see here, move along
at main 91 lines 2.5 kB view raw
1use core::fmt::{self, Write}; 2 3use crate::sync::SyncUnsafe; 4 5const BUF_SIZE: usize = 65536; 6 7pub struct FlightRecorder { 8 buf: [u8; BUF_SIZE], 9 cursor: usize, 10 total_written: usize, 11} 12 13impl FlightRecorder { 14 const fn new() -> Self { 15 Self { 16 buf: [0u8; BUF_SIZE], 17 cursor: 0, 18 total_written: 0, 19 } 20 } 21 22 pub fn append( 23 &mut self, 24 tsc: u64, 25 severity: lancer_log::Severity, 26 domain: &str, 27 message: fmt::Arguments<'_>, 28 ) { 29 let letter = match severity { 30 lancer_log::Severity::Error => 'E', 31 lancer_log::Severity::Warn => 'W', 32 lancer_log::Severity::Info => 'I', 33 lancer_log::Severity::Debug => 'D', 34 }; 35 let _ = writeln!(self, "{:012} {} {:6} {}", tsc, letter, domain, message); 36 } 37 38 fn write_byte(&mut self, byte: u8) { 39 self.buf[self.cursor] = byte; 40 self.cursor = (self.cursor + 1) % BUF_SIZE; 41 self.total_written += 1; 42 } 43 44 #[allow(dead_code)] 45 pub fn total_written(&self) -> usize { 46 self.total_written 47 } 48 49 pub fn read(&self, cursor: usize, dst: &mut [u8]) -> (usize, usize) { 50 let oldest_valid = self.total_written.saturating_sub(BUF_SIZE); 51 let start = match cursor < oldest_valid { 52 true => self.fast_forward(oldest_valid), 53 false => cursor, 54 }; 55 56 let available = self.total_written.saturating_sub(start); 57 let copy_len = available.min(dst.len()); 58 59 (0..copy_len).fold((), |(), i| { 60 let ring_idx = (start + i) % BUF_SIZE; 61 dst[i] = self.buf[ring_idx]; 62 }); 63 64 (start + copy_len, copy_len) 65 } 66 67 fn fast_forward(&self, oldest_valid: usize) -> usize { 68 let search_len = self.total_written.saturating_sub(oldest_valid).min(BUF_SIZE); 69 (0..search_len) 70 .find(|&i| { 71 let ring_idx = (oldest_valid + i) % BUF_SIZE; 72 self.buf[ring_idx] == b'\n' 73 }) 74 .map(|i| oldest_valid + i + 1) 75 .unwrap_or(self.total_written) 76 } 77} 78 79impl Write for FlightRecorder { 80 fn write_str(&mut self, s: &str) -> fmt::Result { 81 s.as_bytes().iter().for_each(|&b| self.write_byte(b)); 82 Ok(()) 83 } 84} 85 86static FLIGHT: SyncUnsafe<FlightRecorder> = SyncUnsafe::new(FlightRecorder::new()); 87 88#[allow(clippy::deref_addrof)] 89pub fn recorder() -> &'static mut FlightRecorder { 90 unsafe { &mut *FLIGHT.get() } 91}