gemini_adk_rs/middleware/
log.rs

1//! Logging middleware for agent and tool lifecycle events.
2
3use async_trait::async_trait;
4
5use gemini_genai_rs::prelude::FunctionCall;
6
7use super::Middleware;
8use crate::context::InvocationContext;
9use crate::error::{AgentError, ToolError};
10
11/// Logs agent and tool lifecycle events.
12///
13/// When the `tracing-support` feature is enabled, uses `tracing` macros for
14/// structured logging. Without the feature, all hooks are silent no-ops.
15pub struct LogMiddleware;
16
17impl LogMiddleware {
18    /// Create a new log middleware.
19    pub fn new() -> Self {
20        Self
21    }
22}
23
24impl Default for LogMiddleware {
25    fn default() -> Self {
26        Self::new()
27    }
28}
29
30#[async_trait]
31impl Middleware for LogMiddleware {
32    fn name(&self) -> &str {
33        "log"
34    }
35
36    async fn before_agent(&self, _ctx: &InvocationContext) -> Result<(), AgentError> {
37        #[cfg(feature = "tracing-support")]
38        tracing::info!("Agent starting");
39        Ok(())
40    }
41
42    async fn after_agent(&self, _ctx: &InvocationContext) -> Result<(), AgentError> {
43        #[cfg(feature = "tracing-support")]
44        tracing::info!("Agent completed");
45        Ok(())
46    }
47
48    async fn before_tool(&self, call: &FunctionCall) -> Result<(), AgentError> {
49        let _ = call; // used only when tracing-support is enabled
50        #[cfg(feature = "tracing-support")]
51        {
52            tracing::info!(tool = %call.name, "Tool call starting");
53            tracing::debug!(tool = %call.name, args = %call.args, "Tool call args");
54        }
55        Ok(())
56    }
57
58    async fn after_tool(
59        &self,
60        call: &FunctionCall,
61        _result: &serde_json::Value,
62    ) -> Result<(), AgentError> {
63        let _ = call;
64        #[cfg(feature = "tracing-support")]
65        tracing::info!(tool = %call.name, "Tool call completed");
66        Ok(())
67    }
68
69    async fn on_tool_error(&self, call: &FunctionCall, err: &ToolError) -> Result<(), AgentError> {
70        let _ = (call, err);
71        #[cfg(feature = "tracing-support")]
72        tracing::warn!(tool = %call.name, error = %err, "Tool call failed");
73        Ok(())
74    }
75
76    async fn on_error(&self, err: &AgentError) -> Result<(), AgentError> {
77        let _ = err;
78        #[cfg(feature = "tracing-support")]
79        tracing::error!(error = %err, "Agent error");
80        Ok(())
81    }
82}