Skip to main content

shared_framework/monitoring/
mod.rs

1//! Log monitoring events and sinks.
2//!
3//! [`MonitoringEvent`] is the structured record emitted for a log entry and
4//! [`ILogMonitor`] is the async sink that receives and flushes those events.
5//!
6//! ```ignore
7//! let event = MonitoringEvent {
8//!     event_id: "evt-1".to_string(),
9//!     timestamp: chrono::Utc::now(),
10//!     duration_ms: None,
11//!     level: LogLevel::Info,
12//!     message: "started".to_string(),
13//!     data: None,
14//!     correlation_id: ctx.correlation_id(),
15//! };
16//! monitor.log(event).await?;
17//! ```
18
19use chrono::{DateTime, Utc};
20use serde::{Deserialize, Serialize};
21
22/// Severity of a [`MonitoringEvent`].
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub enum LogLevel {
25    /// Command execution.
26    Exec,
27    /// Failures.
28    Error,
29    /// Noteworthy normal events.
30    Info,
31    /// Diagnostic detail.
32    Debug,
33    /// Potential problems.
34    Warn,
35    /// Timed-operation records.
36    Time,
37}
38
39/// Structured log record sent to an [`ILogMonitor`].
40#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct MonitoringEvent {
42    /// Unique ID of this event.
43    pub event_id: String,
44    /// When the event occurred.
45    pub timestamp: DateTime<Utc>,
46    /// Operation duration, when the event measures timed work.
47    pub duration_ms: Option<u64>,
48    /// Severity of the event.
49    pub level: LogLevel,
50    /// Human-readable message.
51    pub message: String,
52    /// Optional structured payload.
53    pub data: Option<serde_json::Value>,
54    /// Correlation ID of the request that produced the event.
55    pub correlation_id: String,
56}
57
58/// Async sink for [`MonitoringEvent`] records.
59#[async_trait::async_trait]
60pub trait ILogMonitor: Send + Sync {
61    /// Receives one monitoring event. Returns an error if the event cannot be recorded.
62    async fn log(&self, event: MonitoringEvent) -> anyhow::Result<()>;
63    /// Flushes any buffered events. Returns an error if the flush fails.
64    async fn flush(&self) -> anyhow::Result<()>;
65}