Skip to content

structured_logging

Enhanced Structured Logging for SpinKube Agents

Section titled “Enhanced Structured Logging for SpinKube Agents”

This crate provides performance optimizations and convenience APIs on top of the excellent observability_core hexagonal architecture. It focuses on:

  • 🚀 Performance: String interning, buffer pooling, zero-allocation fast paths
  • 🔗 Correlation: Enhanced W3C baggage, scoped contexts, advanced tracing
  • 🎪 Convenience: Domain-specific APIs for LLM, template, and A2A operations

This crate builds on observability_core’s solid foundation:

  • Domain: Reuses LogEntry, ProcessorChain, TraceContext
  • Ports: Extends TransportPort, FormatterPort interfaces
  • Adapters: Enhances with performance-optimized implementations
  • Extension: Provides enhanced configuration and management
// Just use observability_core - works perfectly
use observability_core::ObservabilityManager;
log::info!("Standard structured logging");
// Add convenience methods
use structured_logging::convenience::*;
log_llm_request("gpt-4", duration, tokens, "success")?;
// Full performance optimization
use structured_logging::{EnhancedObservabilityConfig, PerformanceExtension};
const VERSION: &str = ;

Version information

type Result = Result<T, StructuredLoggingError>;

Result type for structured logging operations

Port (trait) for A2A context management

Required / Provided Methods

fn set_context(&self, message_type: &str, from_agent: &str, to_agent: &str, component: &str)
fn clear_context(&self)

Combined context manager that coordinates all context types

Required / Provided Methods

fn get_llm_manager(&self) -> Option<Arc<dyn LlmContextManager>>
fn get_a2a_manager(&self) -> Option<Arc<dyn A2aContextManager>>
fn get_request_manager(&self) -> Option<Arc<dyn RequestContextManager>>

Port (trait) for LLM context management

Extensions like structured_logging can implement this trait to provide concrete context management functionality.

Required / Provided Methods

fn set_context(&self, model: &str, component: &str)
fn clear_context(&self)

Port (trait) for request context management

Required / Provided Methods

fn set_context(&self, request_id: &str, user_id: Option<&str>, session_id: Option<&str>)
fn clear_context(&self)

Enhanced configuration for structured logging with performance and convenience features

Fields

FieldTypeDescription
baseobservability_core::ObservabilityConfigBase observability configuration
performancePerformanceConfigPerformance optimization settings
correlationCorrelationConfigCorrelation enhancement settings
convenienceConvenienceConfigConvenience feature settings
panic_handlerPanicHandlerConfigPanic handling configuration

Methods

fn with_base(base: ObservabilityConfig) -> Self

Create enhanced config with specified base config

fn with_panic_handler(self, config: PanicHandlerConfig) -> Self

Set panic handler configuration

fn with_all_performance_features(self) -> Self

Enable all performance features (feature-gated)

fn with_no_performance_features(self) -> Self

Disable all performance features (feature-gated)

fn to_base_config(&self) -> ObservabilityConfig

Convert to base observability config

fn validate(&self) -> Result<()>

Validate configuration

fn to_json(&self) -> Result<String>

Serialize configuration to JSON

fn from_json(json: &str) -> Result<Self>

Deserialize configuration from JSON

Enhanced observability manager with performance and convenience features

Methods

fn new(config: EnhancedObservabilityConfig) -> Result<Self>

Create new enhanced extension

fn initialize(&mut self) -> Result<()>

Initialize all configured features

fn is_performance_enabled(&self) -> bool

Check if performance features are enabled

fn is_correlation_enabled(&self) -> bool

Check if correlation features are enabled

fn is_convenience_enabled(&self) -> bool

Check if convenience features are enabled

fn base(&self) -> &ObservabilityManager

Get base observability manager

fn config(&self) -> &EnhancedObservabilityConfig

Get enhanced configuration

fn process_log_entry(&self, entry: LogEntry) -> Result<LogEntry>

Process log entry through all enabled features

fn get_performance_stats(&self) -> Option<PerformanceStats>

Get performance statistics (if enabled)

fn reset_performance_stats(&self) -> Result<()>

Reset performance statistics (if enabled)

fn get_panic_stats(&self) -> Result<PanicStats>

Get panic statistics if panic handler is enabled

fn reset_panic_stats(&self) -> Result<()>

Reset panic statistics if panic handler is enabled

fn capabilities(&self) -> Vec<&''static str>

