Flush to audits to disk after not receiving a write for 5 seconds
Diff
flake.nix | 10 ----------
src/audit.rs | 37 +++++++++++++++++++++++++++++++------
2 files changed, 29 insertions(+), 18 deletions(-)
@@ -40,16 +40,6 @@
};
config = mkIf cfg.enable {
systemd.sockets.pisshoff = {
wantedBy = [ "sockets.target" ];
socketConfig = {
ListenStream = 22;
BindIPv6Only = "both";
Accept = "no";
};
};
systemd.services.pisshoff = {
enable = true;
wantedBy = [ "multi-user.target" ];
@@ -1,14 +1,18 @@
use crate::config::Config;
use serde::Serialize;
use std::io::ErrorKind;
use std::sync::Arc;
use std::{
fmt::{Debug, Formatter},
io::ErrorKind,
net::SocketAddr,
sync::Arc,
time::{Duration, Instant},
};
use tokio::io::{AsyncWriteExt, BufWriter};
use tokio::{fs::OpenOptions, task::JoinHandle};
use tokio::{
fs::OpenOptions,
io::{AsyncWriteExt, BufWriter},
task::JoinHandle,
};
use tracing::debug;
use uuid::Uuid;
pub fn start_audit_writer(
@@ -26,11 +30,28 @@
.open(&config.audit_output_file)
.await?;
let mut writer = BufWriter::new(file);
let mut shutdown = false;
while let Some(log) = recv.recv().await {
let log =
serde_json::to_vec(&log).map_err(|e| std::io::Error::new(ErrorKind::Other, e))?;
writer.write_all(&log).await?;
loop {
tokio::select! {
log = recv.recv(), if !shutdown => {
match log {
Some(log) => {
let log = serde_json::to_vec(&log)
.map_err(|e| std::io::Error::new(ErrorKind::Other, e))?;
writer.write_all(&log).await?;
}
None => {
shutdown = true;
}
}
}
_ = tokio::time::sleep(Duration::from_secs(5)), if !writer.buffer().is_empty() && !shutdown => {
debug!("Flushing audits to disk");
writer.flush().await?;
}
else => break,
}
}
writer.flush().await?;