55 lines
1.5 KiB
Rust
55 lines
1.5 KiB
Rust
use anyhow::Result;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::fs::{create_dir_all, OpenOptions};
|
|
use std::io::Write;
|
|
use std::path::PathBuf;
|
|
|
|
/// JSONL event record.
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct EventRecord {
|
|
pub project: String,
|
|
pub query: String,
|
|
pub run: String,
|
|
pub turn: u32,
|
|
pub event_type: String,
|
|
pub data: serde_json::Value,
|
|
}
|
|
|
|
/// Event log writer.
|
|
pub struct LogWriter {
|
|
path: PathBuf,
|
|
}
|
|
|
|
impl LogWriter {
|
|
/// Open or create log file.
|
|
pub fn new(project: &str, query: &str, run: &str) -> Result<Self> {
|
|
let dir = PathBuf::from(format!("log/{}/{}", project, query));
|
|
create_dir_all(&dir)?;
|
|
Ok(Self {
|
|
path: dir.join(format!("{}.jsonl", run)),
|
|
})
|
|
}
|
|
|
|
/// Append event to log.
|
|
pub fn log(&mut self, record: EventRecord) -> Result<()> {
|
|
let mut file = OpenOptions::new()
|
|
.create(true)
|
|
.append(true)
|
|
.open(&self.path)?;
|
|
|
|
serde_json::to_writer(&mut file, &record)?;
|
|
file.write_all(b"\n")?;
|
|
Ok(())
|
|
}
|
|
|
|
/// Read all events from log.
|
|
pub fn read_all(&self) -> Result<Vec<EventRecord>> {
|
|
let contents = std::fs::read_to_string(&self.path)?;
|
|
contents
|
|
.lines()
|
|
.filter(|line| !line.is_empty())
|
|
.map(|line| serde_json::from_str(line).map_err(|e| anyhow::anyhow!("Parse error: {}", e)))
|
|
.collect()
|
|
}
|
|
}
|