split log
This commit is contained in:
parent
f04c12d78c
commit
203e0835e3
13
crates/prometeu-core/src/log/log_event.rs
Normal file
13
crates/prometeu-core/src/log/log_event.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
use crate::log::LogLevel;
|
||||||
|
use crate::log::LogSource;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct LogEvent {
|
||||||
|
pub seq: u64,
|
||||||
|
pub ts_ms: u64,
|
||||||
|
pub frame: u64,
|
||||||
|
pub level: LogLevel,
|
||||||
|
pub source: LogSource,
|
||||||
|
pub tag: u16,
|
||||||
|
pub msg: String,
|
||||||
|
}
|
||||||
8
crates/prometeu-core/src/log/log_level.rs
Normal file
8
crates/prometeu-core/src/log/log_level.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum LogLevel {
|
||||||
|
Trace,
|
||||||
|
Debug,
|
||||||
|
Info,
|
||||||
|
Warn,
|
||||||
|
Error,
|
||||||
|
}
|
||||||
93
crates/prometeu-core/src/log/log_service.rs
Normal file
93
crates/prometeu-core/src/log/log_service.rs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
use std::collections::VecDeque;
|
||||||
|
use crate::log::{LogEvent, LogLevel, LogSource};
|
||||||
|
|
||||||
|
pub struct LogService {
|
||||||
|
events: VecDeque<LogEvent>,
|
||||||
|
capacity: usize,
|
||||||
|
next_seq: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LogService {
|
||||||
|
pub fn new(capacity: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
events: VecDeque::with_capacity(capacity),
|
||||||
|
capacity,
|
||||||
|
next_seq: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log(&mut self, ts_ms: u64, frame: u64, level: LogLevel, source: LogSource, tag: u16, msg: String) {
|
||||||
|
if self.events.len() >= self.capacity {
|
||||||
|
self.events.pop_front();
|
||||||
|
}
|
||||||
|
self.events.push_back(LogEvent {
|
||||||
|
seq: self.next_seq,
|
||||||
|
ts_ms,
|
||||||
|
frame,
|
||||||
|
level,
|
||||||
|
source,
|
||||||
|
tag,
|
||||||
|
msg,
|
||||||
|
});
|
||||||
|
self.next_seq += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_recent(&self, n: usize) -> Vec<LogEvent> {
|
||||||
|
self.events.iter().rev().take(n).cloned().collect::<Vec<_>>().into_iter().rev().collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_after(&self, seq: u64) -> Vec<LogEvent> {
|
||||||
|
self.events.iter().filter(|e| e.seq > seq).cloned().collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn last_seq(&self) -> Option<u64> {
|
||||||
|
self.events.back().map(|e| e.seq)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ring_buffer_capacity() {
|
||||||
|
let mut service = LogService::new(3);
|
||||||
|
service.log(100, 1, LogLevel::Info, LogSource::Pos, 0, "Log 1".to_string());
|
||||||
|
service.log(110, 1, LogLevel::Info, LogSource::Pos, 0, "Log 2".to_string());
|
||||||
|
service.log(120, 1, LogLevel::Info, LogSource::Pos, 0, "Log 3".to_string());
|
||||||
|
|
||||||
|
assert_eq!(service.events.len(), 3);
|
||||||
|
assert_eq!(service.events[0].msg, "Log 1");
|
||||||
|
|
||||||
|
service.log(130, 1, LogLevel::Info, LogSource::Pos, 0, "Log 4".to_string());
|
||||||
|
assert_eq!(service.events.len(), 3);
|
||||||
|
assert_eq!(service.events[0].msg, "Log 2");
|
||||||
|
assert_eq!(service.events[2].msg, "Log 4");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_recent() {
|
||||||
|
let mut service = LogService::new(10);
|
||||||
|
for i in 0..5 {
|
||||||
|
service.log(i as u64, 1, LogLevel::Info, LogSource::Pos, 0, format!("Log {}", i));
|
||||||
|
}
|
||||||
|
|
||||||
|
let recent = service.get_recent(2);
|
||||||
|
assert_eq!(recent.len(), 2);
|
||||||
|
assert_eq!(recent[0].msg, "Log 3");
|
||||||
|
assert_eq!(recent[1].msg, "Log 4");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_after() {
|
||||||
|
let mut service = LogService::new(10);
|
||||||
|
for i in 0..5 {
|
||||||
|
service.log(i as u64, 1, LogLevel::Info, LogSource::Pos, 0, format!("Log {}", i));
|
||||||
|
}
|
||||||
|
|
||||||
|
let after = service.get_after(2); // seqs são 0, 1, 2, 3, 4. Deve retornar 3 e 4.
|
||||||
|
assert_eq!(after.len(), 2);
|
||||||
|
assert_eq!(after[0].msg, "Log 3");
|
||||||
|
assert_eq!(after[1].msg, "Log 4");
|
||||||
|
}
|
||||||
|
}
|
||||||
8
crates/prometeu-core/src/log/log_source.rs
Normal file
8
crates/prometeu-core/src/log/log_source.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum LogSource {
|
||||||
|
Pos,
|
||||||
|
Hub,
|
||||||
|
Vm,
|
||||||
|
Fs,
|
||||||
|
App { app_id: u32 },
|
||||||
|
}
|
||||||
@ -1,121 +1,9 @@
|
|||||||
use std::collections::VecDeque;
|
mod log_level;
|
||||||
|
mod log_source;
|
||||||
|
mod log_event;
|
||||||
|
mod log_service;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
pub use log_level::LogLevel;
|
||||||
pub enum LogLevel {
|
pub use log_source::LogSource;
|
||||||
Trace,
|
pub use log_event::LogEvent;
|
||||||
Debug,
|
pub use log_service::LogService;
|
||||||
Info,
|
|
||||||
Warn,
|
|
||||||
Error,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
pub enum LogSource {
|
|
||||||
Pos,
|
|
||||||
Hub,
|
|
||||||
Vm,
|
|
||||||
Fs,
|
|
||||||
App { app_id: u32 },
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct LogEvent {
|
|
||||||
pub seq: u64,
|
|
||||||
pub ts_ms: u64,
|
|
||||||
pub frame: u64,
|
|
||||||
pub level: LogLevel,
|
|
||||||
pub source: LogSource,
|
|
||||||
pub tag: u16,
|
|
||||||
pub msg: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct LogService {
|
|
||||||
events: VecDeque<LogEvent>,
|
|
||||||
capacity: usize,
|
|
||||||
next_seq: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LogService {
|
|
||||||
pub fn new(capacity: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
events: VecDeque::with_capacity(capacity),
|
|
||||||
capacity,
|
|
||||||
next_seq: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn log(&mut self, ts_ms: u64, frame: u64, level: LogLevel, source: LogSource, tag: u16, msg: String) {
|
|
||||||
if self.events.len() >= self.capacity {
|
|
||||||
self.events.pop_front();
|
|
||||||
}
|
|
||||||
self.events.push_back(LogEvent {
|
|
||||||
seq: self.next_seq,
|
|
||||||
ts_ms,
|
|
||||||
frame,
|
|
||||||
level,
|
|
||||||
source,
|
|
||||||
tag,
|
|
||||||
msg,
|
|
||||||
});
|
|
||||||
self.next_seq += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_recent(&self, n: usize) -> Vec<LogEvent> {
|
|
||||||
self.events.iter().rev().take(n).cloned().collect::<Vec<_>>().into_iter().rev().collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_after(&self, seq: u64) -> Vec<LogEvent> {
|
|
||||||
self.events.iter().filter(|e| e.seq > seq).cloned().collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn last_seq(&self) -> Option<u64> {
|
|
||||||
self.events.back().map(|e| e.seq)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_ring_buffer_capacity() {
|
|
||||||
let mut service = LogService::new(3);
|
|
||||||
service.log(100, 1, LogLevel::Info, LogSource::Pos, 0, "Log 1".to_string());
|
|
||||||
service.log(110, 1, LogLevel::Info, LogSource::Pos, 0, "Log 2".to_string());
|
|
||||||
service.log(120, 1, LogLevel::Info, LogSource::Pos, 0, "Log 3".to_string());
|
|
||||||
|
|
||||||
assert_eq!(service.events.len(), 3);
|
|
||||||
assert_eq!(service.events[0].msg, "Log 1");
|
|
||||||
|
|
||||||
service.log(130, 1, LogLevel::Info, LogSource::Pos, 0, "Log 4".to_string());
|
|
||||||
assert_eq!(service.events.len(), 3);
|
|
||||||
assert_eq!(service.events[0].msg, "Log 2");
|
|
||||||
assert_eq!(service.events[2].msg, "Log 4");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_get_recent() {
|
|
||||||
let mut service = LogService::new(10);
|
|
||||||
for i in 0..5 {
|
|
||||||
service.log(i as u64, 1, LogLevel::Info, LogSource::Pos, 0, format!("Log {}", i));
|
|
||||||
}
|
|
||||||
|
|
||||||
let recent = service.get_recent(2);
|
|
||||||
assert_eq!(recent.len(), 2);
|
|
||||||
assert_eq!(recent[0].msg, "Log 3");
|
|
||||||
assert_eq!(recent[1].msg, "Log 4");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_get_after() {
|
|
||||||
let mut service = LogService::new(10);
|
|
||||||
for i in 0..5 {
|
|
||||||
service.log(i as u64, 1, LogLevel::Info, LogSource::Pos, 0, format!("Log {}", i));
|
|
||||||
}
|
|
||||||
|
|
||||||
let after = service.get_after(2); // seqs são 0, 1, 2, 3, 4. Deve retornar 3 e 4.
|
|
||||||
assert_eq!(after.len(), 2);
|
|
||||||
assert_eq!(after[0].msg, "Log 3");
|
|
||||||
assert_eq!(after[1].msg, "Log 4");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user