Get manager capabilities

Configuration for panic logging

Fields

FieldTypeDescription
enable_structured_loggingboolEnable structured panic logging
enable_analyticsboolEnable panic analytics and pattern detection
enable_context_preservationboolEnable context preservation across panics

Panic pattern for analytics

Fields

FieldTypeDescription
patternString
countu64
first_seenString
last_seenString

Panic statistics for monitoring

Fields

FieldTypeDescription
total_panicsu64Total panics encountered
panics_by_severityHashMap&lt;String, u64&gt;Panics by severity
panics_by_threadHashMap&lt;String, u64&gt;Panics by thread
common_patternsVec&lt;PanicPattern&gt;Most common panic patterns
last_panic_timestampOption&lt;String&gt;Last panic timestamp

Structured panic information for downstream systems

Fields

FieldTypeDescription
messageStringPanic message
locationOption&lt;String&gt;Panic location (file:line:column)
thread_infoThreadInfoThread name and ID
timestampStringTimestamp when panic occurred (ISO 8601)
severityPanicSeverityPanic severity classification
trace_contextOption&lt;domain::TraceContext&gt;Preserved trace context
enhanced_contextOption&lt;EnhancedTraceContext&gt;Enhanced correlation context
metadataHashMap&lt;String, serde_json::Value&gt;Additional metadata

Thread information for panic context

Fields

FieldTypeDescription
nameOption&lt;String&gt;
idString
is_mainbool

Buffer pool for reusing formatting buffers

Methods

fn new(pool_size: usize, buffer_capacity: usize) -> Self
fn get_buffer(&self) -> Result<Vec<u8>>
fn return_buffer(&self, buffer: Vec<u8>) -> Result<()>

Fast path logger for hot code paths with minimal allocations

Methods

fn new(config: &PerformanceConfig) -> Result<Self>
fn log_llm_request_fast(&self, model: &str, duration_ms: u64, tokens: u32, status: &str) -> Result<Vec<u8>>

Fast path for LLM request logging with minimal allocations

fn log_a2a_message_fast(&self, message_type: &str, from_agent: &str, to_agent: &str, duration_ms: Option<u64>) -> Result<Vec<u8>>

Fast path for A2A message logging

Optimized WASM stdout adapter with performance enhancements

Methods

fn new(config: PerformanceConfig) -> Result<Self>
fn write_entry_optimized(&self, entry: &LogEntry) -> Result<()>

Write log entry using fast path if possible

fn get_stats(&self) -> Result<PerformanceStats>

Performance statistics for monitoring optimization impact

Fields

FieldTypeDescription
entries_processedu64Total entries processed
fast_path_timeweb_time::DurationTotal time spent in fast paths
standard_path_timeweb_time::DurationTotal time spent in standard paths
string_interner_hitsu64Number of string interning hits
string_interner_missesu64Number of string interning misses
buffer_pool_hitsu64Buffer pool hits
buffer_pool_missesu64Buffer pool misses (new allocations)
bytes_writtenu64Total bytes written
avg_processing_time_nsu64Average entry processing time

Methods

fn string_interner_hit_ratio(&self) -> f64

Calculate string interning hit ratio

fn buffer_pool_hit_ratio(&self) -> f64

Calculate buffer pool hit ratio

fn fast_path_ratio(&self) -> f64

Calculate fast path usage ratio

String interner for common log field values

Methods

fn new(capacity: usize) -> Result<Self>
fn intern_string(&self, value: &str) -> Result<String>
fn process_entry(&self, entry: LogEntry) -> Result<LogEntry>

W3C baggage support manager

Methods

fn new(config: CorrelationConfig) -> Self
fn validate_baggage_item(&self, key: &str, value: &str) -> Result<()>

Validate baggage item

fn add_system_baggage(&self, ctx: &mut EnhancedTraceContext, operation: &str) -> Result<()>

Add system baggage for agent operations

Correlation processor for log entries

Methods

fn new(config: CorrelationConfig) -> Self
fn process_entry(&self, entry: LogEntry) -> Result<LogEntry>

Process log entry to add correlation information

Enhanced trace context with additional correlation capabilities

Fields

FieldTypeDescription
basedomain::TraceContextBase trace context from observability_core
baggageHashMap&lt;String, String&gt;W3C baggage for cross-cutting concerns
scoped_contextsVec&lt;ScopedContext&gt;Scoped context stack for nested operations
correlation_metadataHashMap&lt;String, serde_json::Value&gt;Correlation metadata

