gemini_adk_rs/plugin/
logging.rs

1//! Logging plugin — structured logging for agent/tool lifecycle.
2
3use async_trait::async_trait;
4
5use gemini_genai_rs::prelude::FunctionCall;
6
7use super::{Plugin, PluginResult};
8use crate::context::InvocationContext;
9use crate::events::Event;
10
11/// Plugin that 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 LoggingPlugin;
16
17impl LoggingPlugin {
18    /// Create a new logging plugin.
19    pub fn new() -> Self {
20        Self
21    }
22}
23
24impl Default for LoggingPlugin {
25    fn default() -> Self {
26        Self::new()
27    }
28}
29
30#[async_trait]
31impl Plugin for LoggingPlugin {
32    fn name(&self) -> &str {
33        "logging"
34    }
35
36    async fn before_agent(&self, _ctx: &InvocationContext) -> PluginResult {
37        tracing::info!("[plugin:logging] Agent starting");
38        PluginResult::Continue
39    }
40
41    async fn after_agent(&self, _ctx: &InvocationContext) -> PluginResult {
42        tracing::info!("[plugin:logging] Agent completed");
43        PluginResult::Continue
44    }
45
46    async fn before_tool(&self, call: &FunctionCall, _ctx: &InvocationContext) -> PluginResult {
47        tracing::info!(tool = %call.name, "[plugin:logging] Tool call starting");
48        tracing::debug!(tool = %call.name, args = %call.args, "[plugin:logging] Tool call args");
49        PluginResult::Continue
50    }
51
52    async fn after_tool(
53        &self,
54        call: &FunctionCall,
55        _result: &serde_json::Value,
56        _ctx: &InvocationContext,
57    ) -> PluginResult {
58        tracing::info!(tool = %call.name, "[plugin:logging] Tool call completed");
59        PluginResult::Continue
60    }
61
62    async fn on_event(&self, event: &Event, _ctx: &InvocationContext) -> PluginResult {
63        tracing::debug!(
64            event_id = %event.id,
65            author = %event.author,
66            "[plugin:logging] Event emitted"
67        );
68        PluginResult::Continue
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75
76    #[test]
77    fn logging_plugin_name() {
78        let p = LoggingPlugin::new();
79        assert_eq!(p.name(), "logging");
80    }
81
82    #[test]
83    fn logging_plugin_default() {
84        let p = LoggingPlugin;
85        assert_eq!(p.name(), "logging");
86    }
87}