From dac04f08cd69a850152c40e5887aa4c21b58d73f Mon Sep 17 00:00:00 2001 From: Madhu Mohan Jaishankar Date: Mon, 10 Aug 2026 18:48:35 +0100 Subject: [PATCH 1/7] feat: CPEX prompt hooks for prompts/get Signed-off-by: Madhu Mohan Jaishankar --- .../contextforge-gateway-rs-cpex/src/cmf.rs | 100 +++++++++- .../src/handle.rs | 51 ++++- .../contextforge-gateway-rs-cpex/src/hooks.rs | 28 ++- .../contextforge-gateway-rs-cpex/src/lib.rs | 5 +- .../src/pipeline.rs | 47 ++++- .../src/runtime.rs | 167 +++++++++++++--- .../src/gateway/mcp_service/prompts.rs | 13 +- .../tests/gateway_plugins.rs | 115 ++++++++++- .../tests/support/mod.rs | 5 +- .../tests/support/plugin.rs | 178 ++++++++++++++++++ .../tests/support/plugin_gateway.rs | 31 ++- .../tests/support/runtime.rs | 20 +- 12 files changed, 710 insertions(+), 50 deletions(-) diff --git a/crates/contextforge-gateway-rs-cpex/src/cmf.rs b/crates/contextforge-gateway-rs-cpex/src/cmf.rs index b4de6f6e..0791db3e 100644 --- a/crates/contextforge-gateway-rs-cpex/src/cmf.rs +++ b/crates/contextforge-gateway-rs-cpex/src/cmf.rs @@ -1,5 +1,7 @@ -use cpex::cpex_core::cmf::{ContentPart, Message, MessagePayload, Role, ToolCall, ToolResult}; -use rmcp::model::{CallToolRequestParams, CallToolResult, ContentBlock}; +use cpex::cpex_core::cmf::{ + ContentPart, Message, MessagePayload, PromptRequest, PromptResult, Role, ToolCall, ToolResult, +}; +use rmcp::model::{CallToolRequestParams, CallToolResult, ContentBlock, GetPromptRequestParams, GetPromptResult}; use serde_json::{Map, Value}; pub(crate) fn tool_call_payload( @@ -110,10 +112,104 @@ fn raw_error_tool_result(value: Value) -> CallToolResult { } } +pub(crate) fn prompt_request_payload( + request: &GetPromptRequestParams, + prompt_name: &str, + backend_name: &str, + prompt_request_id: &str, +) -> MessagePayload { + MessagePayload { + message: Message { + schema_version: "2.0".to_owned(), + role: Role::User, + content: vec![ContentPart::PromptRequest { + content: PromptRequest { + prompt_request_id: prompt_request_id.to_owned(), + name: prompt_name.to_owned(), + arguments: request.arguments.clone().unwrap_or_default().into_iter().collect(), + server_id: Some(backend_name.to_owned()), + }, + }], + channel: None, + }, + } +} + +pub(crate) fn prompt_request_arguments(payload: &MessagePayload) -> Option> { + payload + .message + .get_prompt_requests() + .first() + .map(|request| request.arguments.clone().into_iter().collect::>()) +} + +pub(crate) fn prompt_result_payload( + response: &GetPromptResult, + prompt_name: &str, + prompt_request_id: &str, +) -> MessagePayload { + let mut content = vec![ContentPart::PromptResult { + content: PromptResult { + prompt_request_id: prompt_request_id.to_owned(), + prompt_name: prompt_name.to_owned(), + messages: Vec::new(), + content: None, + is_error: false, + error_message: None, + }, + }]; + content.extend( + response + .messages + .iter() + .filter_map(|message| message.content.as_text()) + .map(|text| ContentPart::Text { text: text.text.clone() }), + ); + + MessagePayload { + message: Message { schema_version: "2.0".to_owned(), role: Role::Assistant, content, channel: None }, + } +} + +pub(crate) fn prompt_result_response( + mut original: GetPromptResult, + payload: &MessagePayload, +) -> Option { + let mut texts = payload.message.content.iter().filter_map(|part| match part { + ContentPart::Text { text } => Some(text), + _ => None, + }); + + for message in &mut original.messages { + if message.content.as_text().is_none() { + continue; + } + message.content = ContentBlock::text(texts.next()?.clone()); + } + + if texts.next().is_some() { + return None; + } + Some(original) +} + #[cfg(test)] mod tests { + use rmcp::model::{PromptMessage, Role as McpRole}; + use super::*; + /// The write-back refuses extra text as well as missing text: a plugin that appends a part + /// leaves it with nowhere to go, and guessing would silently drop the plugin's edit. + #[test] + fn prompt_result_response_rejects_added_text() { + let original = GetPromptResult::new(vec![PromptMessage::new_text(McpRole::User, "review of weather")]); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + payload.message.content.push(ContentPart::Text { text: "extra".to_owned() }); + + assert!(prompt_result_response(original, &payload).is_none()); + } + #[test] fn tool_result_response_uses_cmf_error_flag_for_nested_mcp_result() { let original = CallToolResult::success(vec![ContentBlock::text("original")]); diff --git a/crates/contextforge-gateway-rs-cpex/src/handle.rs b/crates/contextforge-gateway-rs-cpex/src/handle.rs index b63d6313..8ed27a6f 100644 --- a/crates/contextforge-gateway-rs-cpex/src/handle.rs +++ b/crates/contextforge-gateway-rs-cpex/src/handle.rs @@ -13,7 +13,7 @@ use cpex::cpex_core::{ }; use rmcp::{ ErrorData, - model::{CallToolRequestParams, CallToolResult, ErrorCode}, + model::{CallToolRequestParams, CallToolResult, ErrorCode, GetPromptRequestParams, GetPromptResult}, serde::{Serialize, de::DeserializeOwned}, }; use tokio::task::JoinHandle; @@ -21,7 +21,7 @@ use tokio::task::JoinHandle; use crate::{ config::{LoadedRuntimePluginConfig, RedisRuntimePluginConfigStore, RuntimePluginConfigStore, cpex_config}, error::GatewayPluginRuntimeError, - hooks::{RuntimeHookError, RuntimeHookState, ToolPreCallResult}, + hooks::{PromptPreFetchResult, RuntimeHookError, RuntimeHookState, ToolPreCallResult}, runtime::GatewayPluginRuntime, }; @@ -40,7 +40,7 @@ pub struct GatewayPluginRuntimeHandle { runtime: Arc>, } -struct RegistryToolCallState { +struct RegistryCallState { runtime: Arc, state: Option, } @@ -253,20 +253,52 @@ impl GatewayPluginRuntimeHandle { let mut result = runtime.before_tool_call(request, tool_name, backend_name).await?; if runtime.has_post_hook() { let state = result.state.take(); - result.state = Some(Arc::new(RegistryToolCallState { runtime: Arc::clone(runtime), state })); + result.state = Some(Arc::new(RegistryCallState { runtime: Arc::clone(runtime), state })); } else { result.state = None; } Ok(result) } + pub async fn before_get_prompt( + &self, + request: &GetPromptRequestParams, + prompt_name: &str, + backend_name: &str, + ) -> Result { + let state = self.current(); + let RuntimeState::Active(runtime) = state.as_ref() else { + return Err(runtime_failed_error(state.as_ref())); + }; + let mut result = runtime.before_get_prompt(request, prompt_name, backend_name).await?; + if runtime.has_prompt_post_hook() { + let state = result.state.take(); + result.state = Some(Arc::new(RegistryCallState { runtime: Arc::clone(runtime), state })); + } else { + result.state = None; + } + Ok(result) + } + + pub async fn after_get_prompt( + &self, + prompt_name: &str, + response: GetPromptResult, + state: Option, + ) -> Result { + match state.and_then(|state| state.downcast::().ok()) { + Some(state) => state.runtime.after_get_prompt(prompt_name, response, state.state.clone()).await, + None => Ok(response), + } + } + pub async fn after_tool_call( &self, tool_name: &str, response: CallToolResult, state: Option, ) -> Result { - match state.and_then(|state| state.downcast::().ok()) { + match state.and_then(|state| state.downcast::().ok()) { Some(state) => state.runtime.after_tool_call(tool_name, response, state.state.clone()).await, None => Ok(response), } @@ -283,7 +315,7 @@ impl GatewayPluginRuntimeHandle { where T: Serialize + DeserializeOwned, { - match state.and_then(|state| state.downcast::().ok()) { + match state.and_then(|state| state.downcast::().ok()) { Some(state) => state.runtime.after_tool_event(tool_name, event, state.state.clone()).await, None => Ok(Some(event)), } @@ -714,6 +746,13 @@ mod tests { } } + #[tokio::test(flavor = "multi_thread", worker_threads = 1)] + async fn prompt_hooks_are_accepted_config() { + let plugin = Arc::new(TestPlugin::new("prompt", vec![cmf_hook_names::PROMPT_PRE_FETCH])); + // runtime_with_plugin initializes and expects success + runtime_with_plugin(&plugin, plugin_config(&[Arc::clone(&plugin)])).await; + } + #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn runtime_config_loads_registered_factory_plugin() { let plugin = diff --git a/crates/contextforge-gateway-rs-cpex/src/hooks.rs b/crates/contextforge-gateway-rs-cpex/src/hooks.rs index 0e6ce655..b6a9a63a 100644 --- a/crates/contextforge-gateway-rs-cpex/src/hooks.rs +++ b/crates/contextforge-gateway-rs-cpex/src/hooks.rs @@ -1,6 +1,6 @@ use std::{any::Any, sync::Arc}; -use rmcp::model::CallToolRequestParams; +use rmcp::model::{CallToolRequestParams, GetPromptRequestParams}; use serde_json::{Map, Value}; pub type RuntimeHookError = Box; @@ -31,3 +31,29 @@ impl ToolPreCallResult { Self { arguments: ToolArgumentsUpdate::Unchanged, state: None } } } + +#[derive(Debug)] +pub enum PromptArgumentsUpdate { + Unchanged, + Replace(Option>), +} + +impl PromptArgumentsUpdate { + pub fn apply_to_request(self, request: &mut GetPromptRequestParams, routed_prompt_name: &str) { + routed_prompt_name.clone_into(&mut request.name); + if let Self::Replace(arguments) = self { + request.arguments = arguments; + } + } +} + +pub struct PromptPreFetchResult { + pub arguments: PromptArgumentsUpdate, + pub state: Option, +} + +impl PromptPreFetchResult { + pub fn unchanged() -> Self { + Self { arguments: PromptArgumentsUpdate::Unchanged, state: None } + } +} diff --git a/crates/contextforge-gateway-rs-cpex/src/lib.rs b/crates/contextforge-gateway-rs-cpex/src/lib.rs index 6a57cb51..5d1be674 100644 --- a/crates/contextforge-gateway-rs-cpex/src/lib.rs +++ b/crates/contextforge-gateway-rs-cpex/src/lib.rs @@ -10,4 +10,7 @@ mod runtime; pub use error::GatewayPluginRuntimeError; pub use factory::CmfPluginFactory; pub use handle::{CpexRuntimeRegistry, GatewayPluginRuntimeHandle}; -pub use hooks::{RuntimeHookError, RuntimeHookState, ToolArgumentsUpdate, ToolPreCallResult}; +pub use hooks::{ + PromptArgumentsUpdate, PromptPreFetchResult, RuntimeHookError, RuntimeHookState, ToolArgumentsUpdate, + ToolPreCallResult, +}; diff --git a/crates/contextforge-gateway-rs-cpex/src/pipeline.rs b/crates/contextforge-gateway-rs-cpex/src/pipeline.rs index 5d6cdd97..34569001 100644 --- a/crates/contextforge-gateway-rs-cpex/src/pipeline.rs +++ b/crates/contextforge-gateway-rs-cpex/src/pipeline.rs @@ -2,14 +2,17 @@ use cpex::cpex_core::cmf::MessagePayload; use cpex::cpex_core::executor::PipelineResult; use rmcp::{ ErrorData, - model::{CallToolResult, ErrorCode}, + model::{CallToolResult, ErrorCode, GetPromptResult}, serde::de::DeserializeOwned, }; use tracing::warn; use crate::{ - ToolArgumentsUpdate, - cmf::{tool_call_arguments, tool_result_content, tool_result_response}, + PromptArgumentsUpdate, ToolArgumentsUpdate, + cmf::{ + prompt_request_arguments, prompt_result_response, tool_call_arguments, tool_result_content, + tool_result_response, + }, }; pub(crate) fn modified_message_payload(result: &PipelineResult) -> Option<&MessagePayload> { @@ -39,6 +42,29 @@ pub(crate) fn effective_pre_args( } } +pub(crate) fn effective_pre_prompt_args( + original_args: Option<&serde_json::Map>, + pre_result: &PipelineResult, +) -> Result { + let Some(modified_payload) = modified_message_payload(pre_result) else { + return Ok(PromptArgumentsUpdate::Unchanged); + }; + + let Some(arguments) = prompt_request_arguments(modified_payload) else { + return Err(ErrorData { + code: ErrorCode::INVALID_PARAMS, + message: "Plugin modified prompt payload without a prompt request".into(), + data: None, + }); + }; + + if original_args == Some(&arguments) || (original_args.is_none() && arguments.is_empty()) { + Ok(PromptArgumentsUpdate::Unchanged) + } else { + Ok(PromptArgumentsUpdate::Replace(Some(arguments))) + } +} + pub(crate) fn effective_post_result(original: CallToolResult, result: &PipelineResult) -> CallToolResult { match modified_message_payload(result) { Some(payload) => tool_result_response(original, payload), @@ -46,6 +72,21 @@ pub(crate) fn effective_post_result(original: CallToolResult, result: &PipelineR } } +pub(crate) fn effective_post_prompt_result( + original: GetPromptResult, + result: &PipelineResult, +) -> Result { + let Some(payload) = modified_message_payload(result) else { + return Ok(original); + }; + + prompt_result_response(original, payload).ok_or_else(|| ErrorData { + code: ErrorCode::INTERNAL_ERROR, + message: "Plugin changed the prompt message count".into(), + data: None, + }) +} + pub(crate) fn effective_post_json(original: T, result: &PipelineResult) -> Result where T: DeserializeOwned, diff --git a/crates/contextforge-gateway-rs-cpex/src/runtime.rs b/crates/contextforge-gateway-rs-cpex/src/runtime.rs index 21dc39c5..1da1c11d 100644 --- a/crates/contextforge-gateway-rs-cpex/src/runtime.rs +++ b/crates/contextforge-gateway-rs-cpex/src/runtime.rs @@ -14,25 +14,39 @@ use cpex::cpex_core::{ }; use rmcp::{ ErrorData, - model::{CallToolRequestParams, CallToolResult}, + model::{CallToolRequestParams, CallToolResult, GetPromptRequestParams, GetPromptResult}, serde::{Serialize, de::DeserializeOwned}, }; use tokio::sync::Mutex; use crate::{ - cmf::{tool_call_payload, tool_json_result_payload, tool_result_payload}, + cmf::{ + prompt_request_payload, prompt_result_payload, tool_call_payload, tool_json_result_payload, tool_result_payload, + }, error::GatewayPluginRuntimeError, - hooks::{RuntimeHookState, ToolArgumentsUpdate, ToolPreCallResult}, + hooks::{PromptPreFetchResult, RuntimeHookState, ToolArgumentsUpdate, ToolPreCallResult}, pipeline::{ - effective_post_json, effective_post_result, effective_pre_args, log_pipeline_errors, plugin_denied_error, + effective_post_json, effective_post_prompt_result, effective_post_result, effective_pre_args, + effective_pre_prompt_args, log_pipeline_errors, plugin_denied_error, }, }; +#[derive(Default)] +struct HookPair { + pre: bool, + post: bool, +} + +#[derive(Default)] +struct HookPresence { + tool: HookPair, + prompt: HookPair, +} + #[derive(Default)] pub(crate) struct GatewayPluginRuntime { manager: PluginManager, - has_pre_hook: bool, - has_post_hook: bool, + hooks: HookPresence, } struct ToolCallState { @@ -42,10 +56,10 @@ struct ToolCallState { type SharedToolCallState = Mutex; -static TOOL_CALL_ID: AtomicU64 = AtomicU64::new(1); +static CORRELATION_ID: AtomicU64 = AtomicU64::new(1); fn next_tool_call_id() -> String { - format!("gateway-tool-call-{}", TOOL_CALL_ID.fetch_add(1, Ordering::Relaxed)) + format!("gateway-tool-call-{}", CORRELATION_ID.fetch_add(1, Ordering::Relaxed)) } fn new_tool_call_state() -> RuntimeHookState { @@ -55,9 +69,26 @@ fn new_tool_call_state() -> RuntimeHookState { })) } +fn next_prompt_request_id() -> String { + format!("gateway-prompt-request-{}", CORRELATION_ID.fetch_add(1, Ordering::Relaxed)) +} + +struct PromptCallState { + context_table: PluginContextTable, + prompt_request_id: String, +} + +fn new_prompt_call_state(context_table: PluginContextTable, prompt_request_id: String) -> RuntimeHookState { + Arc::new(PromptCallState { context_table, prompt_request_id }) +} + impl GatewayPluginRuntime { pub(crate) fn has_post_hook(&self) -> bool { - self.has_post_hook + self.hooks.tool.post + } + + pub(crate) fn has_prompt_post_hook(&self) -> bool { + self.hooks.prompt.post } pub(crate) async fn from_config( @@ -66,16 +97,20 @@ impl GatewayPluginRuntime { ) -> Result { validate_gateway_supported_config(&config)?; - let has_pre_hook = - config.plugins.iter().any(|plugin| plugin.hooks.iter().any(|hook| hook == cmf_hook_names::TOOL_PRE_INVOKE)); - let has_post_hook = config - .plugins - .iter() - .any(|plugin| plugin.hooks.iter().any(|hook| hook == cmf_hook_names::TOOL_POST_INVOKE)); + let hooks = HookPresence { + tool: HookPair { + pre: declares(&config, cmf_hook_names::TOOL_PRE_INVOKE), + post: declares(&config, cmf_hook_names::TOOL_POST_INVOKE), + }, + prompt: HookPair { + pre: declares(&config, cmf_hook_names::PROMPT_PRE_FETCH), + post: declares(&config, cmf_hook_names::PROMPT_POST_FETCH), + }, + }; let manager = PluginManager::from_config(config, factories) .map_err(|source| GatewayPluginRuntimeError::Configuration { hook: "config", source })?; manager.initialize().await.map_err(|source| GatewayPluginRuntimeError::Initialization { source })?; - Ok(Self { manager, has_pre_hook, has_post_hook }) + Ok(Self { manager, hooks }) } } @@ -93,6 +128,17 @@ impl Drop for GatewayPluginRuntime { } } +const SUPPORTED_HOOKS: [&str; 4] = [ + cmf_hook_names::TOOL_PRE_INVOKE, + cmf_hook_names::TOOL_POST_INVOKE, + cmf_hook_names::PROMPT_PRE_FETCH, + cmf_hook_names::PROMPT_POST_FETCH, +]; + +fn declares(config: &CpexConfig, hook_name: &str) -> bool { + config.plugins.iter().any(|plugin| plugin.hooks.iter().any(|hook| hook == hook_name)) +} + fn validate_gateway_supported_config(config: &CpexConfig) -> Result<(), GatewayPluginRuntimeError> { if config.routing_enabled() || config.plugin_settings.fail_on_plugin_error @@ -109,11 +155,7 @@ fn validate_gateway_supported_config(config: &CpexConfig) -> Result<(), GatewayP return Err(GatewayPluginRuntimeError::ConfigUnsupported); } - if plugin - .hooks - .iter() - .any(|hook| hook != cmf_hook_names::TOOL_PRE_INVOKE && hook != cmf_hook_names::TOOL_POST_INVOKE) - { + if plugin.hooks.iter().any(|hook| !SUPPORTED_HOOKS.contains(&hook.as_str())) { return Err(GatewayPluginRuntimeError::ConfigUnsupported); } } @@ -152,8 +194,8 @@ impl GatewayPluginRuntime { tool_name: &str, backend_name: &str, ) -> Result { - if !self.has_pre_hook { - let state = self.has_post_hook.then(new_tool_call_state); + if !self.hooks.tool.pre { + let state = self.hooks.tool.post.then(new_tool_call_state); return Ok(ToolPreCallResult { arguments: ToolArgumentsUpdate::Unchanged, state }); } @@ -169,13 +211,88 @@ impl GatewayPluginRuntime { Ok(ToolPreCallResult { arguments, state: Some(Arc::new(state)) }) } + async fn invoke_prompt_pre(&self, payload: MessagePayload) -> PipelineResult { + let (result, background_tasks) = self + .manager + .invoke_named::(cmf_hook_names::PROMPT_PRE_FETCH, payload, Extensions::default(), None) + .await; + log_pipeline_errors(cmf_hook_names::PROMPT_PRE_FETCH, &result); + drop(background_tasks); + result + } + + async fn invoke_prompt_post( + &self, + payload: MessagePayload, + context_table: Option, + ) -> PipelineResult { + let (result, background_tasks) = self + .manager + .invoke_named::(cmf_hook_names::PROMPT_POST_FETCH, payload, Extensions::default(), context_table) + .await; + log_pipeline_errors(cmf_hook_names::PROMPT_POST_FETCH, &result); + drop(background_tasks); + result + } + + pub(crate) async fn before_get_prompt( + &self, + request: &GetPromptRequestParams, + prompt_name: &str, + backend_name: &str, + ) -> Result { + if !self.hooks.prompt.pre { + let mut result = PromptPreFetchResult::unchanged(); + result.state = self + .hooks + .prompt + .post + .then(|| new_prompt_call_state(PluginContextTable::default(), next_prompt_request_id())); + return Ok(result); + } + + let prompt_request_id = next_prompt_request_id(); + let payload = prompt_request_payload(request, prompt_name, backend_name, &prompt_request_id); + let pre_result = self.invoke_prompt_pre(payload).await; + if pre_result.is_denied() { + return Err(plugin_denied_error(pre_result)); + } + + let arguments = effective_pre_prompt_args(request.arguments.as_ref(), &pre_result)?; + let state = + self.hooks.prompt.post.then(|| new_prompt_call_state(pre_result.context_table.clone(), prompt_request_id)); + Ok(PromptPreFetchResult { arguments, state }) + } + + pub(crate) async fn after_get_prompt( + &self, + prompt_name: &str, + response: GetPromptResult, + state: Option, + ) -> Result { + if !self.hooks.prompt.post { + return Ok(response); + } + + let state = state.and_then(|state| state.downcast::().ok()); + let Some(state) = state else { return Ok(response) }; + + let payload = prompt_result_payload(&response, prompt_name, &state.prompt_request_id); + let post_result = self.invoke_prompt_post(payload, Some(state.context_table.clone())).await; + if post_result.is_denied() { + return Err(plugin_denied_error(post_result)); + } + + effective_post_prompt_result(response, &post_result) + } + pub(crate) async fn after_tool_call( &self, tool_name: &str, response: CallToolResult, state: Option, ) -> Result { - if !self.has_post_hook { + if !self.hooks.tool.post { return Ok(response); } @@ -206,7 +323,7 @@ impl GatewayPluginRuntime { where T: Serialize + DeserializeOwned, { - if !self.has_post_hook { + if !self.hooks.tool.post { return Ok(Some(event)); } diff --git a/crates/contextforge-gateway-rs-lib/src/gateway/mcp_service/prompts.rs b/crates/contextforge-gateway-rs-lib/src/gateway/mcp_service/prompts.rs index 14c0654d..be160009 100644 --- a/crates/contextforge-gateway-rs-lib/src/gateway/mcp_service/prompts.rs +++ b/crates/contextforge-gateway-rs-lib/src/gateway/mcp_service/prompts.rs @@ -1,3 +1,4 @@ +use contextforge_gateway_rs_cpex::PromptPreFetchResult; use rmcp::{ ErrorData, RoleServer, model::{GetPromptRequestParams, GetPromptResponse, ListPromptsResult, PaginatedRequestParams}, @@ -84,12 +85,22 @@ where ) .await?; + let pre_result = if let Some(plugin_runtime) = &mcp_service.plugin_runtime { + plugin_runtime.before_get_prompt(&request, &prompt_name, &service_name).await? + } else { + PromptPreFetchResult::unchanged() + }; let mut routed_request = request; - routed_request.name = prompt_name; + pre_result.arguments.apply_to_request(&mut routed_request, &prompt_name); let response = service .get_prompt(routed_request) .await .map_err(|error| backend_forward_error("get_prompt", &service_name, &error))?; info!("get_prompt: backend {service_name} returned {} messages", response.messages.len()); + let response = if let Some(plugin_runtime) = &mcp_service.plugin_runtime { + plugin_runtime.after_get_prompt(&prompt_name, response, pre_result.state).await? + } else { + response + }; Ok(response.into()) } diff --git a/crates/contextforge-gateway-rs-lib/tests/gateway_plugins.rs b/crates/contextforge-gateway-rs-lib/tests/gateway_plugins.rs index 82739372..99c637b1 100644 --- a/crates/contextforge-gateway-rs-lib/tests/gateway_plugins.rs +++ b/crates/contextforge-gateway-rs-lib/tests/gateway_plugins.rs @@ -9,16 +9,18 @@ use cpex::cpex_core::hooks::types::cmf_hook_names; use rmcp::{ ClientHandler, model::{ - CallToolRequestParams, CallToolResult, ClientCapabilities, ClientRequest, ErrorCode, Implementation, - InitializeRequestParams, ProgressNotificationParam, Request, ServerResult, + CallToolRequestParams, CallToolResult, ClientCapabilities, ClientRequest, ContentBlock, ErrorCode, + GetPromptRequestParams, GetPromptResult, Implementation, InitializeRequestParams, ProgressNotificationParam, + Request, ServerResult, }, service::{NotificationContext, PeerRequestOptions, RequestHandle, RoleClient, RunningService}, }; use serde_json::{Map, Value, json}; use support::{ - POST_DENY_ERROR_CODE, PRE_DENY_ERROR_CODE, REWRITTEN_SUM_A, REWRITTEN_SUM_B, RunningGateway, TEST_USER_ID, - TestPlugin, error_code, runtime_with_post, runtime_with_pre, runtime_with_pre_and_post, start_gateway, + POST_DENY_ERROR_CODE, PRE_DENY_ERROR_CODE, PromptBehavior, PromptTestPlugin, REWRITTEN_PROMPT_TEXT, + REWRITTEN_PROMPT_TOPIC, REWRITTEN_SUM_A, REWRITTEN_SUM_B, RunningGateway, TEST_USER_ID, TestPlugin, error_code, + runtime_with_post, runtime_with_pre, runtime_with_pre_and_post, runtime_with_prompt_plugin, start_gateway, start_gateway_with_json_backend_responses, sum_request, text, token, }; @@ -678,3 +680,108 @@ async fn pre_hook_invalid_arguments_return_invalid_params() { assert_eq!(ErrorCode::INVALID_PARAMS, error_code(error)); assert!(gateway.backend_state.calls.lock().expect("backend calls lock poisoned").is_empty()); } + +// --------------------------------------------------------------------------- +// Prompt hooks +// --------------------------------------------------------------------------- + +fn review_request(topic: &str) -> GetPromptRequestParams { + GetPromptRequestParams::new("review") + .with_arguments(serde_json::Map::from_iter([("topic".to_owned(), json!(topic))])) +} + +fn prompt_text(result: &GetPromptResult) -> String { + result + .messages + .iter() + .filter_map(|message| match &message.content { + ContentBlock::Text(text) => Some(text.text.clone()), + _ => None, + }) + .collect() +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn prompt_pre_hook_rewrites_arguments_reaching_the_backend() { + let plugin = Arc::new(PromptTestPlugin::new("prompt-pre", vec![cmf_hook_names::PROMPT_PRE_FETCH])); + let observations = plugin.observations(); + let runtime = runtime_with_prompt_plugin(plugin).await; + + let gateway = start_gateway(TEST_USER_ID, true, runtime).await; + let service = gateway.connect(TEST_USER_ID).await; + let result = service.get_prompt(review_request("weather")).await.expect("prompt is returned"); + + assert_eq!(format!("review of {REWRITTEN_PROMPT_TOPIC}"), prompt_text(&result)); + + let prompt_calls = gateway.backend_state.prompts.lock().expect("backend prompts lock poisoned"); + assert_eq!("review", prompt_calls[0].tool_name); + assert_eq!( + Some(&Value::from(REWRITTEN_PROMPT_TOPIC)), + prompt_calls[0].args.as_ref().and_then(|args| args.get("topic")) + ); + + let observations = observations.lock().expect("observations lock poisoned"); + assert_eq!(1, observations.pre_calls); + assert_eq!(Some("review"), observations.pre_name.as_deref()); + assert_eq!(Some(gateway.backend_name.as_str()), observations.pre_server_id.as_deref()); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn prompt_post_hook_rewrites_rendered_text_before_client_response() { + let plugin = Arc::new(PromptTestPlugin::new("prompt-post", vec![cmf_hook_names::PROMPT_POST_FETCH])); + let observations = plugin.observations(); + let runtime = runtime_with_prompt_plugin(plugin).await; + + let gateway = start_gateway(TEST_USER_ID, true, runtime).await; + let service = gateway.connect(TEST_USER_ID).await; + let result = service.get_prompt(review_request("weather")).await.expect("prompt is returned"); + + assert_eq!(REWRITTEN_PROMPT_TEXT, prompt_text(&result)); + + let prompt_calls = gateway.backend_state.prompts.lock().expect("backend prompts lock poisoned"); + assert_eq!(Some(&Value::from("weather")), prompt_calls[0].args.as_ref().and_then(|args| args.get("topic"))); + drop(prompt_calls); + + let observations = observations.lock().expect("observations lock poisoned"); + assert_eq!(0, observations.pre_calls, "no pre hook is configured"); + assert_eq!(1, observations.post_calls); + assert_eq!(Some("review"), observations.post_prompt_name.as_deref()); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn prompt_post_hook_removing_rendered_text_fails_closed() { + let plugin = Arc::new( + PromptTestPlugin::new("prompt-post-drop", vec![cmf_hook_names::PROMPT_POST_FETCH]) + .with_behavior(PromptBehavior::DropText), + ); + let runtime = runtime_with_prompt_plugin(plugin).await; + + let gateway = start_gateway(TEST_USER_ID, true, runtime).await; + let service = gateway.connect(TEST_USER_ID).await; + + let error = service.get_prompt(review_request("weather")).await.expect_err("dropped text fails the call"); + assert_eq!(ErrorCode::INTERNAL_ERROR, error_code(error)); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn prompt_pre_and_post_hooks_share_gateway_call_context() { + let plugin = Arc::new( + PromptTestPlugin::new( + "prompt-context", + vec![cmf_hook_names::PROMPT_PRE_FETCH, cmf_hook_names::PROMPT_POST_FETCH], + ) + .with_behavior(PromptBehavior::ContextRoundtrip), + ); + let observations = plugin.observations(); + let runtime = runtime_with_prompt_plugin(plugin).await; + + let gateway = start_gateway(TEST_USER_ID, true, runtime).await; + let service = gateway.connect(TEST_USER_ID).await; + let result = service.get_prompt(review_request("weather")).await.expect("prompt is returned"); + + assert_eq!("review of weather", prompt_text(&result)); + + let observations = observations.lock().expect("observations lock poisoned"); + assert_eq!(1, observations.pre_calls); + assert_eq!(1, observations.post_calls); +} diff --git a/crates/contextforge-gateway-rs-lib/tests/support/mod.rs b/crates/contextforge-gateway-rs-lib/tests/support/mod.rs index 54f6898e..fd7da55c 100644 --- a/crates/contextforge-gateway-rs-lib/tests/support/mod.rs +++ b/crates/contextforge-gateway-rs-lib/tests/support/mod.rs @@ -24,9 +24,10 @@ pub(crate) use list_tools_gateway::{ create_tls_gateway_with_four_tls_counters, plaintext_config, }; pub(crate) use plugin::{ - POST_DENY_ERROR_CODE, PRE_DENY_ERROR_CODE, REWRITTEN_SUM_A, REWRITTEN_SUM_B, TestPlugin, TestPluginFactory, + POST_DENY_ERROR_CODE, PRE_DENY_ERROR_CODE, PromptBehavior, PromptTestPlugin, PromptTestPluginFactory, + REWRITTEN_PROMPT_TEXT, REWRITTEN_PROMPT_TOPIC, REWRITTEN_SUM_A, REWRITTEN_SUM_B, TestPlugin, TestPluginFactory, }; pub(crate) use plugin_gateway::{RunningGateway, start_gateway, start_gateway_with_json_backend_responses}; -pub(crate) use runtime::{runtime_with_post, runtime_with_pre, runtime_with_pre_and_post}; +pub(crate) use runtime::{runtime_with_post, runtime_with_pre, runtime_with_pre_and_post, runtime_with_prompt_plugin}; pub(crate) use tool::{error_code, sum_request, text}; pub(crate) use user_config_store::MemoryUserConfigStore; diff --git a/crates/contextforge-gateway-rs-lib/tests/support/plugin.rs b/crates/contextforge-gateway-rs-lib/tests/support/plugin.rs index ddc02109..ddd9446c 100644 --- a/crates/contextforge-gateway-rs-lib/tests/support/plugin.rs +++ b/crates/contextforge-gateway-rs-lib/tests/support/plugin.rs @@ -314,6 +314,184 @@ impl TestPluginFactory { } } +pub(crate) const REWRITTEN_PROMPT_TOPIC: &str = "rewritten-topic"; +pub(crate) const REWRITTEN_PROMPT_TEXT: &str = "review of [REDACTED]"; + +/// What [`PromptTestPlugin`] does when a hook fires. One value drives both hooks so a single +/// fixture can serve pre-only, post-only, and pre-and-post configurations. +#[derive(Clone, Copy, Default)] +pub(crate) enum PromptBehavior { + /// Pre rewrites the `topic` argument; post rewrites the rendered text. + #[default] + Rewrite, + /// Post deletes the rendered text part outright, so the write-back has nothing to line up + /// against. Models a redaction plugin dropping content the client must never receive. + DropText, + /// Pre leaves a marker in the CPEX context; post denies unless it reads the marker back. + ContextRoundtrip, +} + +/// Fake plugin for the prompt hooks. It reads `PromptRequest` and `PromptResult` content parts +/// rather than the tool parts [`TestPlugin`] handles. Which hook is running is inferred from the +/// payload, so one handler serves both. +pub(crate) struct PromptTestPlugin { + pub(crate) config: PluginConfig, + pub(crate) observations: Arc>, + pub(crate) behavior: PromptBehavior, +} + +#[derive(Default)] +pub(crate) struct PromptObservations { + pub(crate) pre_calls: usize, + pub(crate) pre_name: Option, + pub(crate) pre_server_id: Option, + pub(crate) post_calls: usize, + pub(crate) post_prompt_name: Option, +} + +impl PromptTestPlugin { + pub(crate) fn new(name: &str, hooks: Vec<&'static str>) -> Self { + Self { + config: PluginConfig { + name: name.to_owned(), + kind: "prompt-test".to_owned(), + hooks: hooks.into_iter().map(str::to_owned).collect(), + ..Default::default() + }, + observations: Arc::new(Mutex::new(PromptObservations::default())), + behavior: PromptBehavior::default(), + } + } + + pub(crate) fn with_behavior(mut self, behavior: PromptBehavior) -> Self { + self.behavior = behavior; + self + } + + pub(crate) fn observations(&self) -> Arc> { + Arc::clone(&self.observations) + } + + fn handle_pre(&self, payload: &MessagePayload, ctx: &mut PluginContext) -> PluginResult { + let mut observations = self.observations.lock().expect("observations lock poisoned"); + observations.pre_calls += 1; + if let Some(request) = payload.message.get_prompt_requests().first() { + observations.pre_name = Some(request.name.clone()); + observations.pre_server_id.clone_from(&request.server_id); + } + drop(observations); + + match self.behavior { + PromptBehavior::ContextRoundtrip => { + ctx.set_global("prompt_pre_seen", json!(true)); + PluginResult::allow() + }, + PromptBehavior::Rewrite | PromptBehavior::DropText => { + let mut modified = payload.clone(); + if let Some(ContentPart::PromptRequest { content }) = + modified.message.content.iter_mut().find(|part| matches!(part, ContentPart::PromptRequest { .. })) + { + content.arguments = HashMap::from([("topic".to_owned(), json!(REWRITTEN_PROMPT_TOPIC))]); + } + PluginResult::modify_payload(modified) + }, + } + } + + fn handle_post(&self, payload: &MessagePayload, ctx: &mut PluginContext) -> PluginResult { + let mut observations = self.observations.lock().expect("observations lock poisoned"); + observations.post_calls += 1; + if let Some(result) = payload.message.get_prompt_results().first() { + observations.post_prompt_name = Some(result.prompt_name.clone()); + } + drop(observations); + + match self.behavior { + PromptBehavior::Rewrite => { + let mut modified = payload.clone(); + for part in &mut modified.message.content { + if let ContentPart::Text { text } = part { + REWRITTEN_PROMPT_TEXT.clone_into(text); + } + } + PluginResult::modify_payload(modified) + }, + PromptBehavior::DropText => { + let mut modified = payload.clone(); + modified.message.content.retain(|part| !matches!(part, ContentPart::Text { .. })); + PluginResult::modify_payload(modified) + }, + PromptBehavior::ContextRoundtrip => { + if ctx.get_global("prompt_pre_seen") == Some(&json!(true)) { + PluginResult::allow() + } else { + PluginResult::deny( + PluginViolation::new("missing_prompt_context", "prompt pre context missing") + .with_proto_error_code(i64::from(MISSING_CONTEXT_ERROR_CODE)), + ) + } + }, + } + } +} + +#[async_trait] +impl Plugin for PromptTestPlugin { + fn config(&self) -> &PluginConfig { + &self.config + } +} + +impl HookHandler for PromptTestPlugin { + async fn handle( + &self, + payload: &MessagePayload, + _extensions: &Extensions, + ctx: &mut PluginContext, + ) -> PluginResult { + // A rendered prompt carries a `PromptResult` part, a request carries a `PromptRequest` + // one, so the payload itself says which hook is running. + if payload.message.get_prompt_results().is_empty() { + self.handle_pre(payload, ctx) + } else { + self.handle_post(payload, ctx) + } + } +} + +pub(crate) struct PromptTestPluginFactory { + observations: Arc>, + behavior: PromptBehavior, +} + +impl PromptTestPluginFactory { + pub(crate) fn from_plugin(plugin: &PromptTestPlugin) -> Self { + Self { observations: Arc::clone(&plugin.observations), behavior: plugin.behavior } + } +} + +impl PluginFactory for PromptTestPluginFactory { + fn create(&self, config: &PluginConfig) -> Result> { + let plugin = Arc::new(PromptTestPlugin { + config: config.clone(), + observations: Arc::clone(&self.observations), + behavior: self.behavior, + }); + let mut handlers = Vec::new(); + for hook in [cmf_hook_names::PROMPT_PRE_FETCH, cmf_hook_names::PROMPT_POST_FETCH] { + if config.hooks.iter().any(|configured| configured == hook) { + handlers.push(( + hook, + Arc::new(TypedHandlerAdapter::::new(Arc::clone(&plugin))) + as Arc, + )); + } + } + let plugin: Arc = plugin; + Ok(PluginInstance { plugin, handlers }) + } +} + impl PluginFactory for TestPluginFactory { fn create(&self, config: &PluginConfig) -> Result> { let plugin = Arc::new(TestPlugin { diff --git a/crates/contextforge-gateway-rs-lib/tests/support/plugin_gateway.rs b/crates/contextforge-gateway-rs-lib/tests/support/plugin_gateway.rs index edf75a58..b79d259a 100644 --- a/crates/contextforge-gateway-rs-lib/tests/support/plugin_gateway.rs +++ b/crates/contextforge-gateway-rs-lib/tests/support/plugin_gateway.rs @@ -15,9 +15,9 @@ use http::{HeaderMap, HeaderValue}; use rmcp::{ ErrorData, RoleClient, RoleServer, ServerHandler, ServiceExt, model::{ - CallToolRequestParams, CallToolResponse, CallToolResult, ContentBlock, ErrorCode, Implementation, - InitializeRequestParams, InitializeResult, NumberOrString, ProgressNotificationParam, ProgressToken, - ServerCapabilities, + CallToolRequestParams, CallToolResponse, CallToolResult, ContentBlock, ErrorCode, GetPromptRequestParams, + GetPromptResponse, GetPromptResult, Implementation, InitializeRequestParams, InitializeResult, NumberOrString, + ProgressNotificationParam, ProgressToken, PromptMessage, Role, ServerCapabilities, }, service::{RequestContext, Service}, transport::{ @@ -45,6 +45,7 @@ pub(crate) struct BackendObservation { #[derive(Clone, Default)] pub(crate) struct BackendState { pub(crate) calls: Arc>>, + pub(crate) prompts: Arc>>, pub(crate) cancellations: Arc>>, } @@ -59,10 +60,32 @@ impl ServerHandler for TestBackend { _request: InitializeRequestParams, _cx: RequestContext, ) -> Result { - Ok(InitializeResult::new(ServerCapabilities::builder().enable_tools().build()) + Ok(InitializeResult::new(ServerCapabilities::builder().enable_tools().enable_prompts().build()) .with_server_info(Implementation::new("test-backend", "0.1.0"))) } + /// Renders `review` from its `topic` argument, so a test can prove a pre-hook argument + /// rewrite actually reached the backend. + async fn get_prompt( + &self, + request: GetPromptRequestParams, + _cx: RequestContext, + ) -> Result { + self.state + .prompts + .lock() + .expect("backend prompts lock poisoned") + .push(BackendObservation { tool_name: request.name.clone(), args: request.arguments.clone() }); + + let topic = request + .arguments + .as_ref() + .and_then(|arguments| arguments.get("topic")) + .and_then(Value::as_str) + .unwrap_or("nothing"); + Ok(GetPromptResult::new(vec![PromptMessage::new_text(Role::User, format!("review of {topic}"))]).into()) + } + async fn call_tool( &self, request: CallToolRequestParams, diff --git a/crates/contextforge-gateway-rs-lib/tests/support/runtime.rs b/crates/contextforge-gateway-rs-lib/tests/support/runtime.rs index 5a6f463c..9d6630ca 100644 --- a/crates/contextforge-gateway-rs-lib/tests/support/runtime.rs +++ b/crates/contextforge-gateway-rs-lib/tests/support/runtime.rs @@ -4,7 +4,25 @@ use contextforge_gateway_rs_cpex::CpexRuntimeRegistry; use cpex::cpex_core::config::CpexConfig; use serde_json::json; -use super::{TestPlugin, TestPluginFactory}; +use super::{PromptTestPlugin, PromptTestPluginFactory, TestPlugin, TestPluginFactory}; + +/// Builds a runtime holding a single prompt plugin, mirroring [`runtime_with_plugins`]. +pub(crate) async fn runtime_with_prompt_plugin(plugin: Arc) -> Arc { + let mut runtime = CpexRuntimeRegistry::default(); + runtime + .register_factory("prompt-test", Box::new(PromptTestPluginFactory::from_plugin(&plugin))) + .expect("prompt test factory registers"); + let config = serde_json::from_value(json!({ + "plugins": [{ + "name": plugin.config.name.clone(), + "kind": plugin.config.kind.clone(), + "hooks": plugin.config.hooks.clone(), + }] + })) + .expect("prompt CPEX config parses"); + runtime.apply_config(Some(config)).await.expect("prompt runtime config applies"); + Arc::new(runtime) +} pub(crate) async fn runtime_with_pre(plugin: Arc) -> Arc { runtime_with_plugins(&[plugin]).await From 9a67061ca6585c58680bae852f9bcdcefc51928c Mon Sep 17 00:00:00 2001 From: Madhu Mohan Jaishankar Date: Mon, 10 Aug 2026 19:00:25 +0100 Subject: [PATCH 2/7] chore: drop redundant comments from prompt hook tests Signed-off-by: Madhu Mohan Jaishankar --- crates/contextforge-gateway-rs-cpex/src/cmf.rs | 2 -- .../tests/support/plugin.rs | 11 ----------- .../tests/support/plugin_gateway.rs | 2 -- .../tests/support/runtime.rs | 1 - 4 files changed, 16 deletions(-) diff --git a/crates/contextforge-gateway-rs-cpex/src/cmf.rs b/crates/contextforge-gateway-rs-cpex/src/cmf.rs index 0791db3e..9a392527 100644 --- a/crates/contextforge-gateway-rs-cpex/src/cmf.rs +++ b/crates/contextforge-gateway-rs-cpex/src/cmf.rs @@ -199,8 +199,6 @@ mod tests { use super::*; - /// The write-back refuses extra text as well as missing text: a plugin that appends a part - /// leaves it with nowhere to go, and guessing would silently drop the plugin's edit. #[test] fn prompt_result_response_rejects_added_text() { let original = GetPromptResult::new(vec![PromptMessage::new_text(McpRole::User, "review of weather")]); diff --git a/crates/contextforge-gateway-rs-lib/tests/support/plugin.rs b/crates/contextforge-gateway-rs-lib/tests/support/plugin.rs index ddd9446c..7792ffce 100644 --- a/crates/contextforge-gateway-rs-lib/tests/support/plugin.rs +++ b/crates/contextforge-gateway-rs-lib/tests/support/plugin.rs @@ -317,23 +317,14 @@ impl TestPluginFactory { pub(crate) const REWRITTEN_PROMPT_TOPIC: &str = "rewritten-topic"; pub(crate) const REWRITTEN_PROMPT_TEXT: &str = "review of [REDACTED]"; -/// What [`PromptTestPlugin`] does when a hook fires. One value drives both hooks so a single -/// fixture can serve pre-only, post-only, and pre-and-post configurations. #[derive(Clone, Copy, Default)] pub(crate) enum PromptBehavior { - /// Pre rewrites the `topic` argument; post rewrites the rendered text. #[default] Rewrite, - /// Post deletes the rendered text part outright, so the write-back has nothing to line up - /// against. Models a redaction plugin dropping content the client must never receive. DropText, - /// Pre leaves a marker in the CPEX context; post denies unless it reads the marker back. ContextRoundtrip, } -/// Fake plugin for the prompt hooks. It reads `PromptRequest` and `PromptResult` content parts -/// rather than the tool parts [`TestPlugin`] handles. Which hook is running is inferred from the -/// payload, so one handler serves both. pub(crate) struct PromptTestPlugin { pub(crate) config: PluginConfig, pub(crate) observations: Arc>, @@ -449,8 +440,6 @@ impl HookHandler for PromptTestPlugin { _extensions: &Extensions, ctx: &mut PluginContext, ) -> PluginResult { - // A rendered prompt carries a `PromptResult` part, a request carries a `PromptRequest` - // one, so the payload itself says which hook is running. if payload.message.get_prompt_results().is_empty() { self.handle_pre(payload, ctx) } else { diff --git a/crates/contextforge-gateway-rs-lib/tests/support/plugin_gateway.rs b/crates/contextforge-gateway-rs-lib/tests/support/plugin_gateway.rs index b79d259a..876576c0 100644 --- a/crates/contextforge-gateway-rs-lib/tests/support/plugin_gateway.rs +++ b/crates/contextforge-gateway-rs-lib/tests/support/plugin_gateway.rs @@ -64,8 +64,6 @@ impl ServerHandler for TestBackend { .with_server_info(Implementation::new("test-backend", "0.1.0"))) } - /// Renders `review` from its `topic` argument, so a test can prove a pre-hook argument - /// rewrite actually reached the backend. async fn get_prompt( &self, request: GetPromptRequestParams, diff --git a/crates/contextforge-gateway-rs-lib/tests/support/runtime.rs b/crates/contextforge-gateway-rs-lib/tests/support/runtime.rs index 9d6630ca..398a52ff 100644 --- a/crates/contextforge-gateway-rs-lib/tests/support/runtime.rs +++ b/crates/contextforge-gateway-rs-lib/tests/support/runtime.rs @@ -6,7 +6,6 @@ use serde_json::json; use super::{PromptTestPlugin, PromptTestPluginFactory, TestPlugin, TestPluginFactory}; -/// Builds a runtime holding a single prompt plugin, mirroring [`runtime_with_plugins`]. pub(crate) async fn runtime_with_prompt_plugin(plugin: Arc) -> Arc { let mut runtime = CpexRuntimeRegistry::default(); runtime From 9e43e110f0d226105e74360369fafa370b93dcd5 Mon Sep 17 00:00:00 2001 From: Madhu Mohan Jaishankar Date: Mon, 10 Aug 2026 19:08:03 +0100 Subject: [PATCH 3/7] chore: untrack local gateway run logs Signed-off-by: Madhu Mohan Jaishankar --- contextforge-gateway-rs.log.2026-05-28-14 | 32 - contextforge-gateway-rs.log.2026-05-29-13 | 310 -------- contextforge-gateway-rs.log.2026-05-29-14 | 720 ------------------- contextforge-gateway-rs.log.2026-05-29-15 | 816 ---------------------- 4 files changed, 1878 deletions(-) delete mode 100644 contextforge-gateway-rs.log.2026-05-28-14 delete mode 100644 contextforge-gateway-rs.log.2026-05-29-13 delete mode 100644 contextforge-gateway-rs.log.2026-05-29-14 delete mode 100644 contextforge-gateway-rs.log.2026-05-29-15 diff --git a/contextforge-gateway-rs.log.2026-05-28-14 b/contextforge-gateway-rs.log.2026-05-28-14 deleted file mode 100644 index 2b6e1efd..00000000 --- a/contextforge-gateway-rs.log.2026-05-28-14 +++ /dev/null @@ -1,32 +0,0 @@ -2026-05-28T14:50:44.830318Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ThreadStarted" interval_in_millisecs=5000 max_export_batch_size=512 max_queue_size=2048 -2026-05-28T14:50:44.899506Z DEBUG rustls::webpki::anchors: add_parsable_certificates processed 146 valid and 0 invalid certs -2026-05-28T14:50:44.899604Z DEBUG rustls_platform_verifier::verification::others: Loaded 146 CA root certificates from the system -2026-05-28T14:50:44.901110Z INFO contextforge_gateway_rs_lib::transports::tcp: Starting TCP listener at 0.0.0.0:8001 -2026-05-28T14:50:49.830703Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:50:54.831092Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:50:59.831431Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:51:04.831769Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:51:09.832210Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:51:14.832510Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:51:19.832900Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:51:24.833231Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:51:29.833558Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:51:34.834029Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:51:39.834318Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:51:44.834652Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:51:49.834920Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:51:54.835287Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:51:59.835566Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:52:04.835858Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:52:09.836130Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:52:14.836392Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:52:19.836690Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:52:24.836972Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:52:29.837213Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:52:34.837496Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:52:39.837798Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:52:44.838055Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:52:49.838399Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:52:54.838656Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:52:59.838931Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-28T14:53:04.839234Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" diff --git a/contextforge-gateway-rs.log.2026-05-29-13 b/contextforge-gateway-rs.log.2026-05-29-13 deleted file mode 100644 index 845f2b85..00000000 --- a/contextforge-gateway-rs.log.2026-05-29-13 +++ /dev/null @@ -1,310 +0,0 @@ -2026-05-29T13:36:35.164102Z DEBUG rustls::webpki::anchors: add_parsable_certificates processed 146 valid and 0 invalid certs -2026-05-29T13:36:35.164227Z DEBUG rustls_platform_verifier::verification::others: Loaded 146 CA root certificates from the system -2026-05-29T13:36:35.165587Z INFO contextforge_gateway_rs_lib::transports::tcp: Starting TCP listener at 0.0.0.0:8001 -2026-05-29T13:36:40.112609Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:36:45.112993Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:36:50.113238Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:36:55.113487Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:37:00.113757Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:37:05.114052Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:37:06.629924Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T13:37:06.630071Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T13:37:06.636927Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T13:37:06.637060Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T13:37:06.642724Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T13:37:06.642922Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T13:37:06.648929Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T13:37:06.649108Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T13:37:06.654587Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T13:37:06.654691Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T13:37:06.660599Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T13:37:06.660734Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T13:37:06.667025Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T13:37:06.667133Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T13:37:06.673289Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T13:37:06.673402Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T13:37:06.679426Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T13:37:06.679543Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T13:37:06.684711Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T13:37:06.684816Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T13:37:10.114356Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:37:10.115598Z DEBUG opentelemetry-otlp: name="HttpTracesClient.ExportStarted" -2026-05-29T13:37:10.115679Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T13:37:10.116375Z DEBUG reqwest::connect: starting new connection: http://127.0.0.1:3100/ -2026-05-29T13:37:10.116506Z DEBUG hyper_util::client::legacy::connect::http: connecting to 127.0.0.1:3100 -2026-05-29T13:37:10.116778Z DEBUG hyper_util::client::legacy::connect::http: connected to 127.0.0.1:3100 -2026-05-29T13:37:10.251230Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:3100) -2026-05-29T13:37:10.251632Z DEBUG opentelemetry-otlp: name="HttpTracesClient.ExportSucceeded" -2026-05-29T13:37:15.114686Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:37:20.114961Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:37:25.115277Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:37:30.115611Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:37:35.115851Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:37:40.116126Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:37:45.116361Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:37:50.116606Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:37:55.116983Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:38:00.117459Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:38:05.117751Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:38:10.118035Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:38:15.118392Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:38:20.118662Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:38:25.118932Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:38:30.119215Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:38:35.119589Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:38:40.119922Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:38:45.120231Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:38:50.120725Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:38:55.120975Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:39:00.121185Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:39:05.121377Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:39:10.121620Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:39:15.121955Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:39:20.122253Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:39:25.122516Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:39:30.122752Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:39:35.122985Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:39:40.123212Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:39:45.123497Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:39:50.123845Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:39:55.124166Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:40:00.124452Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:40:05.124691Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:40:10.125023Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:40:15.125346Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:40:20.125669Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:40:25.126037Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:40:30.126473Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:40:35.126833Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:40:40.127079Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:40:45.127339Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:40:50.127633Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:40:55.127871Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:41:00.128096Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:41:05.128371Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:41:10.128616Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:41:15.128856Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:41:20.129338Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:41:25.129649Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:41:30.129927Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:41:35.130259Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:41:40.130528Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:41:45.130860Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:41:50.131248Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:41:55.131530Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:42:00.131845Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:42:05.132164Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:42:10.132510Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:42:15.132780Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:42:20.133075Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:42:25.133401Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:42:30.133634Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:42:35.133899Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:42:40.134225Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:42:45.134475Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:42:50.134751Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:42:55.135080Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:43:00.135388Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:43:05.135665Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:43:10.135981Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:43:15.136228Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:43:20.136554Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:43:25.136911Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:43:30.137161Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:43:35.137422Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:43:40.137676Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:43:45.137883Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:43:50.138152Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:43:55.138502Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:44:00.138846Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:44:05.139105Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:44:10.139342Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:44:15.139602Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:44:20.139959Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:44:25.140247Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:44:30.140582Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:44:35.140890Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:44:40.141175Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:44:45.141549Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:44:50.141820Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:44:55.142093Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:45:00.142395Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:45:05.142712Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:45:10.142998Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:45:15.143270Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:45:20.143519Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:45:25.143792Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:45:30.144122Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:45:35.144347Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:45:40.144665Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:45:45.144928Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:45:50.145228Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:45:55.145483Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:46:00.145742Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:46:05.145986Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:46:10.146254Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:46:15.146492Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:46:20.146725Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:46:25.146980Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:46:30.147270Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:46:35.147530Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:46:40.147789Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:46:45.148051Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:46:50.148304Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:46:55.148538Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:47:00.148775Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:47:05.149053Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:47:10.149331Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:47:15.149603Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:47:20.149864Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:47:25.150119Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:47:30.150389Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:47:35.150641Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:47:40.150927Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:47:45.151199Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:47:50.151450Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:47:55.151728Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:48:00.151966Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:48:05.152205Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:48:10.152484Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:48:15.152739Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:48:20.153013Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:48:25.153279Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:48:30.153516Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:48:35.153760Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:48:40.154345Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:48:45.154708Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:48:50.154981Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:48:55.155241Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:49:00.155490Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:49:05.155753Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:49:10.156032Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:49:15.156283Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:49:20.156556Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:49:25.156793Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:49:30.157075Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:49:35.157336Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:49:40.157585Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:49:45.157819Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:49:50.158086Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:49:55.158410Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:50:00.158675Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:50:05.158984Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:50:10.159241Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:50:15.159500Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:50:20.159756Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:50:25.160021Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:50:30.160253Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:50:35.160513Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:50:40.160777Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:50:45.161111Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:50:50.161392Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:50:55.161624Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:51:00.161908Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:51:05.162233Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:51:10.162517Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:51:15.162800Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:51:20.163053Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:51:25.163354Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:51:30.163609Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:51:35.163849Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:51:40.164091Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:51:45.164392Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:51:50.164634Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:51:55.164888Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:52:00.165192Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:52:05.165450Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:52:10.165756Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:52:15.166012Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:52:20.166260Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:52:25.166519Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:52:30.166761Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:52:35.167017Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:52:40.167300Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:52:45.167606Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:52:50.167849Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:52:55.168124Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:53:00.168368Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:53:05.168646Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:53:10.168921Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:53:15.169201Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:53:20.169511Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:53:25.169860Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:53:30.170134Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:53:35.170422Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:53:40.170672Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:53:45.170897Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:53:50.171236Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:53:55.171552Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:54:00.171810Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:54:05.172071Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:54:10.172346Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:54:15.172600Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:54:20.172862Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:54:25.173133Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:54:30.173372Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:54:35.173594Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:54:40.173833Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:54:45.174412Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:54:50.174675Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:54:55.175060Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:55:00.175402Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:55:05.175645Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:55:10.176051Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:55:15.176340Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:55:20.176630Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:55:25.176892Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:55:30.177169Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:55:35.177443Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:55:40.177729Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:55:45.177984Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:55:50.178232Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:55:55.178469Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:56:00.178705Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:56:05.179049Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:56:10.179275Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:56:15.179529Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:56:20.179784Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:56:25.180046Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:56:30.180381Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:56:35.180714Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:56:40.180932Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:56:45.181216Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:56:50.181484Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:56:55.181756Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:57:00.182072Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:57:05.182326Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:57:10.182548Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:57:15.182822Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:57:20.183084Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:57:25.183465Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:57:30.183721Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:57:35.184013Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:57:40.184249Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:57:45.184491Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:57:50.184730Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:57:55.184991Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:58:00.185251Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:58:05.185543Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:58:10.185806Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:58:15.186085Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:58:20.186370Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:58:25.186608Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:58:30.186917Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:58:35.187240Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:58:40.187508Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:58:45.187811Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:58:50.188130Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:58:55.188463Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:59:00.188715Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:59:05.188959Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:59:10.189244Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:59:15.189529Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:59:20.189763Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:59:25.189987Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:59:30.190258Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:59:35.190522Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:59:40.190933Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:59:45.191210Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:59:50.191527Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T13:59:55.191765Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" diff --git a/contextforge-gateway-rs.log.2026-05-29-14 b/contextforge-gateway-rs.log.2026-05-29-14 deleted file mode 100644 index 548d5eb7..00000000 --- a/contextforge-gateway-rs.log.2026-05-29-14 +++ /dev/null @@ -1,720 +0,0 @@ -2026-05-29T14:00:00.192033Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:00:05.192293Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:00:10.192562Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:00:15.192835Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:00:20.193067Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:00:25.193327Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:00:30.193626Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:00:35.193875Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:00:40.194109Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:00:45.194401Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:00:50.194645Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:00:55.194925Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:01:00.195214Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:01:05.195513Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:01:10.195824Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:01:15.196146Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:01:20.196424Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:01:25.196706Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:01:30.196969Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:01:35.197246Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:01:40.197522Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:01:45.197900Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:01:50.198230Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:01:55.198536Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:02:00.198806Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:02:05.199055Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:02:10.199308Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:02:15.199617Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:02:20.199887Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:02:25.200166Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:02:30.200501Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:02:35.200798Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:02:40.201163Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:02:45.201554Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:02:50.201854Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:02:55.202116Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:03:00.202380Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:03:05.202754Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:03:10.203038Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:03:15.203279Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:03:20.203546Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:03:25.204221Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:03:30.204544Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:03:35.204784Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:03:40.205050Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:03:45.205382Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:03:50.205606Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:03:55.205830Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:04:00.206086Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:04:05.206368Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:04:10.206607Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:04:15.206862Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:04:20.207170Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:04:25.207456Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:04:30.207732Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:04:35.207979Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:04:40.208204Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:04:45.208466Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:04:50.208740Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:04:55.208996Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:05:00.209235Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:05:05.209493Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:05:10.209784Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:05:15.210090Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:05:20.210407Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:05:25.210688Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:05:30.210947Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:05:35.211264Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:05:40.211580Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:05:45.211812Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:05:50.212068Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:05:55.212364Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:06:00.212651Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:06:05.212893Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:06:10.213138Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:06:15.213364Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:06:20.213610Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:06:25.213871Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:06:30.214115Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:06:35.214376Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:06:40.214724Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:06:45.215034Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:06:50.215346Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:06:55.215645Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:07:00.215984Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:07:05.216322Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:07:10.216596Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:07:15.216847Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:07:20.217114Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:07:25.217412Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:07:30.217680Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:07:35.218013Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:07:40.218301Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:07:45.218548Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:07:50.218839Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:07:55.219118Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:08:00.219404Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:08:05.219645Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:08:10.219938Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:08:15.220190Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:08:20.220414Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:08:25.220739Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:08:30.220994Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:08:35.221242Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:08:40.221506Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:08:45.221749Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:08:50.221960Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:08:55.222248Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:09:00.222649Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:09:05.222903Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:09:10.223146Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:09:15.223384Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:09:20.223626Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:09:25.223903Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:09:30.224137Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:09:35.224412Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:09:40.224688Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:09:45.225022Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:09:50.225315Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:09:55.225603Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:10:00.225876Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:10:05.226242Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:10:10.226474Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:10:15.226710Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:10:20.226963Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:10:25.227237Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:10:30.227529Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:10:35.227791Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:10:40.228067Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:10:45.228307Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:10:50.228546Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:10:55.228831Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:11:00.229064Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:11:05.229323Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:11:10.229605Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:11:15.229873Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:11:20.230123Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:11:25.230415Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:11:30.230680Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:11:35.230995Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:11:40.231231Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:11:45.231508Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:11:50.231784Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:11:55.232029Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:12:00.232365Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:12:05.232725Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:12:10.233013Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:12:15.233257Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:12:20.233484Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:12:25.233737Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:12:30.233995Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:12:35.234273Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:12:40.234551Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:12:45.234822Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:12:50.235092Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:12:55.235356Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:13:00.235618Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:13:05.235859Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:13:10.236128Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:13:15.236373Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:13:20.236643Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:13:25.236890Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:13:30.237132Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:13:35.237798Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:13:40.238050Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:13:45.238296Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:13:50.238549Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:13:55.238811Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:14:00.239094Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:14:05.239409Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:14:10.239740Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:14:15.240096Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:14:20.240430Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:14:25.240776Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:14:30.241088Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:14:35.241446Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:14:40.241737Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:14:45.241985Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:14:50.242269Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:14:55.242544Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:15:00.242854Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:15:05.243163Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:15:10.243905Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:15:15.244153Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:15:20.244508Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:15:25.244800Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:15:30.245206Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:15:35.245478Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:15:40.245996Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:15:45.246355Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:15:50.246626Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:15:55.246961Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:16:00.247253Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:16:05.247547Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:16:10.247882Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:16:15.248172Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:16:20.248459Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:16:25.248790Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:16:30.249151Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:16:35.249462Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:16:40.249741Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:16:45.250108Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:16:50.250507Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:16:55.250740Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:17:00.250975Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:17:05.251282Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:17:10.251560Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:17:15.251850Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:17:20.252136Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:17:25.252400Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:17:30.252682Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:17:35.252974Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:17:40.253261Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:17:45.253559Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:17:50.255078Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:17:55.255511Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:18:00.255795Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:18:05.256041Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:18:10.256338Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:18:15.256592Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:18:20.256923Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:18:25.257286Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:18:30.257551Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:18:35.257885Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:18:40.258143Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:18:45.258444Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:18:50.258703Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:18:55.258976Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:19:00.259220Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:19:05.259503Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:19:10.259814Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:19:15.260076Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:19:20.260497Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:19:25.260869Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:19:30.261206Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:19:35.261395Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:19:40.261667Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:19:45.261911Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:19:50.262232Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:19:55.262476Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:20:00.262747Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:20:05.263003Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:20:10.263253Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:20:15.263497Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:20:20.263749Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:20:25.263988Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:20:30.264228Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:20:35.264479Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:20:40.264746Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:20:45.265029Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:20:50.265289Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:20:55.265541Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:21:00.265798Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:21:05.266038Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:21:10.266297Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:21:15.266602Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:21:20.266878Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:21:25.267189Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:21:30.267454Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:21:35.267711Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:21:40.267944Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:21:45.268184Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:21:50.268566Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:21:55.268776Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:22:00.269047Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:22:05.269371Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:22:10.269674Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:22:15.269979Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:22:20.270309Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:22:25.270551Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:22:30.270812Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:22:35.271067Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:22:40.271350Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:22:45.271597Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:22:50.271814Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:22:55.272045Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:23:00.272328Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:23:05.272607Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:23:10.272882Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:23:15.273152Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:23:20.273474Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:23:25.273869Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:23:30.274240Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:23:35.274539Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:23:40.274782Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:23:45.275032Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:23:50.275276Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:23:55.275533Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:24:00.275763Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:24:05.276068Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:24:10.276317Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:24:15.276545Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:24:20.276803Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:24:25.277121Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:24:30.277381Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:24:35.277674Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:24:40.277917Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:24:45.278226Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:24:50.278524Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:24:55.278826Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:25:00.279064Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:25:05.279286Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:25:10.279564Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:25:15.279850Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:25:20.280098Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:25:25.280373Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:25:30.280651Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:25:35.280901Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:25:40.281185Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:25:45.281415Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:25:50.281653Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:25:55.281980Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:26:00.282286Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:26:05.282499Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:26:10.282726Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:26:15.282977Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:26:20.283225Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:26:25.283471Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:26:30.283726Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:26:35.283977Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:26:40.284234Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:26:45.284500Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:26:50.284736Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:26:55.284998Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:27:00.285228Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:27:05.285467Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:27:10.285800Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:27:15.286087Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:27:20.286397Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:27:25.286650Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:27:30.286904Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:27:35.287136Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:27:40.287395Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:27:45.287655Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:27:50.287900Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:27:55.288158Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:28:00.288420Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:28:05.288720Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:28:10.288991Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:28:15.289276Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:28:20.289724Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:28:25.289959Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:28:30.290232Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:28:35.290478Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:28:40.290780Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:28:45.291124Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:28:50.291415Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:28:55.291748Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:29:00.292001Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:29:05.292252Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:29:10.292518Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:29:15.292802Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:29:20.293082Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:29:25.293372Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:29:30.293601Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:29:35.293843Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:29:40.294087Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:29:45.294365Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:29:50.294663Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:29:55.294933Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:30:00.295212Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:30:05.295471Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:30:10.295719Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:30:15.295984Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:30:20.296277Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:30:25.296568Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:30:30.296826Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:30:35.297053Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:30:40.297357Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:30:45.297631Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:30:50.297908Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:30:55.298231Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:31:00.298448Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:31:05.298770Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:31:10.299049Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:31:15.299339Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:31:20.299581Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:31:25.299832Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:31:30.300084Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:31:35.300341Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:31:40.300627Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:31:45.300924Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:31:50.301283Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:31:55.301583Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:32:00.302040Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:32:05.302280Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:32:10.302501Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:32:15.302746Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:32:20.303020Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:32:25.303308Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:32:30.303602Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:32:35.303980Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:32:40.304320Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:32:45.304564Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:32:50.304825Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:32:55.305103Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:33:00.305380Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:33:05.305715Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:33:10.305978Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:33:15.306495Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:33:20.306877Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:33:25.307170Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:33:30.307430Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:33:35.307674Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:33:40.307927Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:33:45.308193Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:33:50.308452Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:33:55.308739Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:34:00.309002Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:34:05.309355Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:34:10.309596Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:34:15.309864Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:34:20.310101Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:34:25.310378Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:34:30.310626Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:34:35.310858Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:34:40.311056Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:34:45.311336Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:34:50.311659Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:34:55.312006Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:35:00.312277Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:35:05.312539Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:35:10.312793Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:35:15.313054Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:35:20.313337Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:35:25.313597Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:35:30.313887Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:35:35.314149Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:35:40.314445Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:35:45.314673Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:35:50.314899Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:35:55.315154Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:36:00.315421Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:36:05.315660Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:36:10.315902Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:36:15.316135Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:36:20.316373Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:36:25.316662Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:36:30.316885Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:36:35.317136Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:36:40.317419Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:36:45.317647Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:36:50.317899Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:36:55.318159Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:37:00.318549Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:37:05.318850Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:37:10.319117Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:37:15.319409Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:37:20.319699Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:37:25.319964Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:37:30.320242Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:37:35.320524Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:37:40.320831Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:37:45.321169Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:37:50.321449Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:37:55.321841Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:38:00.322264Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:38:05.322576Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:38:10.322919Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:38:15.323226Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:38:20.323510Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:38:25.323794Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:38:30.324082Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:38:35.324409Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:38:40.324668Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:38:45.324981Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:38:50.325216Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:38:55.325474Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:39:00.325753Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:39:05.326045Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:39:10.326341Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:39:15.326608Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:39:20.326979Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:39:25.327268Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:39:30.327535Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:39:35.327766Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:39:40.328081Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:39:45.328541Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:39:50.328971Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:39:55.329276Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:40:00.329535Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:40:05.329845Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:40:10.330113Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:40:15.330326Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:40:20.330601Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:40:25.330856Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:40:30.331102Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:40:35.331392Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:40:40.331675Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:40:45.331937Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:40:50.332179Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:40:55.332438Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:41:00.332713Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:41:05.332981Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:41:10.333312Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:41:15.333601Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:41:20.333938Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:41:25.334238Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:41:30.334460Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:41:35.334695Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:41:40.334937Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:41:45.335188Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:41:50.335428Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:41:55.335731Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:42:00.336007Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:42:05.336278Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:42:10.336540Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:42:15.336847Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:42:20.337127Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:42:25.337488Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:42:30.337834Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:42:35.338136Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:42:40.338445Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:42:45.338803Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:42:50.339086Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:42:55.339309Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:43:00.339549Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:43:05.339814Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:43:10.340067Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:43:15.340318Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:43:20.340661Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:43:25.341099Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:43:30.341322Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:43:35.341599Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:43:40.341873Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:43:45.342300Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:43:50.342547Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:43:55.342871Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:44:00.343132Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:44:05.343428Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:44:10.343732Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:44:15.344051Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:44:20.344323Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:44:25.344608Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:44:30.344889Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:44:35.345166Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:44:40.345448Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:44:45.345687Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:44:50.345955Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:44:55.346278Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:45:00.346555Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:45:05.346899Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:45:10.347148Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:45:15.347407Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:45:20.347638Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:45:25.347900Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:45:30.348179Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:45:35.348446Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:45:40.348719Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:45:45.348991Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:45:50.349255Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:45:55.349831Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:46:00.350354Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:46:05.350679Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:46:10.351202Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:46:15.351530Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:46:20.351972Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:46:25.352383Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:46:30.352765Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:46:35.353186Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:46:40.353555Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:46:45.353958Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:46:50.354524Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:46:55.354950Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:47:00.355345Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:47:05.355734Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:47:10.356093Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:47:15.356469Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:47:20.357087Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:47:25.357546Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:47:30.358038Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:47:35.358456Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:47:40.358776Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:47:45.359318Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:47:50.359822Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:47:55.360295Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:48:00.360654Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:48:05.361028Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:48:10.361633Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:48:15.362083Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:48:20.362576Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:48:25.363051Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:48:30.363577Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:48:35.363925Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:48:40.364284Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:48:45.364681Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:48:50.365100Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:48:55.365591Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:49:00.365954Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:49:05.366346Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:49:10.366729Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:49:15.367294Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:49:20.367705Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:49:25.368113Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:49:30.368502Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:49:35.368989Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:49:40.369388Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:49:45.369703Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:49:50.370018Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:49:55.370324Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:50:00.370590Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:50:05.370840Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:50:10.371142Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:50:15.371623Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:50:20.371995Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:50:25.372280Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:50:30.372550Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:50:35.372818Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:50:40.373084Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:50:45.373345Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:50:50.373624Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:50:55.373888Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:51:00.374150Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:51:05.374450Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:51:10.374707Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:51:15.375069Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:51:20.375394Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:51:25.375694Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:51:30.375951Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:51:35.376182Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:51:40.376423Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:51:45.376725Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:51:50.377009Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:51:55.377270Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:52:00.377509Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:52:05.377757Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:52:10.378018Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:52:15.378285Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:52:20.378572Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:52:25.378852Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:52:30.379139Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:52:35.379425Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:52:40.379654Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:52:45.379899Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:52:50.380137Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:52:55.380398Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:53:00.380622Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:53:05.380860Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:53:10.381162Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:53:15.381493Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:53:20.381793Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:53:25.382071Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:53:30.382312Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:53:35.382572Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:53:40.382857Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:53:45.383142Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:53:50.383418Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:53:55.383721Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:54:00.383997Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:54:05.384302Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:54:10.384572Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:54:15.384886Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:54:20.385196Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:54:25.385466Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:54:30.385737Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:54:35.386018Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:54:40.386350Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:54:45.386598Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:54:50.386854Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:54:55.387131Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:55:00.387369Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:55:05.387649Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:55:10.387947Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:55:15.388243Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:55:20.388494Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:55:25.388787Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:55:30.389074Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:55:35.389329Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:55:40.389635Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:55:45.389881Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:55:50.390151Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:55:55.390561Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:56:00.390917Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:56:05.391239Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:56:10.391566Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:56:15.391846Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:56:20.392087Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:56:25.392803Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:56:30.393072Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:56:35.393328Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:56:40.393594Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:56:45.393929Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:56:50.394245Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:56:55.394509Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:57:00.394793Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:57:05.395044Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:57:10.395290Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:57:15.395561Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:57:20.395806Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:57:25.396026Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:57:30.396264Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:57:35.396503Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:57:40.396762Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:57:45.397002Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:57:50.397281Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:57:55.397549Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:58:00.397835Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:58:05.398210Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:58:10.398478Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:58:15.398711Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:58:20.399039Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:58:25.399346Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:58:30.399686Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:58:35.399932Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:58:40.400200Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:58:45.400545Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:58:50.400835Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:58:55.401092Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:59:00.401393Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:59:05.401643Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:59:10.401921Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:59:15.402269Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:59:20.402502Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:59:25.402744Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:59:30.402982Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:59:35.403267Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:59:40.403793Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:59:45.404119Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:59:50.404365Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T14:59:55.404646Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" diff --git a/contextforge-gateway-rs.log.2026-05-29-15 b/contextforge-gateway-rs.log.2026-05-29-15 deleted file mode 100644 index 12352f1e..00000000 --- a/contextforge-gateway-rs.log.2026-05-29-15 +++ /dev/null @@ -1,816 +0,0 @@ -2026-05-29T15:00:00.404931Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:00:05.405184Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:00:10.405437Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:00:15.405669Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:00:20.405925Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:00:25.406253Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:00:30.406530Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:00:35.406769Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:00:40.406993Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:00:45.407237Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:00:50.407475Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:00:55.407767Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:01:00.408108Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:01:05.408343Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:01:10.408634Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:01:15.408967Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:01:20.409220Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:01:25.409498Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:01:30.409767Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:01:35.410010Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:01:40.410305Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:01:45.410549Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:01:50.410788Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:01:55.411017Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:02:00.411339Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:02:05.411605Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:02:10.411861Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:02:15.412118Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:02:20.412395Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:02:25.412657Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:02:30.412925Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:02:35.413191Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:02:40.413448Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:02:45.413736Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:02:50.413984Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:02:55.414250Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:03:00.414501Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:03:05.414763Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:03:10.415021Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:03:15.415315Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:03:20.415597Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:03:25.415866Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:03:30.416079Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:03:35.416394Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:03:40.416691Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:03:45.416960Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:03:50.417232Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:03:55.417546Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:04:00.417801Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:04:05.418122Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:04:10.418386Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:04:15.418653Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:04:20.418874Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:04:25.419102Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:04:30.419353Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:04:35.419613Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:04:40.419858Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:04:45.420105Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:04:50.420378Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:04:55.420661Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:05:00.420914Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:05:05.421165Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:05:10.421409Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:05:15.421656Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:05:20.421927Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:05:25.422245Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:05:30.422479Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:05:35.422746Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:05:40.423069Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:05:45.423332Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:05:50.423587Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:05:55.423867Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:06:00.424133Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:06:05.424352Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:06:10.424612Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:06:15.424975Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:06:20.425278Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:06:25.425570Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:06:30.425862Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:06:35.426217Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:06:40.426462Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:06:45.426709Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:06:50.427000Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:06:55.427264Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:07:00.427551Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:07:05.427827Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:07:10.428083Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:07:15.428322Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:07:20.428574Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:07:25.428835Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:07:30.429086Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:07:35.429356Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:07:40.429648Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:07:45.429987Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:07:50.430291Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:07:55.430587Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:08:00.430857Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:08:05.431130Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:08:10.431447Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:08:15.431702Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:08:20.431967Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:08:25.432290Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:08:30.432569Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:08:35.432819Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:08:40.433050Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:08:45.433268Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:08:50.433512Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:08:55.433761Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:09:00.434051Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:09:05.434409Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:09:10.434712Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:09:15.434994Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:09:20.435243Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:09:25.435475Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:09:30.435720Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:09:35.436007Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:09:40.436289Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:09:45.436578Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:09:50.436854Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:09:55.437116Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:10:00.437388Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:10:05.437647Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:10:10.437928Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:10:15.438221Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:10:20.438469Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:10:25.438784Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:10:30.439056Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:10:35.439321Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:10:40.439607Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:10:45.439913Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:10:50.440170Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:10:55.440438Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:11:00.440672Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:11:05.440933Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:11:10.441185Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:11:15.441424Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:11:20.441701Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:11:25.441947Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:11:30.442258Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:11:35.442469Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:11:40.442697Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:11:45.442917Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:11:50.443179Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:11:55.443410Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:12:00.443657Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:12:05.443931Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:12:10.444163Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:12:15.444483Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:12:20.444755Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:12:25.445040Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:12:30.445291Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:12:35.445584Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:12:40.445846Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:12:45.446114Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:12:50.446440Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:12:55.446668Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:13:00.446928Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:13:05.447159Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:13:10.447405Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:13:15.447615Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:13:20.447889Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:13:25.448197Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:13:30.448772Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:13:35.449036Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:13:40.449346Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:13:45.449576Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:13:50.449842Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:13:55.450102Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:14:00.450340Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:14:05.450656Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:14:10.450906Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:14:15.451161Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:14:20.451391Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:14:25.451666Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:14:30.451921Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:14:35.452201Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:14:40.452496Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:14:45.452770Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:14:50.452999Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:14:55.453261Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:15:00.453532Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:15:05.453778Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:15:10.454015Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:15:15.454309Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:15:20.454550Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:15:25.454804Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:15:30.455090Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:15:35.455386Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:15:40.455694Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:15:45.455956Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:15:50.456250Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:15:55.456498Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:16:00.456762Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:16:05.457023Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:16:10.457344Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:16:15.457640Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:16:20.457950Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:16:25.458285Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:16:30.458537Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:16:35.458860Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:16:40.459165Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:16:45.459488Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:16:50.459756Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:16:55.460149Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:17:00.460547Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:17:05.460925Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:17:10.461169Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:17:15.461452Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:17:20.461702Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:17:25.461920Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:17:30.462165Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:17:35.462420Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:17:40.462664Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:17:45.462939Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:17:50.463181Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:17:55.463477Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:18:00.463706Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:18:05.463968Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:18:10.464289Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:18:15.464510Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:18:20.464753Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:18:25.465080Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:18:30.465413Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:18:35.465666Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:18:40.465946Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:18:45.466260Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:18:50.466526Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:18:55.466803Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:19:00.467047Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:19:05.467414Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:19:10.467685Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:19:15.467977Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:19:20.468247Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:19:25.468494Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:19:30.468732Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:19:35.469000Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:19:40.469274Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:19:45.469562Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:19:50.469847Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:19:55.470093Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:20:00.470402Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:20:05.470648Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:20:10.470973Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:20:15.471259Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:20:20.471607Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:20:25.471958Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:20:30.472227Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:20:35.472481Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:20:40.472733Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:20:45.472990Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:20:50.473285Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:20:55.473534Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:21:00.473905Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:21:05.474210Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:21:10.474448Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:21:15.474712Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:21:20.474984Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:21:25.475246Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:21:30.475555Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:21:35.475877Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:21:40.476109Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:21:45.476399Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:21:50.476645Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:21:55.477042Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:22:00.477324Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:22:05.477578Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:22:10.477845Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:22:15.478131Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:22:20.478463Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:22:25.478759Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:22:30.479107Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:22:35.479470Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:22:40.479778Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:22:45.480059Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:22:50.480373Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:22:55.480657Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:23:00.481067Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:23:05.481465Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:23:10.481749Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:23:15.481988Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:23:20.482244Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:23:25.482481Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:23:30.482744Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:23:35.483012Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:23:40.483257Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:23:45.483492Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:23:50.483767Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:23:55.484091Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:24:00.484392Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:24:05.484652Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:24:10.484932Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:24:15.485321Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:24:20.485561Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:24:25.485799Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:24:30.486115Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:24:35.486588Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:24:40.487067Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:24:45.487338Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:24:50.487586Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:24:55.487819Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:00.488049Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:05.488352Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:10.488592Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:15.488872Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:20.489138Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:25.489476Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:30.489702Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:35.489945Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:40.490222Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:42.760083Z DEBUG rustls::webpki::anchors: add_parsable_certificates processed 146 valid and 0 invalid certs -2026-05-29T15:25:42.760110Z DEBUG rustls_platform_verifier::verification::others: Loaded 146 CA root certificates from the system -2026-05-29T15:25:42.760299Z DEBUG opentelemetry_sdk: name="MeterProvider.NewMeterCreated" meter_name="axum-otel-metrics" -2026-05-29T15:25:42.760349Z DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="http.server.request.duration" cardinality_limit=2000 -2026-05-29T15:25:42.760379Z DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="http.server.request.body.size" cardinality_limit=2000 -2026-05-29T15:25:42.760386Z DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="http.server.response.body.size" cardinality_limit=2000 -2026-05-29T15:25:42.760395Z DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="http.server.active_requests" cardinality_limit=2000 -2026-05-29T15:25:42.760403Z INFO contextforge_gateway_rs_lib::transports::tcp: Starting TCP listener at 0.0.0.0:8001 -2026-05-29T15:25:45.490457Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:47.749294Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:50.490695Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:52.749442Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:55.490933Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:25:57.749610Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:00.491274Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:02.749748Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:05.491594Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:07.749940Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:10.491855Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:12.749921Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:26:12.749970Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:26:12.750032Z DEBUG opentelemetry_sdk: name="NoMetricsCollected" -2026-05-29T15:26:12.750044Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:26:12.750056Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29999 -2026-05-29T15:26:12.750115Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:15.492108Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:17.750272Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:20.492405Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:22.750440Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:25.492680Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:27.750616Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:30.492927Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:32.750799Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:35.493175Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:37.750949Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:40.493517Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:42.749972Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:26:42.750012Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:26:42.750042Z DEBUG opentelemetry_sdk: name="NoMetricsCollected" -2026-05-29T15:26:42.750046Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:26:42.750051Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29999 -2026-05-29T15:26:42.751075Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:45.493749Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:47.751219Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:50.493983Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:52.751375Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:55.494286Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:26:57.751573Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:00.494520Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:02.751745Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:05.494840Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:07.751890Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:10.495094Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:12.750091Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:27:12.750121Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:27:12.750133Z DEBUG opentelemetry_sdk: name="NoMetricsCollected" -2026-05-29T15:27:12.750137Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:27:12.750141Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29999 -2026-05-29T15:27:12.752142Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:15.495382Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:17.752316Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:20.495666Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:22.752485Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:25.495914Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:27.752661Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:30.496180Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:32.752906Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:37.753147Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:42.750209Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:27:42.750240Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:27:42.750252Z DEBUG opentelemetry_sdk: name="NoMetricsCollected" -2026-05-29T15:27:42.750257Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:27:42.750262Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29999 -2026-05-29T15:27:42.753293Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:47.753449Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:51.863657Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:27:51.863706Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:27:51.870631Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:27:51.870663Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:27:51.875640Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:27:51.875671Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:27:51.881050Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:27:51.881167Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:27:51.885956Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:27:51.885981Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:27:51.890656Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:27:51.890696Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:27:51.896424Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:27:51.896453Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:27:51.901721Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:27:51.901749Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:27:51.906282Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:27:51.906308Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:27:51.910533Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:27:51.910556Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:27:52.753634Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:27:57.753771Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:28:02.753972Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:28:07.754151Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:28:12.750253Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:28:12.750277Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:28:12.750328Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:28:12.750432Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:28:12.750450Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:28:12.750803Z DEBUG reqwest::connect: starting new connection: http://127.0.0.1:4318/ -2026-05-29T15:28:12.750892Z DEBUG hyper_util::client::legacy::connect::http: connecting to 127.0.0.1:4318 -2026-05-29T15:28:12.751138Z DEBUG hyper_util::client::legacy::connect::http: connected to 127.0.0.1:4318 -2026-05-29T15:28:12.754270Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:28:12.759201Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:28:12.759402Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:28:12.759421Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:28:12.759427Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29990 -2026-05-29T15:28:17.754396Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:28:22.754575Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:28:27.754748Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:28:32.754958Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:28:37.755179Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:28:42.750336Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:28:42.750372Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:28:42.750404Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:28:42.750438Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:28:42.750442Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:28:42.750571Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:28:42.751973Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:28:42.752115Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:28:42.752148Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:28:42.752155Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:28:42.755303Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:28:47.755463Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:28:52.755604Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:28:57.755768Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:29:02.755937Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:29:07.756082Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:29:12.750410Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:29:12.750433Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:29:12.750456Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:29:12.750489Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:29:12.750503Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:29:12.750594Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:29:12.751767Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:29:12.751875Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:29:12.751908Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:29:12.751916Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:29:12.756198Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:29:17.756361Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:29:22.756556Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:29:27.756746Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:29:32.756961Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:29:37.757146Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:29:42.750505Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:29:42.750537Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:29:42.750566Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:29:42.750598Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:29:42.750602Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:29:42.750716Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:29:42.751801Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:29:42.751929Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:29:42.751949Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:29:42.751955Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:29:42.757274Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:29:47.757432Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:29:52.757612Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:29:57.757770Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:30:02.757963Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:30:07.758147Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:30:12.750609Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:30:12.750635Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:30:12.750660Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:30:12.750695Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:30:12.750698Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:30:12.750805Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:30:12.751603Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:30:12.751833Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:30:12.751923Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:30:12.752004Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:30:12.758263Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:30:17.758434Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:30:22.758608Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:30:27.759018Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:30:32.759295Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:30:37.759445Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:30:42.750823Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:30:42.750879Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:30:42.750908Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:30:42.750950Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:30:42.750969Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:30:42.751120Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:30:42.752368Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:30:42.752481Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:30:42.752510Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:30:42.752515Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:30:42.759619Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:30:47.759804Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:30:52.759971Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:30:57.760181Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:31:02.760328Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:31:07.760480Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:31:12.750916Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:31:12.750942Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:31:12.750979Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:31:12.751009Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:31:12.751024Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:31:12.751120Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:31:12.752278Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:31:12.752362Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:31:12.752382Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:31:12.752387Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:31:12.760647Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:31:17.760857Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:31:22.761033Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:31:27.761203Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:31:32.761360Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:31:37.761514Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:31:42.751076Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:31:42.751106Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:31:42.751130Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:31:42.751169Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:31:42.751173Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:31:42.751433Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:31:42.752474Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:31:42.752557Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:31:42.752564Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:31:42.752577Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:31:42.761642Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:31:47.761802Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:31:52.761949Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:31:57.762148Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:32:23.817222Z DEBUG rustls::webpki::anchors: add_parsable_certificates processed 146 valid and 0 invalid certs -2026-05-29T15:32:23.817232Z DEBUG rustls_platform_verifier::verification::others: Loaded 146 CA root certificates from the system -2026-05-29T15:32:23.817387Z DEBUG opentelemetry_sdk: name="MeterProvider.NewMeterCreated" meter_name="axum-otel-metrics" -2026-05-29T15:32:23.817427Z DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="http.server.request.duration" cardinality_limit=2000 -2026-05-29T15:32:23.817486Z DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="http.server.request.body.size" cardinality_limit=2000 -2026-05-29T15:32:23.817515Z DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="http.server.response.body.size" cardinality_limit=2000 -2026-05-29T15:32:23.817531Z DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="http.server.active_requests" cardinality_limit=2000 -2026-05-29T15:32:23.817542Z INFO contextforge_gateway_rs_lib::transports::tcp: Starting TCP listener at 0.0.0.0:8001 -2026-05-29T15:32:28.809258Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:32:33.809437Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:32:38.809585Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:32:43.809730Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:32:48.809968Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:32:53.809740Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:32:53.809766Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:32:53.809787Z DEBUG opentelemetry_sdk: name="NoMetricsCollected" -2026-05-29T15:32:53.809792Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:32:53.809798Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29999 -2026-05-29T15:32:53.810081Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:32:58.810244Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:33:01.606563Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:33:01.606612Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:33:01.612286Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:33:01.612327Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:33:01.619096Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:33:01.619152Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:33:01.625276Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:33:01.625326Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:33:01.630711Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:33:01.630743Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:33:01.635551Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:33:01.635580Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:33:01.640687Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:33:01.640722Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:33:01.645937Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:33:01.645969Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:33:01.650330Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:33:01.650359Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:33:01.654627Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:33:01.654658Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:33:03.810422Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:33:03.810627Z DEBUG opentelemetry-otlp: name="HttpTracesClient.ExportStarted" -2026-05-29T15:33:03.810644Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:33:03.810836Z DEBUG reqwest::connect: starting new connection: http://127.0.0.1:3100/ -2026-05-29T15:33:03.810873Z DEBUG hyper_util::client::legacy::connect::http: connecting to 127.0.0.1:3100 -2026-05-29T15:33:03.811014Z DEBUG hyper_util::client::legacy::connect::http: connected to 127.0.0.1:3100 -2026-05-29T15:33:03.843036Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:3100) -2026-05-29T15:33:03.843144Z DEBUG opentelemetry-otlp: name="HttpTracesClient.ExportSucceeded" -2026-05-29T15:33:08.810584Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:33:13.810759Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:33:18.810905Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:33:23.809856Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:33:23.809887Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:33:23.809940Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:33:23.809998Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:33:23.810003Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:33:23.810164Z DEBUG reqwest::connect: starting new connection: http://127.0.0.1:4318/ -2026-05-29T15:33:23.810221Z DEBUG hyper_util::client::legacy::connect::http: connecting to 127.0.0.1:4318 -2026-05-29T15:33:23.810383Z DEBUG hyper_util::client::legacy::connect::http: connected to 127.0.0.1:4318 -2026-05-29T15:33:23.811003Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:33:23.811510Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:33:23.811590Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:33:23.811611Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:33:23.811615Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:33:28.811175Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:33:33.811347Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:33:38.811503Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:33:43.811671Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:33:48.811816Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:33:53.809975Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:33:53.810000Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:33:53.810053Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:33:53.810078Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:33:53.810081Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:33:53.810197Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:33:53.811076Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:33:53.811159Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:33:53.811190Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:33:53.811195Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:33:53.811944Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:33:58.812096Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:34:03.812262Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:34:08.812455Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:34:13.812620Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:44:15.750356Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadStarted" interval_in_millisecs=30000 -2026-05-29T15:44:15.750393Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=30000 -2026-05-29T15:44:15.758768Z DEBUG rustls::webpki::anchors: add_parsable_certificates processed 146 valid and 0 invalid certs -2026-05-29T15:44:15.758802Z DEBUG rustls_platform_verifier::verification::others: Loaded 146 CA root certificates from the system -2026-05-29T15:44:15.759106Z DEBUG opentelemetry_sdk: name="MeterProvider.NewMeterCreated" meter_name="axum-otel-metrics" -2026-05-29T15:44:15.759152Z DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="http.server.request.duration" cardinality_limit=2000 -2026-05-29T15:44:15.759164Z DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="http.server.request.body.size" cardinality_limit=2000 -2026-05-29T15:44:15.759174Z DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="http.server.response.body.size" cardinality_limit=2000 -2026-05-29T15:44:15.759190Z DEBUG opentelemetry_sdk: name="Metrics.InstrumentCreated" instrument_name="http.server.active_requests" cardinality_limit=2000 -2026-05-29T15:44:15.759211Z INFO contextforge_gateway_rs_lib::transports::tcp: Starting TCP listener at 0.0.0.0:8001 -2026-05-29T15:44:20.749706Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:44:25.750033Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:44:30.750210Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:44:31.243419Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:44:31.243473Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:44:31.247714Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:44:31.247741Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:44:31.251841Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:44:31.251899Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:44:31.257149Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:44:31.257180Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:44:31.261637Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:44:31.261665Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:44:31.266026Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:44:31.266058Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:44:31.270625Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:44:31.270726Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:44:31.275519Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:44:31.275548Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:44:31.279661Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:44:31.279685Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:44:31.283806Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:44:31.283839Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:44:32.506225Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:44:32.506326Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:44:35.750358Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:44:35.750552Z DEBUG opentelemetry-otlp: name="HttpTracesClient.ExportStarted" -2026-05-29T15:44:35.750568Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:44:35.750745Z DEBUG reqwest::connect: starting new connection: http://127.0.0.1:3100/ -2026-05-29T15:44:35.750784Z DEBUG hyper_util::client::legacy::connect::http: connecting to 127.0.0.1:3100 -2026-05-29T15:44:35.750912Z DEBUG hyper_util::client::legacy::connect::http: connected to 127.0.0.1:3100 -2026-05-29T15:44:35.779360Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:3100) -2026-05-29T15:44:35.779468Z DEBUG opentelemetry-otlp: name="HttpTracesClient.ExportSucceeded" -2026-05-29T15:44:36.366891Z DEBUG tower_http::trace::on_request: started processing request -2026-05-29T15:44:36.366934Z DEBUG tower_http::trace::on_response: finished processing request latency=0 ms status=404 -2026-05-29T15:44:40.750565Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:44:40.750659Z DEBUG opentelemetry-otlp: name="HttpTracesClient.ExportStarted" -2026-05-29T15:44:40.750665Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:44:40.750795Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:3100) -2026-05-29T15:44:40.775587Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:3100) -2026-05-29T15:44:40.775690Z DEBUG opentelemetry-otlp: name="HttpTracesClient.ExportSucceeded" -2026-05-29T15:44:45.750508Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:44:45.750564Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:44:45.750598Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:44:45.750660Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:44:45.750664Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:44:45.750870Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:44:45.751011Z DEBUG reqwest::connect: starting new connection: http://127.0.0.1:4318/ -2026-05-29T15:44:45.751035Z DEBUG hyper_util::client::legacy::connect::http: connecting to 127.0.0.1:4318 -2026-05-29T15:44:45.751172Z DEBUG hyper_util::client::legacy::connect::http: connected to 127.0.0.1:4318 -2026-05-29T15:44:45.752208Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:44:45.752428Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:44:45.752484Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:44:45.752497Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29997 -2026-05-29T15:44:50.750955Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:44:55.751275Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:45:00.751458Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:45:05.751638Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:45:10.751795Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:45:15.750657Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:45:15.750681Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:45:15.750704Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:45:15.750727Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:45:15.750729Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:45:15.750860Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:45:15.751708Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:45:15.751776Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:45:15.751807Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:45:15.751821Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:45:15.751897Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:45:20.752035Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:45:25.752211Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:45:30.752369Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:45:35.752499Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:45:40.752631Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:45:45.750761Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:45:45.750787Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:45:45.750810Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:45:45.750843Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:45:45.750857Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:45:45.750971Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:45:45.751931Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:45:45.752089Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:45:45.752123Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:45:45.752131Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:45:45.752730Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:45:50.752875Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:45:55.753102Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:46:00.753358Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:46:05.753569Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:46:10.753760Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:46:15.750860Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:46:15.750894Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:46:15.750917Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:46:15.750940Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:46:15.750943Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:46:15.751073Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:46:15.752203Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:46:15.752275Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:46:15.752282Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:46:15.752286Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:46:15.753908Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:46:20.754076Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:46:25.754271Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:46:30.754405Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:46:35.754550Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:46:40.754788Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:46:45.750975Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:46:45.751008Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:46:45.751034Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:46:45.751073Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:46:45.751077Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:46:45.751267Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:46:45.752240Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:46:45.752352Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:46:45.752359Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:46:45.752364Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:46:45.754905Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:46:50.755052Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:46:55.755333Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:47:00.755530Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:47:05.755711Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:47:10.755872Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:47:15.751100Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:47:15.751132Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:47:15.751157Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:47:15.751186Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:47:15.751202Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:47:15.751353Z DEBUG reqwest::connect: starting new connection: http://127.0.0.1:4318/ -2026-05-29T15:47:15.751388Z DEBUG hyper_util::client::legacy::connect::http: connecting to 127.0.0.1:4318 -2026-05-29T15:47:15.751541Z DEBUG hyper_util::client::legacy::connect::http: connected to 127.0.0.1:4318 -2026-05-29T15:47:15.752829Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:47:15.752905Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:47:15.752926Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:47:15.752931Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:47:15.756074Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:47:20.756295Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:47:25.756476Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:47:30.756684Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:47:35.756848Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:47:40.757006Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:47:45.751237Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:47:45.751264Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:47:45.751289Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:47:45.751323Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:47:45.751326Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:47:45.751452Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:47:45.752686Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:47:45.752778Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:47:45.752797Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:47:45.752802Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:47:45.757193Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:47:50.757379Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:47:55.757574Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:48:00.757722Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:48:05.757952Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:48:10.758167Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:48:15.751314Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:48:15.751341Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:48:15.751366Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:48:15.751393Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:48:15.751410Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:48:15.751578Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:48:15.752690Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:48:15.752790Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:48:15.752808Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:48:15.752824Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:48:15.758290Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:48:20.758445Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:48:25.758610Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:48:30.758796Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:48:35.758955Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:48:40.759104Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:48:45.751437Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadExportingDueToTimer" -2026-05-29T15:48:45.751478Z DEBUG opentelemetry_sdk: name="MeterProviderInvokingObservableCallbacks" count=0 -2026-05-29T15:48:45.751518Z DEBUG opentelemetry_sdk: name="PeriodicReaderMetricsCollected" count=4 time_taken_in_millis=0 -2026-05-29T15:48:45.751556Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportStarted" -2026-05-29T15:48:45.751562Z DEBUG opentelemetry-http: name="ReqwestBlockingClient.Send" -2026-05-29T15:48:45.751692Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:48:45.753111Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:4318) -2026-05-29T15:48:45.753268Z DEBUG opentelemetry-otlp: name="HttpMetricsClient.ExportSucceeded" -2026-05-29T15:48:45.753311Z DEBUG opentelemetry_sdk: name="PeriodReaderInvokedExport" export_result="Ok(())" -2026-05-29T15:48:45.753320Z DEBUG opentelemetry_sdk: name="PeriodReaderThreadLoopAlive" Next export will happen after interval, unless flush or shutdown is triggered. interval_in_millisecs=29998 -2026-05-29T15:48:45.759235Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:48:50.759391Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" -2026-05-29T15:48:55.759578Z DEBUG opentelemetry_sdk: name="BatchSpanProcessor.ExportingDueToTimer" From 7d132032586e1a5f4f3e1c32e07dd027ed7c00a5 Mon Sep 17 00:00:00 2001 From: Madhu Mohan Jaishankar Date: Tue, 11 Aug 2026 12:26:57 +0100 Subject: [PATCH 4/7] fix: register prompt hooks in CmfPluginFactory and round-trip full prompt messages through CMF Signed-off-by: Madhu Mohan Jaishankar --- .../contextforge-data-plane-cpex/src/cmf.rs | 249 +++++++++++++++--- .../src/factory.rs | 11 +- .../src/handle.rs | 70 ++++- .../src/pipeline.rs | 6 +- .../src/runtime.rs | 8 +- .../tests/gateway_plugins.rs | 79 +++++- .../tests/support/mod.rs | 12 +- .../tests/support/plugin.rs | 93 ++++--- .../tests/support/plugin_gateway.rs | 46 +++- .../tests/support/runtime.rs | 7 +- .../tests/support/tool.rs | 7 + 11 files changed, 489 insertions(+), 99 deletions(-) diff --git a/crates/contextforge-data-plane-cpex/src/cmf.rs b/crates/contextforge-data-plane-cpex/src/cmf.rs index 9a392527..8dc6ffde 100644 --- a/crates/contextforge-data-plane-cpex/src/cmf.rs +++ b/crates/contextforge-data-plane-cpex/src/cmf.rs @@ -1,7 +1,13 @@ +use std::collections::HashMap; + use cpex::cpex_core::cmf::{ - ContentPart, Message, MessagePayload, PromptRequest, PromptResult, Role, ToolCall, ToolResult, + AudioSource, ContentPart, ImageSource, Message, MessagePayload, PromptRequest, PromptResult, + Resource as CmfResource, ResourceReference, ResourceType, Role, ToolCall, ToolResult, +}; +use rmcp::model::{ + CallToolRequestParams, CallToolResult, ContentBlock, GetPromptRequestParams, GetPromptResult, PromptMessage, + Resource as McpResource, ResourceContents, Role as McpRole, }; -use rmcp::model::{CallToolRequestParams, CallToolResult, ContentBlock, GetPromptRequestParams, GetPromptResult}; use serde_json::{Map, Value}; pub(crate) fn tool_call_payload( @@ -148,66 +154,239 @@ pub(crate) fn prompt_result_payload( prompt_name: &str, prompt_request_id: &str, ) -> MessagePayload { - let mut content = vec![ContentPart::PromptResult { - content: PromptResult { - prompt_request_id: prompt_request_id.to_owned(), - prompt_name: prompt_name.to_owned(), - messages: Vec::new(), - content: None, - is_error: false, - error_message: None, - }, - }]; - content.extend( - response - .messages - .iter() - .filter_map(|message| message.content.as_text()) - .map(|text| ContentPart::Text { text: text.text.clone() }), - ); + let messages = + response.messages.iter().map(|message| cmf_prompt_message(message, prompt_request_id)).collect::>(); MessagePayload { - message: Message { schema_version: "2.0".to_owned(), role: Role::Assistant, content, channel: None }, + message: Message { + schema_version: "2.0".to_owned(), + role: Role::Assistant, + content: vec![ContentPart::PromptResult { + content: PromptResult { + prompt_request_id: prompt_request_id.to_owned(), + prompt_name: prompt_name.to_owned(), + messages, + content: None, + is_error: false, + error_message: None, + }, + }], + channel: None, + }, } } +/// `None` means refuse: falling back to the backend's original would undo a plugin's redaction. pub(crate) fn prompt_result_response( mut original: GetPromptResult, payload: &MessagePayload, ) -> Option { - let mut texts = payload.message.content.iter().filter_map(|part| match part { - ContentPart::Text { text } => Some(text), - _ => None, - }); + let results = payload.message.get_prompt_results(); + let result = results.first()?; + if result.messages.len() != original.messages.len() { + return None; + } - for message in &mut original.messages { - if message.content.as_text().is_none() { + for (message, edited) in original.messages.iter_mut().zip(&result.messages) { + let projected = cmf_prompt_message(message, &result.prompt_request_id); + if serde_json::to_value(&projected).ok()? == serde_json::to_value(edited).ok()? { continue; } - message.content = ContentBlock::text(texts.next()?.clone()); + *message = mcp_prompt_message(edited)?; } - if texts.next().is_some() { - return None; - } Some(original) } +fn cmf_prompt_message(message: &PromptMessage, prompt_request_id: &str) -> Message { + Message { + schema_version: "2.0".to_owned(), + role: match message.role { + McpRole::Assistant => Role::Assistant, + McpRole::User => Role::User, + }, + content: cmf_content_part(&message.content, prompt_request_id).into_iter().collect(), + channel: None, + } +} + +fn cmf_content_part(block: &ContentBlock, prompt_request_id: &str) -> Option { + let part = match block { + ContentBlock::Text(text) => ContentPart::Text { text: text.text.clone() }, + ContentBlock::Image(image) => ContentPart::Image { + content: ImageSource { + source_type: "base64".to_owned(), + data: image.data.clone(), + media_type: Some(image.mime_type.clone()), + }, + }, + ContentBlock::Audio(audio) => ContentPart::Audio { + content: AudioSource { + source_type: "base64".to_owned(), + data: audio.data.clone(), + media_type: Some(audio.mime_type.clone()), + duration_ms: None, + }, + }, + ContentBlock::Resource(resource) => { + let (uri, mime_type, content) = match &resource.resource { + ResourceContents::TextResourceContents { uri, mime_type, text, .. } => { + (uri.clone(), mime_type.clone(), Some(text.clone())) + }, + ResourceContents::BlobResourceContents { uri, mime_type, .. } => (uri.clone(), mime_type.clone(), None), + _ => return None, + }; + ContentPart::Resource { + content: CmfResource { + resource_request_id: prompt_request_id.to_owned(), + uri, + name: None, + description: None, + resource_type: ResourceType::Uri, + content, + blob: None, + mime_type, + size_bytes: None, + annotations: HashMap::new(), + version: None, + }, + } + }, + ContentBlock::ResourceLink(link) => ContentPart::ResourceRef { + content: ResourceReference { + resource_request_id: prompt_request_id.to_owned(), + uri: link.uri.clone(), + name: Some(link.name.clone()), + resource_type: ResourceType::Uri, + range_start: None, + range_end: None, + selector: None, + }, + }, + _ => return None, + }; + + Some(part) +} + +fn mcp_prompt_message(message: &Message) -> Option { + let role = match message.role { + Role::Assistant => McpRole::Assistant, + Role::User => McpRole::User, + _ => return None, + }; + + let [part] = message.content.as_slice() else { return None }; + let content = match part { + ContentPart::Text { text } => ContentBlock::text(text.clone()), + ContentPart::Image { content } => { + ContentBlock::image(content.data.clone(), content.media_type.clone().unwrap_or_default()) + }, + ContentPart::Audio { content } => { + ContentBlock::audio(content.data.clone(), content.media_type.clone().unwrap_or_default()) + }, + ContentPart::Resource { content } => ContentBlock::resource(ResourceContents::TextResourceContents { + uri: content.uri.clone(), + mime_type: content.mime_type.clone(), + text: content.content.clone()?, + meta: None, + }), + ContentPart::ResourceRef { content } => { + ContentBlock::ResourceLink(McpResource::new(content.uri.clone(), content.name.clone().unwrap_or_default())) + }, + _ => return None, + }; + + Some(PromptMessage::new(role, content)) +} + #[cfg(test)] mod tests { - use rmcp::model::{PromptMessage, Role as McpRole}; - use super::*; + fn text_prompt() -> GetPromptResult { + GetPromptResult::new(vec![PromptMessage::new_text(McpRole::User, "review of weather")]) + } + + fn edited_messages(payload: &mut MessagePayload) -> &mut Vec { + payload + .message + .content + .iter_mut() + .find_map(|part| match part { + ContentPart::PromptResult { content } => Some(&mut content.messages), + _ => None, + }) + .expect("payload carries a prompt result") + } + + #[test] + fn prompt_result_response_rejects_added_message() { + let original = text_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let extra = edited_messages(&mut payload).first().cloned().expect("one message"); + edited_messages(&mut payload).push(extra); + + assert!(prompt_result_response(original, &payload).is_none()); + } + + #[test] + fn prompt_result_response_rejects_removed_message() { + let original = text_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + edited_messages(&mut payload).clear(); + + assert!(prompt_result_response(original, &payload).is_none()); + } + #[test] - fn prompt_result_response_rejects_added_text() { - let original = GetPromptResult::new(vec![PromptMessage::new_text(McpRole::User, "review of weather")]); + fn prompt_result_response_rejects_unmappable_role() { + let original = text_prompt(); let mut payload = prompt_result_payload(&original, "review", "prompt-1"); - payload.message.content.push(ContentPart::Text { text: "extra".to_owned() }); + edited_messages(&mut payload)[0].role = Role::System; assert!(prompt_result_response(original, &payload).is_none()); } + #[test] + fn prompt_result_response_preserves_unmodified_messages() { + let original = text_prompt(); + let payload = prompt_result_payload(&original, "review", "prompt-1"); + + let result = prompt_result_response(original.clone(), &payload).expect("unmodified payload applies"); + + assert_eq!( + serde_json::to_value(&original).expect("original serializes"), + serde_json::to_value(&result).expect("result serializes") + ); + } + + #[test] + fn prompt_result_response_round_trips_embedded_resource() { + let original = GetPromptResult::new(vec![PromptMessage::new( + McpRole::User, + ContentBlock::resource(ResourceContents::text("token=secret", "file:///app.env")), + )]); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + + let ContentPart::Resource { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("embedded resource reaches the plugin as a CMF resource part"); + }; + assert_eq!(Some("token=secret"), content.content.as_deref()); + content.content = Some("token=[REDACTED]".to_owned()); + + let result = prompt_result_response(original, &payload).expect("resource edit applies"); + + let ContentBlock::Resource(resource) = &result.messages[0].content else { + panic!("expected an embedded resource"); + }; + let ResourceContents::TextResourceContents { text, uri, .. } = &resource.resource else { + panic!("expected text resource contents"); + }; + assert_eq!("token=[REDACTED]", text); + assert_eq!("file:///app.env", uri); + } + #[test] fn tool_result_response_uses_cmf_error_flag_for_nested_mcp_result() { let original = CallToolResult::success(vec![ContentBlock::text("original")]); diff --git a/crates/contextforge-data-plane-cpex/src/factory.rs b/crates/contextforge-data-plane-cpex/src/factory.rs index a41c4f40..598d8a2e 100644 --- a/crates/contextforge-data-plane-cpex/src/factory.rs +++ b/crates/contextforge-data-plane-cpex/src/factory.rs @@ -1,4 +1,4 @@ -use std::{marker::PhantomData, sync::Arc}; +use std::sync::Arc; use cpex::cpex_core::{ cmf::CmfHook, @@ -10,13 +10,12 @@ use cpex::cpex_core::{ }; pub struct CmfPluginFactory