Methods

fn new(base: TraceContext) -> Self

Create new enhanced trace context

fn from_w3c_headers(trace_parent: &str, _trace_state: Option<&str>) -> Result<Self>

Create from W3C trace headers

fn add_baggage(&mut self, key: String, value: String) -> Result<()>

Add baggage item

fn get_baggage(&self, key: &str) -> Option<&String>

Get baggage item

fn remove_baggage(&mut self, key: &str) -> Option<String>

Remove baggage item

fn push_scope(&mut self, scope_name: String, metadata: HashMap<String, Value>) -> Result<String>

Push new scoped context

fn pop_scope(&mut self) -> Option<ScopedContext>

Pop current scoped context

fn current_scope(&self) -> Option<&ScopedContext>

Get current scope

fn add_correlation_metadata(&mut self, key: String, value: Value)

Add correlation metadata

fn get_correlation_metadata(&self) -> &HashMap<String, Value>

Get correlation metadata

fn to_baggage_header(&self) -> String

Convert to W3C baggage header format

fn from_baggage_header(&mut self, baggage_header: &str) -> Result<()>

Parse from W3C baggage header

Scoped context manager for nested operations

Methods

fn new(config: CorrelationConfig) -> Self
fn enter_scope(&self, trace_id: &str, scope_name: String, metadata: HashMap<String, Value>) -> Result<String>

Enter a new scope

fn exit_scope(&self, trace_id: &str) -> Result<Option<ScopedContext>>

Exit current scope

fn current_scope(&self, trace_id: &str) -> Result<Option<ScopedContext>>

Get current scope

fn register_context(&self, ctx: EnhancedTraceContext) -> Result<()>

Register new trace context

fn unregister_context(&self, trace_id: &str) -> Result<()>

Unregister trace context

W3C baggage support utilities

Methods

fn extract_from_headers(headers: &HashMap<String, String>) -> Result<HashMap<String, String>>

Extract baggage from HTTP headers

fn inject_into_headers(baggage: &HashMap<String, String>, headers: &mut HashMap<String, String>)

Inject baggage into HTTP headers

Context for A2A operations

Fields

FieldTypeDescription
message_typeString
from_agentString
to_agentString
componentString
operation_startString

Convenience manager that integrates domain-aware processing into the processor chain

Methods

fn new() -> Result<Self>

Create new convenience manager

fn process_entry(&self, entry: LogEntry) -> Result<LogEntry>

Process log entry through domain-aware enhancement

fn get_processor(&self) -> &DomainContextProcessor

Get the domain context processor for integration with processor chain

Processor that automatically enhances standard log calls with domain-specific structure

Methods

fn new() -> Self

Context for LLM operations

Fields

FieldTypeDescription
modelString
componentString
operation_startString

Context for template operations

Fields

FieldTypeDescription
engineString
templateString
componentString
operation_startString

RAII guard for A2A context

Automatically clears A2A context when dropped, providing exception-safe cleanup.

Combined RAII guard for all contexts

When dropped, clears all contexts in the correct order. This is the safest option for complex operations.

RAII guard for LLM context

When this guard is dropped, the LLM context is automatically cleared. This ensures exception-safe cleanup and prevents forgetting to clear context.

{
let _guard = set_llm_context_scoped("gpt-4", "openai_client");
log::info!("This will have LLM context");
}
log::info!("This will NOT have LLM context");

RAII guard for request context

Automatically clears request context when dropped, providing exception-safe cleanup.

Scoped context builder for complex nested operations

Allows building up contexts step by step with automatic cleanup. Each context level gets its own guard for fine-grained control.

Methods

fn new() -> Self
fn with_llm_context(self, model: &str, component: &str) -> Self
fn with_a2a_context(self, message_type: &str, from_agent: &str, to_agent: &str, component: &str) -> Self
fn with_request_context(self, request_id: &str, user_id: Option<&str>, session_id: Option<&str>) -> Self
fn execute<F, R>(&self, f: F) -> R
where
F: FnOnce

Execute a closure with all built contexts active

Adapter implementing A2A context management for structured_logging

Registry coordinating all structured_logging context managers

Methods

fn new() -> Self

Create a new registry with all structured_logging context managers

fn register(&self)

Register this registry with the global context system

Adapter implementing LLM context management for structured_logging

Adapter implementing request context management for structured_logging

Convenience feature configuration

