micromegas_analytics/
response_writer.rs

1use anyhow::{Context, Result};
2use async_trait::async_trait;
3use bytes::Bytes;
4use micromegas_telemetry::wire_format::encode_cbor;
5use micromegas_tracing::prelude::*;
6use tokio::sync::mpsc::Sender;
7
8/// A trait for writing log entries.
9#[async_trait]
10pub trait Logger: Send + Sync {
11    async fn write_log_entry(&self, msg: String) -> Result<()>;
12}
13
14/// A writer for sending responses to a client.
15pub struct ResponseWriter {
16    sender: Option<Sender<Bytes>>,
17}
18
19impl ResponseWriter {
20    pub fn new(sender: Option<Sender<Bytes>>) -> Self {
21        Self { sender }
22    }
23    pub async fn write_string(&self, value: String) -> Result<()> {
24        info!("{value}");
25        let buffer = encode_cbor(&value)?;
26        if let Some(sender) = &self.sender {
27            sender
28                .send(buffer.into())
29                .await
30                .with_context(|| "writing response")?;
31        }
32        Ok(())
33    }
34
35    pub fn is_closed(&self) -> bool {
36        if let Some(sender) = &self.sender {
37            sender.is_closed()
38        } else {
39            false
40        }
41    }
42}
43
44#[async_trait]
45impl Logger for ResponseWriter {
46    async fn write_log_entry(&self, msg: String) -> Result<()> {
47        self.write_string(msg).await
48    }
49}
50
51/// A sender for sending log entries to a channel.
52pub struct LogSender {
53    sender: Sender<(chrono::DateTime<chrono::Utc>, String)>,
54}
55
56impl LogSender {
57    pub fn new(sender: Sender<(chrono::DateTime<chrono::Utc>, String)>) -> Self {
58        Self { sender }
59    }
60}
61
62#[async_trait]
63impl Logger for LogSender {
64    async fn write_log_entry(&self, msg: String) -> Result<()> {
65        info!("{msg}");
66        self.sender
67            .send((chrono::Utc::now(), msg))
68            .await
69            .with_context(|| "LogSender::write_log_entry")
70    }
71}
72
73/// Tracing logger
74pub struct TracingLogger {}
75
76#[async_trait]
77impl Logger for TracingLogger {
78    async fn write_log_entry(&self, msg: String) -> Result<()> {
79        info!("{msg}");
80        Ok(())
81    }
82}