bss_oss_utils/
observability.rs

1//! Observability helpers for monitoring and tracing
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use uuid::Uuid;
6
7/// Request trace information
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct TraceContext {
10    pub trace_id: Uuid,
11    pub span_id: Uuid,
12    pub parent_span_id: Option<Uuid>,
13    pub timestamp: DateTime<Utc>,
14}
15
16impl TraceContext {
17    /// Create a new trace context
18    pub fn new() -> Self {
19        Self {
20            trace_id: Uuid::new_v4(),
21            span_id: Uuid::new_v4(),
22            parent_span_id: None,
23            timestamp: Utc::now(),
24        }
25    }
26
27    /// Create a child span
28    pub fn child_span(&self) -> Self {
29        Self {
30            trace_id: self.trace_id,
31            span_id: Uuid::new_v4(),
32            parent_span_id: Some(self.span_id),
33            timestamp: Utc::now(),
34        }
35    }
36}
37
38impl Default for TraceContext {
39    fn default() -> Self {
40        Self::new()
41    }
42}
43
44/// Metrics for API operations
45#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct ApiMetrics {
47    pub endpoint: String,
48    pub method: String,
49    pub status_code: u16,
50    pub duration_ms: u64,
51    pub timestamp: DateTime<Utc>,
52}
53
54/// Health check response
55#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct HealthCheck {
57    pub status: HealthStatus,
58    pub version: String,
59    pub timestamp: DateTime<Utc>,
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub checks: Option<Vec<ComponentCheck>>,
62}
63
64/// Health status
65#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
66#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
67pub enum HealthStatus {
68    Healthy,
69    Degraded,
70    Unhealthy,
71}
72
73/// Component health check
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct ComponentCheck {
76    pub name: String,
77    pub status: HealthStatus,
78    #[serde(skip_serializing_if = "Option::is_none")]
79    pub message: Option<String>,
80}
81
82impl HealthCheck {
83    /// Create a healthy health check
84    pub fn healthy(version: String) -> Self {
85        Self {
86            status: HealthStatus::Healthy,
87            version,
88            timestamp: Utc::now(),
89            checks: None,
90        }
91    }
92}