Fields

FieldTypeDescription
enable_llm_loggingboolEnable LLM operation logging
enable_template_loggingboolEnable template rendering logging
enable_a2a_loggingboolEnable A2A message logging
enable_convenience_macrosboolEnable convenience macros
enable_domain_fieldsboolEnable domain-specific field extraction

Correlation enhancement configuration

Fields

FieldTypeDescription
enable_baggageboolEnable W3C baggage support
max_baggage_sizeusizeMaximum baggage size in bytes
enable_scoped_contextboolEnable scoped context management
max_context_depthusizeMaximum context nesting depth
enable_auto_propagationboolEnable automatic context propagation

Performance optimization configuration

Fields

FieldTypeDescription
enable_string_interningboolEnable string interning for common log field values
string_interner_capacityusizeInitial capacity for string interner
enable_buffer_poolingboolEnable buffer pooling for log formatting
buffer_pool_sizeusizeInitial buffer pool size
buffer_capacityusizeIndividual buffer capacity in bytes
enable_fast_pathsboolEnable zero-allocation fast paths for hot operations
enable_wasm_optimizationsboolEnable WASM-specific memory optimizations

Enhanced error types for structured logging operations

Variants

VariantDescription
Observability(observability_core::ObservabilityError)Wraps observability_core errors
Performance { ... }Performance optimization errors
StringInterning { ... }String interning errors
BufferPool { ... }Buffer pool errors
Correlation { ... }Correlation enhancement errors
Baggage { ... }Baggage management errors
ScopedContext { ... }Scoped context errors
Convenience { ... }Convenience API errors
EnhancedConfig { ... }Configuration errors specific to enhanced features
FastPath { ... }Fast path errors
FeatureNotEnabled { ... }Feature not enabled

Methods

fn performance<T>(message: T) -> Self

Create a performance error

fn string_interning<T>(message: T) -> Self

Create a string interning error

fn buffer_pool<T>(message: T) -> Self

Create a buffer pool error

fn correlation<T>(message: T) -> Self

Create a correlation error

fn baggage<T>(message: T) -> Self

Create a baggage error

fn scoped_context<T>(message: T) -> Self

Create a scoped context error

fn convenience<T>(message: T) -> Self

Create a convenience API error

fn enhanced_config<T>(message: T) -> Self

Create an enhanced configuration error

fn fast_path<T>(message: T) -> Self

Create a fast path error

fn feature_not_enabled<T>(feature: T) -> Self

Create a feature not enabled error

Panic severity levels for classification

Variants

VariantDescription
LowLow severity panic
MediumMedium severity panic
HighHigh severity panic
CriticalCritical severity panic
fn create_performance_extension(config: EnhancedObservabilityConfig) -> Result<PerformanceExtension>

Create performance extension from configuration

fn create_performance_extension_from_config(config_path: &str) -> Result<PerformanceExtension>

Create performance extension from configuration file

fn get_panic_stats() -> Result<PanicStats>

Get panic statistics if handler is installed

fn install_panic_handler() -> Result<()>

Install panic handler with default configuration

fn install_panic_handler_with_config(config: PanicHandlerConfig) -> Result<()>

Install panic handler with custom configuration

fn reset_panic_stats() -> Result<()>

Reset panic statistics if handler is installed

fn clear_a2a_context()

Clear A2A context only

fn clear_all_contexts()

Clear all contexts

fn clear_llm_context()

Clear LLM context only

fn clear_request_context()

Clear request context only

fn clear_template_context()

Clear template context only

fn emit_a2a_message_latency(latency_ms: u64) -> Result<()>

Emit an A2A message latency metric with context

fn emit_counter(name: &str, value: f64) -> Result<()>

Generic counter metric with automatic context detection

fn emit_histogram(name: &str, value: f64) -> Result<()>

Generic histogram metric with automatic context detection

fn emit_llm_request_duration(model: &str, duration_ms: u64) -> Result<()>

Emit an LLM request duration metric with context

fn emit_llm_tokens_used(model: &str, tokens: u32) -> Result<()>

Emit an LLM token usage metric with context

fn emit_request_duration(duration_ms: u64) -> Result<()>

Emit request processing duration metric with context

fn emit_template_render_duration(template: &str, duration_ms: u64) -> Result<()>

Emit a template render duration metric with context

fn log_a2a_message(message_type: &str, from_agent: &str, to_agent: &str, duration: Option<web_time::Duration>, status: &str) -> Result<observability_core::LogEntry>

