agentguard_telemetry/sinks/
stdout.rs1use crate::sink::{Sink, SinkError, SinkEvent};
4use async_trait::async_trait;
5use std::io::Write;
6use std::sync::Mutex;
7
8pub struct StdoutSink {
12 inner: Mutex<std::io::Stdout>,
13}
14
15impl StdoutSink {
16 pub fn new() -> Self {
17 Self {
18 inner: Mutex::new(std::io::stdout()),
19 }
20 }
21}
22
23impl Default for StdoutSink {
24 fn default() -> Self {
25 Self::new()
26 }
27}
28
29#[async_trait]
30impl Sink for StdoutSink {
31 fn name(&self) -> &str {
32 "stdout"
33 }
34
35 async fn emit(&self, event: &SinkEvent) -> Result<(), SinkError> {
36 let json = serde_json::to_string_pretty(event)?;
37 let mut guard = self.inner.lock().unwrap_or_else(|e| e.into_inner());
42 writeln!(guard, "{}", json)?;
43 guard.flush()?;
44 Ok(())
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[tokio::test]
53 async fn stdout_sink_serializes_event() {
54 let sink = StdoutSink::new();
55 let event = SinkEvent::decision("allow", "alice", "x", "y", vec![], vec![], 100);
56 sink.emit(&event).await.unwrap();
58 }
59}