From 54b9694f0d0d7e853592317d60ad262ae8c13568 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 23 Feb 2022 21:08:56 +0100 Subject: implement matchlogger --- planetwars-matchrunner/src/match_log.rs | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 planetwars-matchrunner/src/match_log.rs (limited to 'planetwars-matchrunner/src/match_log.rs') diff --git a/planetwars-matchrunner/src/match_log.rs b/planetwars-matchrunner/src/match_log.rs new file mode 100644 index 0000000..9991f99 --- /dev/null +++ b/planetwars-matchrunner/src/match_log.rs @@ -0,0 +1,45 @@ +use std::path::Path; + +use serde::{Deserialize, Serialize}; +use tokio::{fs::File, io::AsyncWriteExt}; + +use planetwars_rules::protocol::State; +use tokio::sync::mpsc; + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum MatchLogMessage { + #[serde(rename = "gamestate")] + GameState(State), + #[serde(rename = "stderr")] + StdErr(StdErrMessage), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct StdErrMessage { + pub player_id: u32, + pub message: String, +} + +pub type MatchLogger = mpsc::UnboundedSender; + +pub async fn create_log_sink(log_file_path: &Path) -> MatchLogger { + let (tx, rx) = mpsc::unbounded_channel(); + let log_file = File::create(log_file_path) + .await + .expect("Could not create log file"); + tokio::spawn(run_log_sink(rx, log_file)); + return tx; +} + +async fn run_log_sink(mut rx: mpsc::UnboundedReceiver, mut file: File) { + while let Some(message) = rx.recv().await { + let json = serde_json::to_string(&message).expect("failed to serialize message"); + file.write_all(json.as_bytes()) + .await + .expect("failed to write log message to file"); + file.write_all(b"\n") + .await + .expect("failed to write newline log message to file"); + } +} -- cgit v1.2.3