{ - build: fn(PluginConfig) -> P, - _plugin: PhantomData

, + build: Box P + Send + Sync>, } impl

CmfPluginFactory

{ - pub fn new(build: fn(PluginConfig) -> P) -> Self { - Self { build, _plugin: PhantomData } + pub fn new(build: impl Fn(PluginConfig) -> P + Send + Sync + 'static) -> Self { + Self { build: Box::new(build) } } } @@ -50,6 +49,8 @@ fn cmf_hook_name(hook: &str) -> Option<&'static str> { match hook { cmf_hook_names::TOOL_PRE_INVOKE => Some(cmf_hook_names::TOOL_PRE_INVOKE), cmf_hook_names::TOOL_POST_INVOKE => Some(cmf_hook_names::TOOL_POST_INVOKE), + cmf_hook_names::PROMPT_PRE_FETCH => Some(cmf_hook_names::PROMPT_PRE_FETCH), + cmf_hook_names::PROMPT_POST_FETCH => Some(cmf_hook_names::PROMPT_POST_FETCH), _ => None, } } diff --git a/crates/contextforge-data-plane-cpex/src/handle.rs b/crates/contextforge-data-plane-cpex/src/handle.rs index 828af917..eae5f182 100644 --- a/crates/contextforge-data-plane-cpex/src/handle.rs +++ b/crates/contextforge-data-plane-cpex/src/handle.rs @@ -361,13 +361,14 @@ mod tests { }; use crate::config::LoadedRuntimePluginConfig; - use crate::{CmfPluginFactory, ToolArgumentsUpdate}; + use crate::{CmfPluginFactory, PromptArgumentsUpdate, ToolArgumentsUpdate}; use super::*; const TEST_MISSING_CONTEXT_ERROR_CODE: i64 = -32003; const TEST_REWRITTEN_SUM_A: i64 = 10; const TEST_REWRITTEN_SUM_B: i64 = 20; + const TEST_REWRITTEN_PROMPT_TOPIC: &str = "rewritten-topic"; const TEST_SHUTDOWN_RETRY_COUNT: usize = 20; const TEST_SHUTDOWN_RETRY_INTERVAL: Duration = Duration::from_millis(10); const TEST_WATCHER_INTERVAL: Duration = Duration::from_millis(10); @@ -587,6 +588,15 @@ mod tests { ("b".to_owned(), json!(TEST_REWRITTEN_SUM_B)), ]); } + if let Some(ContentPart::PromptRequest { content }) = modified + .message + .content + .iter_mut() + .find(|part| matches!(part, ContentPart::PromptRequest { .. })) + { + content.arguments = + HashMap::from([("topic".to_owned(), json!(TEST_REWRITTEN_PROMPT_TOPIC))]); + } PluginResult::modify_payload(modified) }, PreBehavior::SetContext => { @@ -648,6 +658,11 @@ mod tests { .with_arguments(serde_json::Map::from_iter([("a".to_owned(), json!(a)), ("b".to_owned(), json!(b))])) } + fn review_request(topic: &str) -> GetPromptRequestParams { + GetPromptRequestParams::new("review") + .with_arguments(serde_json::Map::from_iter([("topic".to_owned(), json!(topic))])) + } + fn progress_event() -> ProgressNotificationParam { ProgressNotificationParam::new(ProgressToken(NumberOrString::String("stream-token".into())), 1.0) .with_message("step 1/2") @@ -786,6 +801,59 @@ mod tests { assert!(matches!(result.arguments, ToolArgumentsUpdate::Replace(Some(_)))); } + #[tokio::test(flavor = "multi_thread", worker_threads = 1)] + async fn generic_cmf_factory_registers_prompt_only_plugin() { + let config = config_document(json!({ + "plugins": [{ + "name": "generic-prompt", + "kind": "generic", + "hooks": [cmf_hook_names::PROMPT_PRE_FETCH] + }] + })); + let mut runtime = CpexRuntimeRegistry::with_config_store(Arc::new(MemoryConfigStore::with_config(config))); + runtime + .register_factory("generic", Box::new(CmfPluginFactory::new(TestPlugin::rewrite_from_config))) + .expect("test factory registers"); + runtime.initialize().await.expect("runtime initializes"); + + let result = runtime + .handle() + .before_get_prompt(&review_request("weather"), "review", "backend") + .await + .expect("prompt pre hook runs"); + + assert!( + matches!(result.arguments, PromptArgumentsUpdate::Replace(Some(_))), + "the prompt hook must actually run, not merely be accepted by config validation" + ); + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 1)] + async fn generic_cmf_factory_registers_mixed_tool_and_prompt_plugin() { + let config = config_document(json!({ + "plugins": [{ + "name": "generic-mixed", + "kind": "generic", + "hooks": [cmf_hook_names::TOOL_PRE_INVOKE, cmf_hook_names::PROMPT_PRE_FETCH] + }] + })); + let mut runtime = CpexRuntimeRegistry::with_config_store(Arc::new(MemoryConfigStore::with_config(config))); + runtime + .register_factory("generic", Box::new(CmfPluginFactory::new(TestPlugin::rewrite_from_config))) + .expect("test factory registers"); + runtime.initialize().await.expect("runtime initializes"); + + let tool = runtime.before_tool_call(&sum_request(1, 2), "sum", "backend").await.expect("tool pre hook runs"); + let prompt = runtime + .handle() + .before_get_prompt(&review_request("weather"), "review", "backend") + .await + .expect("prompt pre hook runs"); + + assert!(matches!(tool.arguments, ToolArgumentsUpdate::Replace(Some(_)))); + assert!(matches!(prompt.arguments, PromptArgumentsUpdate::Replace(Some(_)))); + } + #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn runtime_reload_replaces_and_clears_current_runtime() { let plugin = diff --git a/crates/contextforge-data-plane-cpex/src/pipeline.rs b/crates/contextforge-data-plane-cpex/src/pipeline.rs index 34569001..f34fbac1 100644 --- a/crates/contextforge-data-plane-cpex/src/pipeline.rs +++ b/crates/contextforge-data-plane-cpex/src/pipeline.rs @@ -108,16 +108,16 @@ where }) } -pub(crate) fn plugin_denied_error(result: PipelineResult) -> ErrorData { +pub(crate) fn plugin_denied_error(subject: &str, result: PipelineResult) -> ErrorData { let code = result .violation .and_then(|violation| { - warn!("Plugin denied tool call: code={} plugin={:?}", violation.code, violation.plugin_name); + warn!("Plugin denied {subject}: code={} plugin={:?}", violation.code, violation.plugin_name); violation.proto_error_code.and_then(|code| i32::try_from(code).ok()).map(ErrorCode) }) .unwrap_or(ErrorCode::INVALID_REQUEST); - ErrorData { code, message: "Plugin denied tool call".into(), data: None } + ErrorData { code, message: format!("Plugin denied {subject}").into(), data: None } } pub(crate) fn log_pipeline_errors(hook: &'static str, result: &PipelineResult) { diff --git a/crates/contextforge-data-plane-cpex/src/runtime.rs b/crates/contextforge-data-plane-cpex/src/runtime.rs index 1da1c11d..af2d8ecd 100644 --- a/crates/contextforge-data-plane-cpex/src/runtime.rs +++ b/crates/contextforge-data-plane-cpex/src/runtime.rs @@ -203,7 +203,7 @@ impl GatewayPluginRuntime { let original_payload = tool_call_payload(request, tool_name, backend_name, &tool_call_id); let pre_result = self.invoke_tool_pre(original_payload).await; if pre_result.is_denied() { - return Err(plugin_denied_error(pre_result)); + return Err(plugin_denied_error("tool call", pre_result)); } let arguments = effective_pre_args(request.arguments.as_ref(), &pre_result)?; @@ -255,7 +255,7 @@ impl GatewayPluginRuntime { let payload = prompt_request_payload(request, prompt_name, backend_name, &prompt_request_id); let pre_result = self.invoke_prompt_pre(payload).await; if pre_result.is_denied() { - return Err(plugin_denied_error(pre_result)); + return Err(plugin_denied_error("prompt", pre_result)); } let arguments = effective_pre_prompt_args(request.arguments.as_ref(), &pre_result)?; @@ -280,7 +280,7 @@ impl GatewayPluginRuntime { let payload = prompt_result_payload(&response, prompt_name, &state.prompt_request_id); let post_result = self.invoke_prompt_post(payload, Some(state.context_table.clone())).await; if post_result.is_denied() { - return Err(plugin_denied_error(post_result)); + return Err(plugin_denied_error("prompt", post_result)); } effective_post_prompt_result(response, &post_result) @@ -307,7 +307,7 @@ impl GatewayPluginRuntime { ) .await; if post_result.is_denied() { - return Err(plugin_denied_error(post_result)); + return Err(plugin_denied_error("tool call", post_result)); } state.context_table = post_result.context_table.clone(); diff --git a/crates/contextforge-data-plane-lib/tests/gateway_plugins.rs b/crates/contextforge-data-plane-lib/tests/gateway_plugins.rs index 0d873702..e0f7c596 100644 --- a/crates/contextforge-data-plane-lib/tests/gateway_plugins.rs +++ b/crates/contextforge-data-plane-lib/tests/gateway_plugins.rs @@ -11,17 +11,18 @@ use rmcp::{ model::{ CallToolRequestParams, CallToolResult, ClientCapabilities, ClientRequest, ContentBlock, ErrorCode, GetPromptRequestParams, GetPromptResult, Implementation, InitializeRequestParams, ProgressNotificationParam, - Request, ServerResult, + Request, ResourceContents, Role as McpRole, ServerResult, }, service::{NotificationContext, PeerRequestOptions, RequestHandle, RoleClient, RunningService}, }; use serde_json::{Map, Value, json}; use support::{ - POST_DENY_ERROR_CODE, PRE_DENY_ERROR_CODE, PromptBehavior, PromptTestPlugin, REWRITTEN_PROMPT_TEXT, + BACKEND_PROMPT_IMAGE, BACKEND_PROMPT_RESOURCE, POST_DENY_ERROR_CODE, PRE_DENY_ERROR_CODE, + PROMPT_POST_DENY_ERROR_CODE, PromptBehavior, PromptTestPlugin, REWRITTEN_PROMPT_RESOURCE, REWRITTEN_PROMPT_TEXT, REWRITTEN_PROMPT_TOPIC, REWRITTEN_SUM_A, REWRITTEN_SUM_B, RunningGateway, TEST_USER_ID, TestPlugin, error_code, - runtime_with_post, runtime_with_pre, runtime_with_pre_and_post, runtime_with_prompt_plugin, start_gateway, - start_gateway_with_json_backend_responses, sum_request, text, token, + error_parts, runtime_with_post, runtime_with_pre, runtime_with_pre_and_post, runtime_with_prompt_plugin, + start_gateway, start_gateway_with_events, start_gateway_with_json_backend_responses, sum_request, text, token, }; type Recorded = Arc>>; @@ -763,6 +764,76 @@ async fn prompt_post_hook_removing_rendered_text_fails_closed() { assert_eq!(ErrorCode::INTERNAL_ERROR, error_code(error)); } +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn prompt_post_hook_rewrites_multimodal_prompt_content() { + let plugin = Arc::new(PromptTestPlugin::new("prompt-multimodal", vec![cmf_hook_names::PROMPT_POST_FETCH])); + let runtime = runtime_with_prompt_plugin(plugin).await; + + let gateway = start_gateway(TEST_USER_ID, true, runtime).await; + let service = gateway.connect(TEST_USER_ID).await; + let request = GetPromptRequestParams::new("review_bundle") + .with_arguments(Map::from_iter([("topic".to_owned(), json!("weather"))])); + let result = service.get_prompt(request).await.expect("prompt is returned"); + + assert_eq!(3, result.messages.len()); + assert_eq!(REWRITTEN_PROMPT_TEXT, prompt_text(&result)); + + let ContentBlock::Resource(resource) = &result.messages[1].content else { + panic!("expected the embedded resource to survive as a resource"); + }; + let ResourceContents::TextResourceContents { text, uri, .. } = &resource.resource else { + panic!("expected text resource contents"); + }; + assert_eq!(REWRITTEN_PROMPT_RESOURCE, text, "the plugin's resource edit must reach the client"); + assert_ne!(BACKEND_PROMPT_RESOURCE, text); + assert_eq!("file:///app.env", uri, "identity the plugin did not touch is preserved"); + + let ContentBlock::Image(image) = &result.messages[2].content else { + panic!("expected the image to survive as an image"); + }; + assert_eq!(BACKEND_PROMPT_IMAGE, image.data, "untouched content passes through unchanged"); + assert_eq!(McpRole::Assistant, result.messages[2].role, "roles survive the round trip"); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn prompt_post_hook_denial_returns_plugin_error_code() { + let plugin = Arc::new( + PromptTestPlugin::new("prompt-post-deny", vec![cmf_hook_names::PROMPT_POST_FETCH]) + .with_behavior(PromptBehavior::Deny), + ); + let runtime = runtime_with_prompt_plugin(plugin).await; + + let gateway = start_gateway(TEST_USER_ID, true, runtime).await; + let service = gateway.connect(TEST_USER_ID).await; + + let error = service.get_prompt(review_request("weather")).await.expect_err("denied prompt fails the call"); + let (code, message) = error_parts(error); + assert_eq!(ErrorCode(PROMPT_POST_DENY_ERROR_CODE), code); + assert!( + message.contains("prompt"), + "a denied prompt must not be reported to the client as a denied tool call: {message}" + ); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn prompt_hooks_run_either_side_of_the_backend_call() { + let events: Arc>> = Arc::new(StdMutex::new(Vec::new())); + let plugin = Arc::new( + PromptTestPlugin::new( + "prompt-ordering", + vec![cmf_hook_names::PROMPT_PRE_FETCH, cmf_hook_names::PROMPT_POST_FETCH], + ) + .with_events(Arc::clone(&events)), + ); + let runtime = runtime_with_prompt_plugin(plugin).await; + + let gateway = start_gateway_with_events(TEST_USER_ID, runtime, Arc::clone(&events)).await; + let service = gateway.connect(TEST_USER_ID).await; + service.get_prompt(review_request("weather")).await.expect("prompt is returned"); + + assert_eq!(vec!["pre", "backend", "post"], *events.lock().expect("events lock poisoned")); +} + #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn prompt_pre_and_post_hooks_share_gateway_call_context() { let plugin = Arc::new( diff --git a/crates/contextforge-data-plane-lib/tests/support/mod.rs b/crates/contextforge-data-plane-lib/tests/support/mod.rs index fd7da55c..da2f73af 100644 --- a/crates/contextforge-data-plane-lib/tests/support/mod.rs +++ b/crates/contextforge-data-plane-lib/tests/support/mod.rs @@ -24,10 +24,14 @@ pub(crate) use list_tools_gateway::{ create_tls_gateway_with_four_tls_counters, plaintext_config, }; pub(crate) use plugin::{ - POST_DENY_ERROR_CODE, PRE_DENY_ERROR_CODE, PromptBehavior, PromptTestPlugin, PromptTestPluginFactory, - REWRITTEN_PROMPT_TEXT, REWRITTEN_PROMPT_TOPIC, REWRITTEN_SUM_A, REWRITTEN_SUM_B, TestPlugin, TestPluginFactory, + POST_DENY_ERROR_CODE, PRE_DENY_ERROR_CODE, PROMPT_POST_DENY_ERROR_CODE, PromptBehavior, PromptTestPlugin, + REWRITTEN_PROMPT_RESOURCE, REWRITTEN_PROMPT_TEXT, REWRITTEN_PROMPT_TOPIC, REWRITTEN_SUM_A, REWRITTEN_SUM_B, + TestPlugin, TestPluginFactory, +}; +pub(crate) use plugin_gateway::{ + BACKEND_PROMPT_IMAGE, BACKEND_PROMPT_RESOURCE, RunningGateway, start_gateway, start_gateway_with_events, + start_gateway_with_json_backend_responses, }; -pub(crate) use plugin_gateway::{RunningGateway, start_gateway, start_gateway_with_json_backend_responses}; pub(crate) use runtime::{runtime_with_post, runtime_with_pre, runtime_with_pre_and_post, runtime_with_prompt_plugin}; -pub(crate) use tool::{error_code, sum_request, text}; +pub(crate) use tool::{error_code, error_parts, sum_request, text}; pub(crate) use user_config_store::MemoryUserConfigStore; diff --git a/crates/contextforge-data-plane-lib/tests/support/plugin.rs b/crates/contextforge-data-plane-lib/tests/support/plugin.rs index 7792ffce..1553c2ee 100644 --- a/crates/contextforge-data-plane-lib/tests/support/plugin.rs +++ b/crates/contextforge-data-plane-lib/tests/support/plugin.rs @@ -5,7 +5,7 @@ use std::{ use async_trait::async_trait; use cpex::cpex_core::{ - cmf::{CmfHook, ContentPart, Message, MessagePayload, Role}, + cmf::{CmfHook, ContentPart, Message, MessagePayload, PromptResult as CmfPromptResult, Role}, context::PluginContext, error::{PluginError, PluginViolation}, factory::{PluginFactory, PluginInstance}, @@ -316,6 +316,15 @@ impl TestPluginFactory { pub(crate) const REWRITTEN_PROMPT_TOPIC: &str = "rewritten-topic"; pub(crate) const REWRITTEN_PROMPT_TEXT: &str = "review of [REDACTED]"; +pub(crate) const REWRITTEN_PROMPT_RESOURCE: &str = "config with [REDACTED]"; +pub(crate) const PROMPT_POST_DENY_ERROR_CODE: i32 = -32004; + +fn prompt_result_mut(payload: &mut MessagePayload) -> Option<&mut CmfPromptResult> { + payload.message.content.iter_mut().find_map(|part| match part { + ContentPart::PromptResult { content } => Some(content), + _ => None, + }) +} #[derive(Clone, Copy, Default)] pub(crate) enum PromptBehavior { @@ -323,12 +332,14 @@ pub(crate) enum PromptBehavior { Rewrite, DropText, ContextRoundtrip, + Deny, } pub(crate) struct PromptTestPlugin { pub(crate) config: PluginConfig, pub(crate) observations: Arc>, pub(crate) behavior: PromptBehavior, + pub(crate) events: Option>>>, } #[derive(Default)] @@ -351,6 +362,27 @@ impl PromptTestPlugin { }, observations: Arc::new(Mutex::new(PromptObservations::default())), behavior: PromptBehavior::default(), + events: None, + } + } + + pub(crate) fn with_events(mut self, events: Arc>>) -> Self { + self.events = Some(events); + self + } + + pub(crate) fn rebuild(&self, config: PluginConfig) -> Self { + Self { + config, + observations: Arc::clone(&self.observations), + behavior: self.behavior, + events: self.events.clone(), + } + } + + fn record(&self, event: &'static str) { + if let Some(events) = &self.events { + events.lock().expect("events lock poisoned").push(event); } } @@ -364,6 +396,7 @@ impl PromptTestPlugin { } fn handle_pre(&self, payload: &MessagePayload, ctx: &mut PluginContext) -> PluginResult { + self.record("pre"); let mut observations = self.observations.lock().expect("observations lock poisoned"); observations.pre_calls += 1; if let Some(request) = payload.message.get_prompt_requests().first() { @@ -377,7 +410,7 @@ impl PromptTestPlugin { ctx.set_global("prompt_pre_seen", json!(true)); PluginResult::allow() }, - PromptBehavior::Rewrite | PromptBehavior::DropText => { + PromptBehavior::Rewrite | PromptBehavior::DropText | PromptBehavior::Deny => { let mut modified = payload.clone(); if let Some(ContentPart::PromptRequest { content }) = modified.message.content.iter_mut().find(|part| matches!(part, ContentPart::PromptRequest { .. })) @@ -390,6 +423,7 @@ impl PromptTestPlugin { } fn handle_post(&self, payload: &MessagePayload, ctx: &mut PluginContext) -> PluginResult { + self.record("post"); let mut observations = self.observations.lock().expect("observations lock poisoned"); observations.post_calls += 1; if let Some(result) = payload.message.get_prompt_results().first() { @@ -400,18 +434,32 @@ impl PromptTestPlugin { match self.behavior { PromptBehavior::Rewrite => { let mut modified = payload.clone(); - for part in &mut modified.message.content { - if let ContentPart::Text { text } = part { - REWRITTEN_PROMPT_TEXT.clone_into(text); + if let Some(result) = prompt_result_mut(&mut modified) { + for message in &mut result.messages { + for part in &mut message.content { + match part { + ContentPart::Text { text } => REWRITTEN_PROMPT_TEXT.clone_into(text), + ContentPart::Resource { content } => { + content.content = Some(REWRITTEN_PROMPT_RESOURCE.to_owned()); + }, + _ => {}, + } + } } } PluginResult::modify_payload(modified) }, PromptBehavior::DropText => { let mut modified = payload.clone(); - modified.message.content.retain(|part| !matches!(part, ContentPart::Text { .. })); + if let Some(result) = prompt_result_mut(&mut modified) { + result.messages.clear(); + } PluginResult::modify_payload(modified) }, + PromptBehavior::Deny => PluginResult::deny( + PluginViolation::new("prompt_post_denied", "prompt post denied") + .with_proto_error_code(i64::from(PROMPT_POST_DENY_ERROR_CODE)), + ), PromptBehavior::ContextRoundtrip => { if ctx.get_global("prompt_pre_seen") == Some(&json!(true)) { PluginResult::allow() @@ -448,39 +496,6 @@ impl HookHandler for PromptTestPlugin { } } -pub(crate) struct PromptTestPluginFactory { - observations: Arc>, - behavior: PromptBehavior, -} - -impl PromptTestPluginFactory { - pub(crate) fn from_plugin(plugin: &PromptTestPlugin) -> Self { - Self { observations: Arc::clone(&plugin.observations), behavior: plugin.behavior } - } -} - -impl PluginFactory for PromptTestPluginFactory { - fn create(&self, config: &PluginConfig) -> Result> { - let plugin = Arc::new(PromptTestPlugin { - config: config.clone(), - observations: Arc::clone(&self.observations), - behavior: self.behavior, - }); - let mut handlers = Vec::new(); - for hook in [cmf_hook_names::PROMPT_PRE_FETCH, cmf_hook_names::PROMPT_POST_FETCH] { - if config.hooks.iter().any(|configured| configured == hook) { - handlers.push(( - hook, - Arc::new(TypedHandlerAdapter::::new(Arc::clone(&plugin))) - as Arc, - )); - } - } - let plugin: Arc = plugin; - Ok(PluginInstance { plugin, handlers }) - } -} - impl PluginFactory for TestPluginFactory { fn create(&self, config: &PluginConfig) -> Result> { let plugin = Arc::new(TestPlugin { diff --git a/crates/contextforge-data-plane-lib/tests/support/plugin_gateway.rs b/crates/contextforge-data-plane-lib/tests/support/plugin_gateway.rs index 0b7b3792..c43ac8b7 100644 --- a/crates/contextforge-data-plane-lib/tests/support/plugin_gateway.rs +++ b/crates/contextforge-data-plane-lib/tests/support/plugin_gateway.rs @@ -17,7 +17,7 @@ use rmcp::{ model::{ CallToolRequestParams, CallToolResponse, CallToolResult, ContentBlock, ErrorCode, GetPromptRequestParams, GetPromptResponse, GetPromptResult, Implementation, InitializeRequestParams, InitializeResult, NumberOrString, - ProgressNotificationParam, ProgressToken, PromptMessage, Role, ServerCapabilities, + ProgressNotificationParam, ProgressToken, PromptMessage, ResourceContents, Role, ServerCapabilities, }, service::{RequestContext, Service}, transport::{ @@ -31,6 +31,9 @@ use tokio::sync::Mutex as TokioMutex; use super::{MemoryUserConfigStore, token}; +pub(crate) const BACKEND_PROMPT_RESOURCE: &str = "token=secret"; +pub(crate) const BACKEND_PROMPT_IMAGE: &str = "aW1hZ2UtYnl0ZXM="; + static GATEWAY_PORT_LOCK: OnceLock>> = OnceLock::new(); const CLIENT_CONNECT_TIMEOUT: Duration = Duration::from_secs(2); const GATEWAY_PORT_READY_TIMEOUT: Duration = Duration::from_secs(10); @@ -47,6 +50,7 @@ pub(crate) struct BackendState { pub(crate) calls: Arc>>, pub(crate) prompts: Arc>>, pub(crate) cancellations: Arc>>, + pub(crate) events: Arc>>, } #[derive(Clone)] @@ -74,6 +78,7 @@ impl ServerHandler for TestBackend { .lock() .expect("backend prompts lock poisoned") .push(BackendObservation { tool_name: request.name.clone(), args: request.arguments.clone() }); + self.state.events.lock().expect("backend events lock poisoned").push("backend"); let topic = request .arguments @@ -81,6 +86,18 @@ impl ServerHandler for TestBackend { .and_then(|arguments| arguments.get("topic")) .and_then(Value::as_str) .unwrap_or("nothing"); + if request.name == "review_bundle" { + return Ok(GetPromptResult::new(vec![ + PromptMessage::new_text(Role::User, format!("review of {topic}")), + PromptMessage::new( + Role::User, + ContentBlock::resource(ResourceContents::text(BACKEND_PROMPT_RESOURCE, "file:///app.env")), + ), + PromptMessage::new(Role::Assistant, ContentBlock::image(BACKEND_PROMPT_IMAGE, "image/png")), + ]) + .into()); + } + Ok(GetPromptResult::new(vec![PromptMessage::new_text(Role::User, format!("review of {topic}"))]).into()) } @@ -243,6 +260,15 @@ pub(crate) async fn start_gateway( start_gateway_with_runtime(user, runtime_plugins_enabled, plugin_runtime, false).await } +pub(crate) async fn start_gateway_with_events( + user: &str, + plugin_runtime: Arc, + events: Arc>>, +) -> RunningGateway { + start_gateway_with_state(user, true, plugin_runtime, false, BackendState { events, ..BackendState::default() }) + .await +} + pub(crate) async fn start_gateway_with_json_backend_responses( user: &str, runtime_plugins_enabled: bool, @@ -256,6 +282,23 @@ async fn start_gateway_with_runtime( runtime_plugins_enabled: bool, plugin_runtime: Arc, json_backend_responses: bool, +) -> RunningGateway { + start_gateway_with_state( + user, + runtime_plugins_enabled, + plugin_runtime, + json_backend_responses, + BackendState::default(), + ) + .await +} + +async fn start_gateway_with_state( + user: &str, + runtime_plugins_enabled: bool, + plugin_runtime: Arc, + json_backend_responses: bool, + backend_state: BackendState, ) -> RunningGateway { let port_lock = Arc::clone(GATEWAY_PORT_LOCK.get_or_init(|| Arc::new(TokioMutex::new(())))); let port_guard = port_lock.lock().await; @@ -264,7 +307,6 @@ async fn start_gateway_with_runtime( let backend_port = backend_listener.local_addr().expect("backend address").port(); let backend_name = format!("backend-{backend_port}"); let virtual_host_id = "vh-cpex-test"; - let backend_state = BackendState::default(); let backend_service = StreamableHttpService::new( { diff --git a/crates/contextforge-data-plane-lib/tests/support/runtime.rs b/crates/contextforge-data-plane-lib/tests/support/runtime.rs index 649ea5d6..fc4c6c0b 100644 --- a/crates/contextforge-data-plane-lib/tests/support/runtime.rs +++ b/crates/contextforge-data-plane-lib/tests/support/runtime.rs @@ -4,12 +4,15 @@ use contextforge_data_plane_cpex::CpexRuntimeRegistry; use cpex::cpex_core::config::CpexConfig; use serde_json::json; -use super::{PromptTestPlugin, PromptTestPluginFactory, TestPlugin, TestPluginFactory}; +use contextforge_data_plane_cpex::CmfPluginFactory; + +use super::{PromptTestPlugin, TestPlugin, TestPluginFactory}; pub(crate) async fn runtime_with_prompt_plugin(plugin: Arc) -> Arc { let mut runtime = CpexRuntimeRegistry::default(); + let template = Arc::clone(&plugin); runtime - .register_factory("prompt-test", Box::new(PromptTestPluginFactory::from_plugin(&plugin))) + .register_factory("prompt-test", Box::new(CmfPluginFactory::new(move |config| template.rebuild(config)))) .expect("prompt test factory registers"); let config = serde_json::from_value(json!({ "plugins": [{ diff --git a/crates/contextforge-data-plane-lib/tests/support/tool.rs b/crates/contextforge-data-plane-lib/tests/support/tool.rs index cc36c55b..e4793575 100644 --- a/crates/contextforge-data-plane-lib/tests/support/tool.rs +++ b/crates/contextforge-data-plane-lib/tests/support/tool.rs @@ -26,3 +26,10 @@ pub(crate) fn error_code(error: ServiceError) -> ErrorCode { }; error.code } + +pub(crate) fn error_parts(error: ServiceError) -> (ErrorCode, String) { + let ServiceError::McpError(error) = error else { + panic!("expected MCP error, got {error:?}"); + }; + (error.code, error.message.into_owned()) +} From 516e001ce981f5cc6e31d633d4bbd4da8d8801ff Mon Sep 17 00:00:00 2001 From: Madhu Mohan Jaishankar Date: Tue, 11 Aug 2026 16:13:50 +0100 Subject: [PATCH 5/7] fix: require exactly one prompt result, honour is_error, and document prompt hooks Signed-off-by: Madhu Mohan Jaishankar --- .../contextforge-data-plane-cpex/src/cmf.rs | 66 +++++++++++++++++-- .../src/pipeline.rs | 8 ++- .../tests/gateway_plugins.rs | 19 +++++- .../tests/support/mod.rs | 6 +- .../tests/support/plugin.rs | 12 +++- docs/book/src/architectural-choices.md | 2 +- docs/book/src/mcp-method-reference.md | 2 +- docs/book/src/plugins-and-policy.md | 45 ++++++++++++- docs/book/src/request-flow.md | 7 +- docs/book/src/testing.md | 2 +- 10 files changed, 148 insertions(+), 21 deletions(-) diff --git a/crates/contextforge-data-plane-cpex/src/cmf.rs b/crates/contextforge-data-plane-cpex/src/cmf.rs index 8dc6ffde..4806b085 100644 --- a/crates/contextforge-data-plane-cpex/src/cmf.rs +++ b/crates/contextforge-data-plane-cpex/src/cmf.rs @@ -132,7 +132,7 @@ pub(crate) fn prompt_request_payload( content: PromptRequest { prompt_request_id: prompt_request_id.to_owned(), name: prompt_name.to_owned(), - arguments: request.arguments.clone().unwrap_or_default().into_iter().collect(), + arguments: request.arguments.clone().map(HashMap::from_iter).unwrap_or_default(), server_id: Some(backend_name.to_owned()), }, }], @@ -176,13 +176,25 @@ pub(crate) fn prompt_result_payload( } } -/// `None` means refuse: falling back to the backend's original would undo a plugin's redaction. +fn prompt_result(payload: &MessagePayload) -> Option<&PromptResult> { + let results = payload.message.get_prompt_results(); + let [result] = results.as_slice() else { return None }; + Some(*result) +} + +pub(crate) fn prompt_result_rejection(payload: &MessagePayload) -> Option { + let result = prompt_result(payload)?; + result + .is_error + .then(|| result.error_message.clone().unwrap_or_else(|| "Plugin rejected the rendered prompt".to_owned())) +} + +// `None` means refuse: falling back to the backend's original would undo a plugin's redaction. pub(crate) fn prompt_result_response( mut original: GetPromptResult, payload: &MessagePayload, ) -> Option { - let results = payload.message.get_prompt_results(); - let result = results.first()?; + let result = prompt_result(payload)?; if result.messages.len() != original.messages.len() { return None; } @@ -308,18 +320,22 @@ mod tests { GetPromptResult::new(vec![PromptMessage::new_text(McpRole::User, "review of weather")]) } - fn edited_messages(payload: &mut MessagePayload) -> &mut Vec { + fn prompt_result_mut(payload: &mut MessagePayload) -> &mut PromptResult { payload .message .content .iter_mut() .find_map(|part| match part { - ContentPart::PromptResult { content } => Some(&mut content.messages), + ContentPart::PromptResult { content } => Some(content), _ => None, }) .expect("payload carries a prompt result") } + fn edited_messages(payload: &mut MessagePayload) -> &mut Vec { + &mut prompt_result_mut(payload).messages + } + #[test] fn prompt_result_response_rejects_added_message() { let original = text_prompt(); @@ -330,6 +346,44 @@ mod tests { assert!(prompt_result_response(original, &payload).is_none()); } + #[test] + fn prompt_result_response_rejects_extra_prompt_result() { + let original = text_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let duplicate = payload.message.content[0].clone(); + payload.message.content.push(duplicate); + + assert!(prompt_result_response(original, &payload).is_none()); + } + + #[test] + fn prompt_result_rejection_reports_the_plugin_error_message() { + let original = text_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let result = prompt_result_mut(&mut payload); + result.is_error = true; + result.error_message = Some("blocked by policy".to_owned()); + + assert_eq!(Some("blocked by policy".to_owned()), prompt_result_rejection(&payload)); + } + + #[test] + fn prompt_result_rejection_falls_back_when_the_plugin_gives_no_message() { + let original = text_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + prompt_result_mut(&mut payload).is_error = true; + + assert_eq!(Some("Plugin rejected the rendered prompt".to_owned()), prompt_result_rejection(&payload)); + } + + #[test] + fn prompt_result_rejection_is_absent_for_a_normal_result() { + let original = text_prompt(); + let payload = prompt_result_payload(&original, "review", "prompt-1"); + + assert_eq!(None, prompt_result_rejection(&payload)); + } + #[test] fn prompt_result_response_rejects_removed_message() { let original = text_prompt(); diff --git a/crates/contextforge-data-plane-cpex/src/pipeline.rs b/crates/contextforge-data-plane-cpex/src/pipeline.rs index f34fbac1..de2e92b4 100644 --- a/crates/contextforge-data-plane-cpex/src/pipeline.rs +++ b/crates/contextforge-data-plane-cpex/src/pipeline.rs @@ -10,8 +10,8 @@ use tracing::warn; use crate::{ PromptArgumentsUpdate, ToolArgumentsUpdate, cmf::{ - prompt_request_arguments, prompt_result_response, tool_call_arguments, tool_result_content, - tool_result_response, + prompt_request_arguments, prompt_result_rejection, prompt_result_response, tool_call_arguments, + tool_result_content, tool_result_response, }, }; @@ -80,6 +80,10 @@ pub(crate) fn effective_post_prompt_result( return Ok(original); }; + if let Some(message) = prompt_result_rejection(payload) { + return Err(ErrorData { code: ErrorCode::INVALID_REQUEST, message: message.into(), data: None }); + } + prompt_result_response(original, payload).ok_or_else(|| ErrorData { code: ErrorCode::INTERNAL_ERROR, message: "Plugin changed the prompt message count".into(), diff --git a/crates/contextforge-data-plane-lib/tests/gateway_plugins.rs b/crates/contextforge-data-plane-lib/tests/gateway_plugins.rs index e0f7c596..75e8c0b9 100644 --- a/crates/contextforge-data-plane-lib/tests/gateway_plugins.rs +++ b/crates/contextforge-data-plane-lib/tests/gateway_plugins.rs @@ -18,7 +18,7 @@ use rmcp::{ use serde_json::{Map, Value, json}; use support::{ - BACKEND_PROMPT_IMAGE, BACKEND_PROMPT_RESOURCE, POST_DENY_ERROR_CODE, PRE_DENY_ERROR_CODE, + BACKEND_PROMPT_IMAGE, BACKEND_PROMPT_RESOURCE, POST_DENY_ERROR_CODE, PRE_DENY_ERROR_CODE, PROMPT_ERROR_MESSAGE, PROMPT_POST_DENY_ERROR_CODE, PromptBehavior, PromptTestPlugin, REWRITTEN_PROMPT_RESOURCE, REWRITTEN_PROMPT_TEXT, REWRITTEN_PROMPT_TOPIC, REWRITTEN_SUM_A, REWRITTEN_SUM_B, RunningGateway, TEST_USER_ID, TestPlugin, error_code, error_parts, runtime_with_post, runtime_with_pre, runtime_with_pre_and_post, runtime_with_prompt_plugin, @@ -815,6 +815,23 @@ async fn prompt_post_hook_denial_returns_plugin_error_code() { ); } +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +async fn prompt_post_hook_error_flag_fails_the_call() { + let plugin = Arc::new( + PromptTestPlugin::new("prompt-post-error", vec![cmf_hook_names::PROMPT_POST_FETCH]) + .with_behavior(PromptBehavior::MarkError), + ); + let runtime = runtime_with_prompt_plugin(plugin).await; + + let gateway = start_gateway(TEST_USER_ID, true, runtime).await; + let service = gateway.connect(TEST_USER_ID).await; + + let error = service.get_prompt(review_request("weather")).await.expect_err("flagged prompt fails the call"); + let (code, message) = error_parts(error); + assert_eq!(ErrorCode::INVALID_REQUEST, code); + assert_eq!(PROMPT_ERROR_MESSAGE, message); +} + #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn prompt_hooks_run_either_side_of_the_backend_call() { let events: Arc>> = Arc::new(StdMutex::new(Vec::new())); diff --git a/crates/contextforge-data-plane-lib/tests/support/mod.rs b/crates/contextforge-data-plane-lib/tests/support/mod.rs index da2f73af..a1ce24b3 100644 --- a/crates/contextforge-data-plane-lib/tests/support/mod.rs +++ b/crates/contextforge-data-plane-lib/tests/support/mod.rs @@ -24,9 +24,9 @@ pub(crate) use list_tools_gateway::{ create_tls_gateway_with_four_tls_counters, plaintext_config, }; pub(crate) use plugin::{ - POST_DENY_ERROR_CODE, PRE_DENY_ERROR_CODE, PROMPT_POST_DENY_ERROR_CODE, PromptBehavior, PromptTestPlugin, - REWRITTEN_PROMPT_RESOURCE, REWRITTEN_PROMPT_TEXT, REWRITTEN_PROMPT_TOPIC, REWRITTEN_SUM_A, REWRITTEN_SUM_B, - TestPlugin, TestPluginFactory, + POST_DENY_ERROR_CODE, PRE_DENY_ERROR_CODE, PROMPT_ERROR_MESSAGE, PROMPT_POST_DENY_ERROR_CODE, PromptBehavior, + PromptTestPlugin, REWRITTEN_PROMPT_RESOURCE, REWRITTEN_PROMPT_TEXT, REWRITTEN_PROMPT_TOPIC, REWRITTEN_SUM_A, + REWRITTEN_SUM_B, TestPlugin, TestPluginFactory, }; pub(crate) use plugin_gateway::{ BACKEND_PROMPT_IMAGE, BACKEND_PROMPT_RESOURCE, RunningGateway, start_gateway, start_gateway_with_events, diff --git a/crates/contextforge-data-plane-lib/tests/support/plugin.rs b/crates/contextforge-data-plane-lib/tests/support/plugin.rs index 1553c2ee..788bfe9f 100644 --- a/crates/contextforge-data-plane-lib/tests/support/plugin.rs +++ b/crates/contextforge-data-plane-lib/tests/support/plugin.rs @@ -318,6 +318,7 @@ pub(crate) const REWRITTEN_PROMPT_TOPIC: &str = "rewritten-topic"; pub(crate) const REWRITTEN_PROMPT_TEXT: &str = "review of [REDACTED]"; pub(crate) const REWRITTEN_PROMPT_RESOURCE: &str = "config with [REDACTED]"; pub(crate) const PROMPT_POST_DENY_ERROR_CODE: i32 = -32004; +pub(crate) const PROMPT_ERROR_MESSAGE: &str = "prompt blocked by policy"; fn prompt_result_mut(payload: &mut MessagePayload) -> Option<&mut CmfPromptResult> { payload.message.content.iter_mut().find_map(|part| match part { @@ -333,6 +334,7 @@ pub(crate) enum PromptBehavior { DropText, ContextRoundtrip, Deny, + MarkError, } pub(crate) struct PromptTestPlugin { @@ -410,7 +412,7 @@ impl PromptTestPlugin { ctx.set_global("prompt_pre_seen", json!(true)); PluginResult::allow() }, - PromptBehavior::Rewrite | PromptBehavior::DropText | PromptBehavior::Deny => { + PromptBehavior::Rewrite | PromptBehavior::DropText | PromptBehavior::Deny | PromptBehavior::MarkError => { let mut modified = payload.clone(); if let Some(ContentPart::PromptRequest { content }) = modified.message.content.iter_mut().find(|part| matches!(part, ContentPart::PromptRequest { .. })) @@ -456,6 +458,14 @@ impl PromptTestPlugin { } PluginResult::modify_payload(modified) }, + PromptBehavior::MarkError => { + let mut modified = payload.clone(); + if let Some(result) = prompt_result_mut(&mut modified) { + result.is_error = true; + result.error_message = Some(PROMPT_ERROR_MESSAGE.to_owned()); + } + PluginResult::modify_payload(modified) + }, PromptBehavior::Deny => PluginResult::deny( PluginViolation::new("prompt_post_denied", "prompt post denied") .with_proto_error_code(i64::from(PROMPT_POST_DENY_ERROR_CODE)), diff --git a/docs/book/src/architectural-choices.md b/docs/book/src/architectural-choices.md index ae804b3a..a8e2496c 100644 --- a/docs/book/src/architectural-choices.md +++ b/docs/book/src/architectural-choices.md @@ -18,7 +18,7 @@ They describe the shape of the current Rust dataplane, not just preferences. | Backend names are public | The backend map key is part of tool/resource/prompt names. | Backend renames are client-visible behavior changes. | | Sessions are local today | Backend RMCP services live in `BackendTransports` inside one process. | Load-balanced deployments need sticky routing or a new session ownership design. | | Merged MCP semantics define the contract | The client sees one gateway MCP server with namespaced backend objects. | Backend topology should not become a hard client dependency beyond the namespace contract. | -| Plugin boundaries stay explicit | Tool pre/post hooks are integrated at known points around backend invocation. | Payload mutation needs clear failure, timeout, cancellation, and telemetry behavior. | +| Plugin boundaries stay explicit | Tool and prompt pre/post hooks are integrated at known points around backend invocation. | Payload mutation needs clear failure, timeout, cancellation, and telemetry behavior. | ## Dataplane, Not Control Plane diff --git a/docs/book/src/mcp-method-reference.md b/docs/book/src/mcp-method-reference.md index d378a853..dd110c77 100644 --- a/docs/book/src/mcp-method-reference.md +++ b/docs/book/src/mcp-method-reference.md @@ -45,7 +45,7 @@ single-backend pass-through, or a multi-backend prefix: | `call_tool` | Resolves an exact control-plane alias first, then falls back to the single-versus-multi rule. It runs the optional plugin hooks, tracks progress, forwards the backend-local tool name, and propagates downstream cancellation. | | `read_resource` | Preserves a single-backend URI or strips a multi-backend prefix, then returns the selected backend's result. | | `subscribe`, `unsubscribe` | Apply the same resource-URI routing, track the downstream subscription, and forward or stop forwarding matching resource-update notifications. | -| `get_prompt` | Preserves a single-backend prompt name or strips a multi-backend prefix, then returns the selected backend's result. | +| `get_prompt` | Preserves a single-backend prompt name or strips a multi-backend prefix, runs the optional plugin hooks either side of the backend call, and returns the selected backend's result. | | `complete` | Applies the same routing to the prompt name or resource URI in `ref` and returns the selected backend's completion result. | Routed failures are JSON-RPC errors: an identifier that cannot select a backend diff --git a/docs/book/src/plugins-and-policy.md b/docs/book/src/plugins-and-policy.md index e6e647ad..45c8412f 100644 --- a/docs/book/src/plugins-and-policy.md +++ b/docs/book/src/plugins-and-policy.md @@ -92,13 +92,19 @@ The supported surface is deliberately narrow: ```text cmf.tool_pre_invoke cmf.tool_post_invoke +cmf.prompt_pre_fetch +cmf.prompt_post_fetch ``` The gateway rejects route-based plugin selection, plugin directories, global -policies/defaults, non-tool hooks, and plugin conditions. Those features need -clear behavior for streaming, failures, timeouts, backpressure, context +policies/defaults, resource and LLM hooks, and plugin conditions. Those features +need clear behavior for streaming, failures, timeouts, backpressure, context propagation, and observability before they belong on the hot path. +Configuration validation and factory registration must agree on this list. A +hook accepted by validation but not registered by `CmfPluginFactory` leaves the +plugin loaded and silently inert. + ## Tool Call Behavior For `call_tool`, the pre hook runs after backend routing has selected the @@ -118,6 +124,41 @@ After the upstream backend returns, the post hook can: Hook state is carried across the upstream call so pre and post hooks can share CPEX context for the same logical tool call. +## Prompt Fetch Behavior + +For `get_prompt`, the pre hook runs after backend routing, so the plugin sees +the backend-local prompt name and the owning backend separately rather than the +gateway-prefixed identifier. It can leave the arguments unchanged, replace them, +or deny the fetch before the backend renders anything. + +The post hook receives the rendered prompt as one CMF message per rendered MCP +message, each carrying its role and its content block: text, image, audio, +embedded resource, or resource link. A plugin can inspect or rewrite any of +them, which is what lets a policy act on a file interpolated into a prompt +rather than only on its surrounding text. + +Writing plugin edits back follows three rules: + +- A message the plugin left unchanged is returned exactly as the backend sent + it, so annotations, `_meta`, and binary resource blobs survive untouched. +- A message the plugin changed is rebuilt from CMF. CMF does not model MCP + annotations or `_meta`, so an edited message loses them. +- Edits that cannot be applied faithfully fail the call rather than falling back + to the backend's original. A changed message count, more than one prompt + result in the payload, a role MCP prompts cannot express, or a resource whose + text the plugin removed all return an error. Silently restoring the backend's + content would undo a redaction. + +MCP prompt results carry no error flag, so a plugin setting `is_error` on the +CMF prompt result is rejecting the prompt rather than describing it. The gateway +turns that into an MCP error carrying the plugin's `error_message`; the rendered +content never reaches the client. This differs from tools, where `is_error` is a +field on `CallToolResult` and is forwarded as a successful response. + +Binary resource blobs reach plugins by URI and MIME type but not by content: +CMF stores decoded bytes while MCP sends base64. A plugin can deny such a +message; editing one fails the write-back. + ## Boundary Rules Plugin execution must not poison shared gateway state. A plugin denial becomes diff --git a/docs/book/src/request-flow.md b/docs/book/src/request-flow.md index ba907306..1579e779 100644 --- a/docs/book/src/request-flow.md +++ b/docs/book/src/request-flow.md @@ -164,7 +164,8 @@ Current routed method families: | --- | --- | | `list_tools`, `list_resources`, `list_prompts`, `list_resource_templates` | Decode the incoming gateway cursor (if present) to recover per-backend positions. On the first request (no cursor) all configured backend services are queried; on a resume request only backends that still have pages are queried. Call each selected backend concurrently via `fan_out_list`, passing its own per-backend cursor. Preserve identifiers for a single backend or namespace them for multiple backends. Sort the merged page output. Encode a new gateway cursor when at least one backend returned a `next_cursor`; omit it when all are exhausted. Explicit tool aliases are preserved exactly. An undecodable cursor returns `−32602 Invalid params`. | | `call_tool` | Resolve an exact tool alias first; otherwise preserve the name for one backend or split `{backend_name}-{tool_name}` for multiple backends. Resolve one backend, run the optional tool hooks, track progress, call the backend, and return the result. | -| `read_resource`, `subscribe`, `unsubscribe`, `get_prompt` | Select the only backend and forward the identifier unchanged, or split and strip the prefix for a multi-backend host, then call the resolved backend. | +| `read_resource`, `subscribe`, `unsubscribe` | Select the only backend and forward the identifier unchanged, or split and strip the prefix for a multi-backend host, then call the resolved backend. | +| `get_prompt` | Route as above, then run the optional prompt hooks around the backend call: the pre hook sees the backend-local prompt name and may rewrite arguments or deny, and the post hook sees the rendered messages and may rewrite or reject them. | | `complete` | Apply the same conditional routing to the prompt name or resource URI in `ref`, then return the selected backend's completion result. | `GatewayBackendClient` handles backend progress notifications for `call_tool`. @@ -194,8 +195,8 @@ backend fanout or identifier routing. ## Response Path -Backend responses return to `McpService` first. `call_tool` may run response -plugin hooks before returning. +Backend responses return to `McpService` first. `call_tool` and `get_prompt` +may run response plugin hooks before returning. List calls decode the incoming gateway cursor, fan out to the active backends, merge the current page of output (preserving single-backend identifiers and diff --git a/docs/book/src/testing.md b/docs/book/src/testing.md index 4f804860..907ec597 100644 --- a/docs/book/src/testing.md +++ b/docs/book/src/testing.md @@ -36,7 +36,7 @@ in-process mock MCP backends (shared helpers live in `tests/support/`): | `gateway_list_tools.rs` | List fanout, prefixing, and merged output. | | `gateway_prompts.rs` | Prompt listing and prefixed `get_prompt` routing. | | `gateway_resource_templates.rs` | Template fanout with prefixed names and URI templates, plus `read_resource` round-trips. | -| `gateway_plugins.rs` | CPEX pre/post tool hooks around `call_tool` and stream events. | +| `gateway_plugins.rs` | CPEX pre/post tool hooks around `call_tool` and stream events, and prompt hooks around `get_prompt`. | These run in `cargo nextest run` with no Docker dependencies. From 5bac5022b643a1467ae12ceb807d81f8d4ea3480 Mon Sep 17 00:00:00 2001 From: Madhu Mohan Jaishankar Date: Wed, 12 Aug 2026 10:02:39 +0100 Subject: [PATCH 6/7] fix: fail closed on unsupported prompt result envelope and CMF content edits Signed-off-by: Madhu Mohan Jaishankar --- .../contextforge-data-plane-cpex/src/cmf.rs | 117 ++++++++++++++++-- .../src/pipeline.rs | 6 +- .../src/runtime.rs | 2 +- 3 files changed, 113 insertions(+), 12 deletions(-) diff --git a/crates/contextforge-data-plane-cpex/src/cmf.rs b/crates/contextforge-data-plane-cpex/src/cmf.rs index 4806b085..54943412 100644 --- a/crates/contextforge-data-plane-cpex/src/cmf.rs +++ b/crates/contextforge-data-plane-cpex/src/cmf.rs @@ -193,8 +193,13 @@ pub(crate) fn prompt_result_rejection(payload: &MessagePayload) -> Option Option { let result = prompt_result(payload)?; + if result.prompt_name != prompt_name || result.prompt_request_id != prompt_request_id || result.content.is_some() { + return None; + } if result.messages.len() != original.messages.len() { return None; } @@ -281,6 +286,12 @@ fn cmf_content_part(block: &ContentBlock, prompt_request_id: &str) -> Option(source_type: &str, data: &'a str) -> Option<&'a str> { + (source_type == "base64").then_some(data) +} + fn mcp_prompt_message(message: &Message) -> Option { let role = match message.role { Role::Assistant => McpRole::Assistant, @@ -292,10 +303,10 @@ fn mcp_prompt_message(message: &Message) -> Option { let content = match part { ContentPart::Text { text } => ContentBlock::text(text.clone()), ContentPart::Image { content } => { - ContentBlock::image(content.data.clone(), content.media_type.clone().unwrap_or_default()) + ContentBlock::image(inline_media_data(&content.source_type, &content.data)?, content.media_type.clone()?) }, ContentPart::Audio { content } => { - ContentBlock::audio(content.data.clone(), content.media_type.clone().unwrap_or_default()) + ContentBlock::audio(inline_media_data(&content.source_type, &content.data)?, content.media_type.clone()?) }, ContentPart::Resource { content } => ContentBlock::resource(ResourceContents::TextResourceContents { uri: content.uri.clone(), @@ -304,7 +315,10 @@ fn mcp_prompt_message(message: &Message) -> Option { meta: None, }), ContentPart::ResourceRef { content } => { - ContentBlock::ResourceLink(McpResource::new(content.uri.clone(), content.name.clone().unwrap_or_default())) + if content.range_start.is_some() || content.range_end.is_some() || content.selector.is_some() { + return None; + } + ContentBlock::ResourceLink(McpResource::new(content.uri.clone(), content.name.clone()?)) }, _ => return None, }; @@ -343,7 +357,7 @@ mod tests { let extra = edited_messages(&mut payload).first().cloned().expect("one message"); edited_messages(&mut payload).push(extra); - assert!(prompt_result_response(original, &payload).is_none()); + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); } #[test] @@ -353,7 +367,7 @@ mod tests { let duplicate = payload.message.content[0].clone(); payload.message.content.push(duplicate); - assert!(prompt_result_response(original, &payload).is_none()); + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); } #[test] @@ -384,13 +398,97 @@ mod tests { assert_eq!(None, prompt_result_rejection(&payload)); } + #[test] + fn prompt_result_response_rejects_envelope_content_edit() { + let original = text_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + prompt_result_mut(&mut payload).content = Some("[REDACTED]".to_owned()); + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_result_response_rejects_renamed_prompt() { + let original = text_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + prompt_result_mut(&mut payload).prompt_name = "other".to_owned(); + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_result_response_rejects_recorrelated_result() { + let original = text_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + prompt_result_mut(&mut payload).prompt_request_id = "prompt-2".to_owned(); + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_result_response_rejects_url_sourced_image() { + let original = + GetPromptResult::new(vec![PromptMessage::new(McpRole::User, ContentBlock::image("aW1hZ2U=", "image/png"))]); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let ContentPart::Image { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("expected an image part"); + }; + "url".clone_into(&mut content.source_type); + content.data = "https://example.invalid/image.png".to_owned(); + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_result_response_rejects_image_without_media_type() { + let original = + GetPromptResult::new(vec![PromptMessage::new(McpRole::User, ContentBlock::image("aW1hZ2U=", "image/png"))]); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let ContentPart::Image { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("expected an image part"); + }; + content.media_type = None; + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_result_response_rejects_resource_link_without_name() { + let original = GetPromptResult::new(vec![PromptMessage::new( + McpRole::User, + ContentBlock::ResourceLink(McpResource::new("file:///app.env", "app-env")), + )]); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let ContentPart::ResourceRef { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("expected a resource reference part"); + }; + content.name = None; + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_result_response_rejects_resource_link_range_edit() { + let original = GetPromptResult::new(vec![PromptMessage::new( + McpRole::User, + ContentBlock::ResourceLink(McpResource::new("file:///app.env", "app-env")), + )]); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let ContentPart::ResourceRef { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("expected a resource reference part"); + }; + content.range_start = Some(10); + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + #[test] fn prompt_result_response_rejects_removed_message() { let original = text_prompt(); let mut payload = prompt_result_payload(&original, "review", "prompt-1"); edited_messages(&mut payload).clear(); - assert!(prompt_result_response(original, &payload).is_none()); + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); } #[test] @@ -399,7 +497,7 @@ mod tests { let mut payload = prompt_result_payload(&original, "review", "prompt-1"); edited_messages(&mut payload)[0].role = Role::System; - assert!(prompt_result_response(original, &payload).is_none()); + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); } #[test] @@ -407,7 +505,8 @@ mod tests { let original = text_prompt(); let payload = prompt_result_payload(&original, "review", "prompt-1"); - let result = prompt_result_response(original.clone(), &payload).expect("unmodified payload applies"); + let result = prompt_result_response(original.clone(), &payload, "review", "prompt-1") + .expect("unmodified payload applies"); assert_eq!( serde_json::to_value(&original).expect("original serializes"), @@ -429,7 +528,7 @@ mod tests { assert_eq!(Some("token=secret"), content.content.as_deref()); content.content = Some("token=[REDACTED]".to_owned()); - let result = prompt_result_response(original, &payload).expect("resource edit applies"); + let result = prompt_result_response(original, &payload, "review", "prompt-1").expect("resource edit applies"); let ContentBlock::Resource(resource) = &result.messages[0].content else { panic!("expected an embedded resource"); diff --git a/crates/contextforge-data-plane-cpex/src/pipeline.rs b/crates/contextforge-data-plane-cpex/src/pipeline.rs index de2e92b4..10b76d37 100644 --- a/crates/contextforge-data-plane-cpex/src/pipeline.rs +++ b/crates/contextforge-data-plane-cpex/src/pipeline.rs @@ -75,6 +75,8 @@ pub(crate) fn effective_post_result(original: CallToolResult, result: &PipelineR pub(crate) fn effective_post_prompt_result( original: GetPromptResult, result: &PipelineResult, + prompt_name: &str, + prompt_request_id: &str, ) -> Result { let Some(payload) = modified_message_payload(result) else { return Ok(original); @@ -84,9 +86,9 @@ pub(crate) fn effective_post_prompt_result( return Err(ErrorData { code: ErrorCode::INVALID_REQUEST, message: message.into(), data: None }); } - prompt_result_response(original, payload).ok_or_else(|| ErrorData { + prompt_result_response(original, payload, prompt_name, prompt_request_id).ok_or_else(|| ErrorData { code: ErrorCode::INTERNAL_ERROR, - message: "Plugin changed the prompt message count".into(), + message: "Plugin returned a prompt result the gateway cannot apply".into(), data: None, }) } diff --git a/crates/contextforge-data-plane-cpex/src/runtime.rs b/crates/contextforge-data-plane-cpex/src/runtime.rs index af2d8ecd..d8746984 100644 --- a/crates/contextforge-data-plane-cpex/src/runtime.rs +++ b/crates/contextforge-data-plane-cpex/src/runtime.rs @@ -283,7 +283,7 @@ impl GatewayPluginRuntime { return Err(plugin_denied_error("prompt", post_result)); } - effective_post_prompt_result(response, &post_result) + effective_post_prompt_result(response, &post_result, prompt_name, &state.prompt_request_id) } pub(crate) async fn after_tool_call( From c371ec1fecf4fce13362c58875e0682a78f7d7b8 Mon Sep 17 00:00:00 2001 From: Madhu Mohan Jaishankar Date: Wed, 12 Aug 2026 11:51:45 +0100 Subject: [PATCH 7/7] fix: fail closed on ignored prompt request and result field edits Signed-off-by: Madhu Mohan Jaishankar --- .../contextforge-data-plane-cpex/src/cmf.rs | 266 +++++++++++++++++- .../src/pipeline.rs | 8 +- .../src/runtime.rs | 8 +- 3 files changed, 267 insertions(+), 15 deletions(-) diff --git a/crates/contextforge-data-plane-cpex/src/cmf.rs b/crates/contextforge-data-plane-cpex/src/cmf.rs index 54943412..eeb74c97 100644 --- a/crates/contextforge-data-plane-cpex/src/cmf.rs +++ b/crates/contextforge-data-plane-cpex/src/cmf.rs @@ -141,12 +141,21 @@ pub(crate) fn prompt_request_payload( } } -pub(crate) fn prompt_request_arguments(payload: &MessagePayload) -> Option> { - payload - .message - .get_prompt_requests() - .first() - .map(|request| request.arguments.clone().into_iter().collect::>()) +pub(crate) fn prompt_request_arguments( + payload: &MessagePayload, + prompt_name: &str, + backend_name: &str, + prompt_request_id: &str, +) -> Option> { + let requests = payload.message.get_prompt_requests(); + let [request] = requests.as_slice() else { return None }; + if request.name != prompt_name + || request.prompt_request_id != prompt_request_id + || request.server_id.as_deref() != Some(backend_name) + { + return None; + } + Some(request.arguments.clone().into_iter().collect::>()) } pub(crate) fn prompt_result_payload( @@ -197,7 +206,11 @@ pub(crate) fn prompt_result_response( prompt_request_id: &str, ) -> Option { let result = prompt_result(payload)?; - if result.prompt_name != prompt_name || result.prompt_request_id != prompt_request_id || result.content.is_some() { + if result.prompt_name != prompt_name + || result.prompt_request_id != prompt_request_id + || result.content.is_some() + || result.error_message.is_some() + { return None; } if result.messages.len() != original.messages.len() { @@ -205,11 +218,18 @@ pub(crate) fn prompt_result_response( } for (message, edited) in original.messages.iter_mut().zip(&result.messages) { - let projected = cmf_prompt_message(message, &result.prompt_request_id); + let projected = cmf_prompt_message(message, prompt_request_id); if serde_json::to_value(&projected).ok()? == serde_json::to_value(edited).ok()? { continue; } - *message = mcp_prompt_message(edited)?; + + let rebuilt = mcp_prompt_message(edited)?; + if serde_json::to_value(cmf_prompt_message(&rebuilt, prompt_request_id)).ok()? + != serde_json::to_value(edited).ok()? + { + return None; + } + *message = rebuilt; } Some(original) @@ -315,9 +335,6 @@ fn mcp_prompt_message(message: &Message) -> Option { meta: None, }), ContentPart::ResourceRef { content } => { - if content.range_start.is_some() || content.range_end.is_some() || content.selector.is_some() { - return None; - } ContentBlock::ResourceLink(McpResource::new(content.uri.clone(), content.name.clone()?)) }, _ => return None, @@ -398,6 +415,67 @@ mod tests { assert_eq!(None, prompt_result_rejection(&payload)); } + fn review_payload() -> MessagePayload { + let request = GetPromptRequestParams::new("review") + .with_arguments(Map::from_iter([("topic".to_owned(), Value::from("weather"))])); + prompt_request_payload(&request, "review", "backend-a", "prompt-1") + } + + fn prompt_request_mut(payload: &mut MessagePayload) -> &mut PromptRequest { + payload + .message + .content + .iter_mut() + .find_map(|part| match part { + ContentPart::PromptRequest { content } => Some(content), + _ => None, + }) + .expect("payload carries a prompt request") + } + + #[test] + fn prompt_request_arguments_accepts_an_argument_edit() { + let mut payload = review_payload(); + prompt_request_mut(&mut payload).arguments.insert("topic".to_owned(), Value::from("rain")); + + let arguments = prompt_request_arguments(&payload, "review", "backend-a", "prompt-1"); + + assert_eq!(Some(&Value::from("rain")), arguments.as_ref().and_then(|args| args.get("topic"))); + } + + #[test] + fn prompt_request_arguments_rejects_a_renamed_prompt() { + let mut payload = review_payload(); + "other".clone_into(&mut prompt_request_mut(&mut payload).name); + + assert!(prompt_request_arguments(&payload, "review", "backend-a", "prompt-1").is_none()); + } + + #[test] + fn prompt_request_arguments_rejects_a_rerouted_backend() { + let mut payload = review_payload(); + prompt_request_mut(&mut payload).server_id = Some("backend-b".to_owned()); + + assert!(prompt_request_arguments(&payload, "review", "backend-a", "prompt-1").is_none()); + } + + #[test] + fn prompt_request_arguments_rejects_a_recorrelated_request() { + let mut payload = review_payload(); + "prompt-2".clone_into(&mut prompt_request_mut(&mut payload).prompt_request_id); + + assert!(prompt_request_arguments(&payload, "review", "backend-a", "prompt-1").is_none()); + } + + #[test] + fn prompt_request_arguments_rejects_extra_prompt_requests() { + let mut payload = review_payload(); + let duplicate = payload.message.content[0].clone(); + payload.message.content.push(duplicate); + + assert!(prompt_request_arguments(&payload, "review", "backend-a", "prompt-1").is_none()); + } + #[test] fn prompt_result_response_rejects_envelope_content_edit() { let original = text_prompt(); @@ -425,6 +503,170 @@ mod tests { assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); } + #[test] + fn prompt_result_response_rejects_error_message_without_error_flag() { + let original = text_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + prompt_result_mut(&mut payload).error_message = Some("blocked".to_owned()); + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + fn resource_prompt() -> GetPromptResult { + GetPromptResult::new(vec![PromptMessage::new( + McpRole::User, + ContentBlock::resource(ResourceContents::text("token=secret", "file:///app.env")), + )]) + } + + #[test] + fn prompt_result_response_rejects_resource_type_edit() { + let original = resource_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let ContentPart::Resource { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("expected a resource part"); + }; + content.resource_type = ResourceType::Database; + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_result_response_rejects_dropped_resource_metadata() { + let original = resource_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let ContentPart::Resource { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("expected a resource part"); + }; + content.description = Some("annotated by policy".to_owned()); + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + fn media_prompt(content: ContentBlock) -> GetPromptResult { + GetPromptResult::new(vec![PromptMessage::new(McpRole::User, content)]) + } + + #[test] + fn prompt_result_response_round_trips_an_image_edit() { + let original = media_prompt(ContentBlock::image("aW1hZ2U=", "image/png")); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let ContentPart::Image { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("expected an image part"); + }; + content.data = "cmVkYWN0ZWQ=".to_owned(); + + let result = prompt_result_response(original, &payload, "review", "prompt-1").expect("image edit applies"); + + let ContentBlock::Image(image) = &result.messages[0].content else { panic!("expected an image") }; + assert_eq!("cmVkYWN0ZWQ=", image.data); + assert_eq!("image/png", image.mime_type); + } + + #[test] + fn prompt_result_response_round_trips_an_audio_edit() { + let original = media_prompt(ContentBlock::audio("YXVkaW8=", "audio/mp3")); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let ContentPart::Audio { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("audio reaches the plugin as a CMF audio part"); + }; + content.data = "cmVkYWN0ZWQ=".to_owned(); + + let result = prompt_result_response(original, &payload, "review", "prompt-1").expect("audio edit applies"); + + let ContentBlock::Audio(audio) = &result.messages[0].content else { panic!("expected audio") }; + assert_eq!("cmVkYWN0ZWQ=", audio.data); + assert_eq!("audio/mp3", audio.mime_type); + } + + #[test] + fn prompt_result_response_rejects_url_sourced_audio() { + let original = media_prompt(ContentBlock::audio("YXVkaW8=", "audio/mp3")); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let ContentPart::Audio { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("expected an audio part"); + }; + "url".clone_into(&mut content.source_type); + content.data = "https://example.invalid/clip.mp3".to_owned(); + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_result_response_rejects_audio_without_media_type() { + let original = media_prompt(ContentBlock::audio("YXVkaW8=", "audio/mp3")); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let ContentPart::Audio { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("expected an audio part"); + }; + content.media_type = None; + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_result_response_round_trips_a_resource_link_edit() { + let original = media_prompt(ContentBlock::ResourceLink(McpResource::new("file:///app.env", "app-env"))); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let ContentPart::ResourceRef { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("expected a resource reference part"); + }; + content.name = Some("redacted-env".to_owned()); + + let result = prompt_result_response(original, &payload, "review", "prompt-1").expect("link edit applies"); + + let ContentBlock::ResourceLink(link) = &result.messages[0].content else { panic!("expected a link") }; + assert_eq!("redacted-env", link.name); + assert_eq!("file:///app.env", link.uri); + } + + #[test] + fn prompt_result_response_rejects_resource_with_removed_text() { + let original = resource_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + let ContentPart::Resource { content } = &mut edited_messages(&mut payload)[0].content[0] else { + panic!("expected a resource part"); + }; + content.content = None; + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_result_response_rejects_multiple_content_parts() { + let original = text_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + edited_messages(&mut payload)[0].content.push(ContentPart::Text { text: "extra".to_owned() }); + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_result_response_rejects_a_cmf_only_content_part() { + let original = text_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + edited_messages(&mut payload)[0].content = vec![ContentPart::Thinking { text: "reasoning".to_owned() }]; + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_result_response_rejects_a_payload_without_a_prompt_result() { + let original = text_prompt(); + let mut payload = prompt_result_payload(&original, "review", "prompt-1"); + payload.message.content.clear(); + + assert!(prompt_result_response(original, &payload, "review", "prompt-1").is_none()); + } + + #[test] + fn prompt_request_arguments_rejects_a_payload_without_a_prompt_request() { + let mut payload = review_payload(); + payload.message.content.clear(); + + assert!(prompt_request_arguments(&payload, "review", "backend-a", "prompt-1").is_none()); + } + #[test] fn prompt_result_response_rejects_url_sourced_image() { let original = diff --git a/crates/contextforge-data-plane-cpex/src/pipeline.rs b/crates/contextforge-data-plane-cpex/src/pipeline.rs index 10b76d37..9e4ecab0 100644 --- a/crates/contextforge-data-plane-cpex/src/pipeline.rs +++ b/crates/contextforge-data-plane-cpex/src/pipeline.rs @@ -45,15 +45,19 @@ pub(crate) fn effective_pre_args( pub(crate) fn effective_pre_prompt_args( original_args: Option<&serde_json::Map>, pre_result: &PipelineResult, + prompt_name: &str, + backend_name: &str, + prompt_request_id: &str, ) -> Result { let Some(modified_payload) = modified_message_payload(pre_result) else { return Ok(PromptArgumentsUpdate::Unchanged); }; - let Some(arguments) = prompt_request_arguments(modified_payload) else { + let Some(arguments) = prompt_request_arguments(modified_payload, prompt_name, backend_name, prompt_request_id) + else { return Err(ErrorData { code: ErrorCode::INVALID_PARAMS, - message: "Plugin modified prompt payload without a prompt request".into(), + message: "Plugin returned a prompt request the gateway cannot apply".into(), data: None, }); }; diff --git a/crates/contextforge-data-plane-cpex/src/runtime.rs b/crates/contextforge-data-plane-cpex/src/runtime.rs index d8746984..36c2efb7 100644 --- a/crates/contextforge-data-plane-cpex/src/runtime.rs +++ b/crates/contextforge-data-plane-cpex/src/runtime.rs @@ -258,7 +258,13 @@ impl GatewayPluginRuntime { return Err(plugin_denied_error("prompt", pre_result)); } - let arguments = effective_pre_prompt_args(request.arguments.as_ref(), &pre_result)?; + let arguments = effective_pre_prompt_args( + request.arguments.as_ref(), + &pre_result, + prompt_name, + backend_name, + &prompt_request_id, + )?; let state = self.hooks.prompt.post.then(|| new_prompt_call_state(pre_result.context_table.clone(), prompt_request_id)); Ok(PromptPreFetchResult { arguments, state })