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/// Uses `tracing` macros for structured logging; the events are no-ops
14/// until a subscriber is installed.
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        tracing::info!("Agent starting");
38        Ok(())
39    }
40
41    async fn after_agent(&self, _ctx: &InvocationContext) -> Result<(), AgentError> {
42        tracing::info!("Agent completed");
43        Ok(())
44    }
45
46    async fn before_tool(&self, call: &FunctionCall) -> Result<(), AgentError> {
47        tracing::info!(tool = %call.name, "Tool call starting");
48        tracing::debug!(tool = %call.name, args = %call.args, "Tool call args");
49        Ok(())
50    }
51
52    async fn after_tool(
53        &self,
54        call: &FunctionCall,
55        _result: &serde_json::Value,
56    ) -> Result<(), AgentError> {
57        tracing::info!(tool = %call.name, "Tool call completed");
58        Ok(())
59    }
60
61    async fn on_tool_error(&self, call: &FunctionCall, err: &ToolError) -> Result<(), AgentError> {
62        tracing::warn!(tool = %call.name, error = %err, "Tool call failed");
63        Ok(())
64    }
65
66    async fn on_error(&self, err: &AgentError) -> Result<(), AgentError> {
67        tracing::error!(error = %err, "Agent error");
68        Ok(())
69    }
70}