✅ Validation Results: - PPO training: 24.2s (1 epoch, 950 samples, dim=225) - Feature extraction: 105μs/bar (9.5x faster than target) - Model checkpoint: 293KB (147KB actor + 146KB critic) - GPU memory: 145MB used (96.4% headroom) - Zero dimension mismatches 📊 Success Criteria (5/5): ✅ Feature dimension = 225 (Wave C 201 + Wave D 24) ✅ Model state_dim = 225 ✅ Training completed without errors ✅ Checkpoint saved successfully ✅ No dimension mismatch errors 📁 Training Data Ready: - ES.FUT: 2.9MB, 180 days - NQ.FUT: 4.4MB, 180 days - 6E.FUT: 2.8MB, 180 days - ZN.FUT: 65KB, 90 days (clean) 🚀 Next: Full production model retraining (4 models, ~10min GPU time) 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
137 lines
4.0 KiB
Rust
137 lines
4.0 KiB
Rust
//! Observability infrastructure for the Foxhunt HFT trading system.
|
|
//!
|
|
//! This module provides comprehensive observability capabilities including:
|
|
//! - Correlation ID generation and propagation across service boundaries
|
|
//! - Structured JSON logging with consistent format
|
|
//! - OpenTelemetry distributed tracing with Jaeger integration
|
|
//!
|
|
//! # Architecture
|
|
//!
|
|
//! The observability infrastructure follows a three-layer approach:
|
|
//!
|
|
//! 1. **Correlation Layer**: Generates and propagates correlation IDs across all services
|
|
//! via gRPC metadata, enabling request tracking across the entire system.
|
|
//!
|
|
//! 2. **Logging Layer**: Provides structured JSON logging with automatic correlation ID
|
|
//! injection, service identification, and log rotation.
|
|
//!
|
|
//! 3. **Tracing Layer**: Implements OpenTelemetry distributed tracing with parent-child
|
|
//! span linking, context propagation, and Jaeger export.
|
|
//!
|
|
//! # Usage
|
|
//!
|
|
//! ## Initialize Observability in Services
|
|
//!
|
|
//! ```rust,no_run
|
|
//! use common::observability::{init_observability, CorrelationId};
|
|
//!
|
|
//! #[tokio::main]
|
|
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
//! // Initialize observability infrastructure
|
|
//! init_observability("trading_service", "localhost:6831").await?;
|
|
//!
|
|
//! // Correlation IDs are automatically propagated via gRPC metadata
|
|
//! Ok(())
|
|
//! }
|
|
//! ```
|
|
//!
|
|
//! ## Log with Correlation ID
|
|
//!
|
|
//! ```rust,no_run
|
|
//! use tracing::{info, error};
|
|
//! use common::observability::CorrelationId;
|
|
//!
|
|
//! async fn handle_request() {
|
|
//! let correlation_id = CorrelationId::new();
|
|
//!
|
|
//! info!(
|
|
//! correlation_id = %correlation_id,
|
|
//! "Processing trade request"
|
|
//! );
|
|
//! }
|
|
//! ```
|
|
//!
|
|
//! ## Create Traced Spans
|
|
//!
|
|
//! ```rust,no_run
|
|
//! use tracing::{info_span, instrument};
|
|
//!
|
|
//! #[instrument(name = "process_order", skip(order))]
|
|
//! async fn process_order(order: Order) -> Result<(), Error> {
|
|
//! // Span is automatically created and linked to parent context
|
|
//! Ok(())
|
|
//! }
|
|
//! ```
|
|
|
|
pub mod correlation;
|
|
pub mod logger;
|
|
pub mod tracing_config;
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|
|
|
|
// Re-export commonly used types
|
|
pub use correlation::{CorrelationId, CorrelationIdExt, CORRELATION_ID_HEADER};
|
|
pub use logger::{init_json_logger, JsonLoggerConfig, LogLevel};
|
|
pub use tracing_config::{init_tracing, TracingConfig};
|
|
|
|
use crate::error::{CommonError, CommonResult};
|
|
|
|
/// Initialize the complete observability stack for a service.
|
|
///
|
|
/// This is a convenience function that initializes both logging and tracing
|
|
/// in a single call. It should be called early in the service startup process,
|
|
/// before any business logic executes.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `service_name` - Name of the service (e.g., "api_gateway", "trading_service")
|
|
/// * `jaeger_endpoint` - Jaeger agent endpoint (e.g., "localhost:6831")
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// Returns `Ok(())` on success, or an error if initialization fails.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust,no_run
|
|
/// use common::observability::init_observability;
|
|
///
|
|
/// #[tokio::main]
|
|
/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
/// init_observability("trading_service", "localhost:6831").await?;
|
|
///
|
|
/// // Service logic here...
|
|
/// Ok(())
|
|
/// }
|
|
/// ```
|
|
pub async fn init_observability(
|
|
service_name: &str,
|
|
jaeger_endpoint: &str,
|
|
) -> CommonResult<()> {
|
|
// Initialize JSON logger with default configuration
|
|
let logger_config = JsonLoggerConfig {
|
|
service_name: service_name.to_string(),
|
|
log_level: LogLevel::Info,
|
|
enable_console: true,
|
|
enable_file: true,
|
|
log_directory: format!("logs/{}", service_name),
|
|
rotation: logger::LogRotation::Daily,
|
|
max_files: 10,
|
|
max_file_size_mb: 100,
|
|
};
|
|
|
|
init_json_logger(logger_config)?;
|
|
|
|
// Initialize OpenTelemetry tracing
|
|
let tracing_config = TracingConfig {
|
|
service_name: service_name.to_string(),
|
|
jaeger_endpoint: jaeger_endpoint.to_string(),
|
|
enable_jaeger: true,
|
|
};
|
|
|
|
init_tracing(tracing_config).await?;
|
|
|
|
Ok(())
|
|
}
|