ai_agent/services/api/
logging.rs1use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
8#[serde(rename_all = "lowercase")]
9pub enum ApiLogLevel {
10 Debug,
11 Info,
12 Warn,
13 Error,
14}
15
16impl Default for ApiLogLevel {
17 fn default() -> Self {
18 ApiLogLevel::Info
19 }
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct ApiLogEntry {
25 pub timestamp: String,
26 pub level: ApiLogLevel,
27 pub message: String,
28 pub details: Option<serde_json::Value>,
29}
30
31impl ApiLogEntry {
32 pub fn new(level: ApiLogLevel, message: impl Into<String>) -> Self {
33 Self {
34 timestamp: chrono::Utc::now().to_rfc3339(),
35 level,
36 message: message.into(),
37 details: None,
38 }
39 }
40
41 pub fn with_details(mut self, details: serde_json::Value) -> Self {
42 self.details = Some(details);
43 self
44 }
45
46 pub fn debug(message: impl Into<String>) -> Self {
47 Self::new(ApiLogLevel::Debug, message)
48 }
49
50 pub fn info(message: impl Into<String>) -> Self {
51 Self::new(ApiLogLevel::Info, message)
52 }
53
54 pub fn warn(message: impl Into<String>) -> Self {
55 Self::new(ApiLogLevel::Warn, message)
56 }
57
58 pub fn error(message: impl Into<String>) -> Self {
59 Self::new(ApiLogLevel::Error, message)
60 }
61}
62
63pub struct ApiLogger {
65 enabled: bool,
66 min_level: ApiLogLevel,
67}
68
69impl ApiLogger {
70 pub fn new() -> Self {
71 Self {
72 enabled: true,
73 min_level: ApiLogLevel::Info,
74 }
75 }
76
77 pub fn set_enabled(&mut self, enabled: bool) {
78 self.enabled = enabled;
79 }
80
81 pub fn set_min_level(&mut self, level: ApiLogLevel) {
82 self.min_level = level;
83 }
84
85 pub fn log(&self, entry: &ApiLogEntry) {
86 if !self.enabled {
87 return;
88 }
89
90 let level_priority = match entry.level {
91 ApiLogLevel::Debug => 0,
92 ApiLogLevel::Info => 1,
93 ApiLogLevel::Warn => 2,
94 ApiLogLevel::Error => 3,
95 };
96
97 let min_priority = match self.min_level {
98 ApiLogLevel::Debug => 0,
99 ApiLogLevel::Info => 1,
100 ApiLogLevel::Warn => 2,
101 ApiLogLevel::Error => 3,
102 };
103
104 if level_priority >= min_priority {
105 eprintln!("[API] {:?}: {}", entry.level, entry.message);
107 }
108 }
109}
110
111impl Default for ApiLogger {
112 fn default() -> Self {
113 Self::new()
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn test_api_log_entry_creation() {
123 let entry = ApiLogEntry::info("test message");
124 assert_eq!(entry.level, ApiLogLevel::Info);
125 assert_eq!(entry.message, "test message");
126 assert!(entry.details.is_none());
127 }
128
129 #[test]
130 fn test_api_log_entry_with_details() {
131 let entry = ApiLogEntry::info("test").with_details(serde_json::json!({"key": "value"}));
132 assert!(entry.details.is_some());
133 }
134}