use crate::telemetry::events::TelemetryEvent;
pub trait TelemetrySink: Send + Sync {
fn track(&mut self, event: TelemetryEvent);
fn flush(&mut self) {}
}
pub struct ConsoleSink {
app_name: String,
}
impl ConsoleSink {
pub fn new(app_name: impl Into<String>) -> Self {
Self {
app_name: app_name.into(),
}
}
}
impl TelemetrySink for ConsoleSink {
fn track(&mut self, event: TelemetryEvent) {
let json = serde_json::to_string(&event).unwrap_or_default();
tracing::info!(app = %self.app_name, event = %json, "telemetry");
}
}
pub struct NoopSink;
impl TelemetrySink for NoopSink {
fn track(&mut self, _event: TelemetryEvent) {}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::telemetry::events::FailureClass;
#[test]
fn console_sink_does_not_panic() {
use crate::telemetry::events::ToolName;
let mut sink = ConsoleSink::new("test");
sink.track(TelemetryEvent::ToolInvoked {
tool: ToolName::Search,
});
sink.track(TelemetryEvent::Error {
class: FailureClass::Network,
});
sink.flush();
}
#[test]
fn noop_sink_discards() {
use crate::telemetry::events::ToolName;
let mut sink = NoopSink;
sink.track(TelemetryEvent::ToolInvoked {
tool: ToolName::Search,
});
sink.flush();
}
}