minion_engine/events/
subscribers.rs1use std::io::Write as _;
2
3use super::{Event, EventSubscriber};
4
5pub struct WebhookSubscriber {
10 url: String,
11}
12
13impl WebhookSubscriber {
14 pub fn new(url: impl Into<String>) -> Self {
15 Self { url: url.into() }
16 }
17}
18
19impl EventSubscriber for WebhookSubscriber {
20 fn on_event(&self, event: &Event) {
21 let url = self.url.clone();
22 let body = match serde_json::to_string(event) {
23 Ok(s) => s,
24 Err(e) => {
25 tracing::warn!(error = %e, "WebhookSubscriber: failed to serialize event");
26 return;
27 }
28 };
29
30 tokio::spawn(async move {
32 let client = reqwest::Client::new();
33 if let Err(e) = client
34 .post(&url)
35 .header("Content-Type", "application/json")
36 .body(body)
37 .send()
38 .await
39 {
40 tracing::warn!(url = %url, error = %e, "WebhookSubscriber: HTTP POST failed");
41 }
42 });
43 }
44}
45
46pub struct FileSubscriber {
52 path: String,
53}
54
55impl FileSubscriber {
56 pub fn new(path: impl Into<String>) -> Self {
57 Self { path: path.into() }
58 }
59}
60
61impl EventSubscriber for FileSubscriber {
62 fn on_event(&self, event: &Event) {
63 let line = match serde_json::to_string(event) {
64 Ok(s) => s,
65 Err(e) => {
66 tracing::warn!(error = %e, "FileSubscriber: failed to serialize event");
67 return;
68 }
69 };
70
71 match std::fs::OpenOptions::new()
72 .create(true)
73 .append(true)
74 .open(&self.path)
75 {
76 Ok(mut file) => {
77 if let Err(e) = writeln!(file, "{}", line) {
78 tracing::warn!(path = %self.path, error = %e, "FileSubscriber: write failed");
79 }
80 }
81 Err(e) => {
82 tracing::warn!(path = %self.path, error = %e, "FileSubscriber: open failed");
83 }
84 }
85 }
86}