Convenience function to log A2A messages with structured format

fn log_llm_request(model: &str, duration: web_time::Duration, tokens: u32, status: &str) -> Result<observability_core::LogEntry>

Convenience function to log LLM requests with structured format

fn log_template_render(engine: &str, template: &str, duration: web_time::Duration, size: usize, status: &str) -> Result<observability_core::LogEntry>

Convenience function to log template rendering with structured format

fn set_a2a_context(message_type: &str, from_agent: &str, to_agent: &str, component: &str)

Set A2A context

fn set_llm_context(model: &str, component: &str)

Set LLM context

fn set_request_context(request_id: &str, user_id: Option<&str>, session_id: Option<&str>)

Set request context

fn set_template_context(engine: &str, template: &str, component: &str)

Set template context

fn init_context_integration()

Initialize structured_logging context management integration

Call this once during application startup to enable advanced RAII context management features in structured_logging.

use structured_logging::context_adapter::init_context_integration;
init_context_integration();
let _guard = set_llm_context_scoped("gpt-4", "my_component");
log::info!("This log will have LLM context automatically");
fn set_a2a_context_scoped(message_type: &str, from_agent: &str, to_agent: &str, component: &str) -> A2aContextGuard

Set A2A context with RAII guard

Returns a guard that will automatically clear the context when dropped.

fn set_all_contexts_scoped(model: &str, component: &str, message_type: &str, from_agent: &str, to_agent: &str, a2a_component: &str, request_id: &str, user_id: Option<&str>, session_id: Option<&str>) -> AllContextsGuard

Set all contexts with combined RAII guard

Returns a guard that will automatically clear all contexts when dropped. This is the most comprehensive option for complex operations.

fn set_llm_context_scoped(model: &str, component: &str) -> LlmContextGuard

Set LLM context with RAII guard

Returns a guard that will automatically clear the context when dropped. This is the safest way to set LLM context as cleanup is guaranteed.

let _guard = set_llm_context_scoped("gpt-4", "openai_client");
log::info!("Processing LLM request");
fn set_request_context_scoped(request_id: &str, user_id: Option<&str>, session_id: Option<&str>) -> RequestContextGuard

Set request context with RAII guard

Returns a guard that will automatically clear the context when dropped.

fn with_a2a_context<F, R>(message_type: &str, from_agent: &str, to_agent: &str, component: &str, f: F) -> R
where
F: FnOnce

Execute a closure with A2A context, automatically clearing when done

fn with_all_contexts<F, R>(model: &str, component: &str, message_type: &str, from_agent: &str, to_agent: &str, a2a_component: &str, request_id: &str, user_id: Option<&str>, session_id: Option<&str>, f: F) -> R
where
F: FnOnce

Execute a closure with all contexts, automatically clearing when done

This is the most comprehensive scoped API that sets all contexts and guarantees cleanup regardless of how the closure exits.

fn with_llm_context<F, R>(model: &str, component: &str, f: F) -> R
where
F: FnOnce

Execute a closure with LLM context, automatically clearing when done

This is the most secure pattern as it guarantees context cleanup even if the closure panics or returns early.

let result = with_llm_context("gpt-4", "openai_client", || {
log::info!("This has LLM context");
process_llm_request()
});
fn with_request_context<F, R>(request_id: &str, user_id: Option<&str>, session_id: Option<&str>, f: F) -> R
where
F: FnOnce

Execute a closure with request context, automatically clearing when done

fn create_logger() -> ObservabilityResult<ObservabilityManager>

Create a logger using observability_core foundation

fn create_performance_logger() -> Result<PerformanceExtension>

Create an enhanced logger with performance optimizations

fn create_logger_from_config(config: ObservabilityConfig) -> ObservabilityResult<ObservabilityManager>

Create logger from configuration

fn create_enhanced_logger_from_config(config: EnhancedObservabilityConfig) -> Result<PerformanceExtension>

Create enhanced logger from enhanced configuration

Set LLM context for subsequent standard log calls

Set template context for subsequent standard log calls

Set A2A context for subsequent standard log calls

Clear all domain contexts

Convenience macros for structured logging

Macro for easy scoped LLM context

with_llm_context_scoped!("gpt-4", "openai_client" => {
log::info!("Processing with LLM context");
});

Macro for easy scoped A2A context

Macro for easy scoped request context

Macro for supervised execution with panic capturing