Structured Logging with Tracing¶
Note for Python users: This page documents the Rust-internal
tracing_configmodule, which is not exposed to the Python package. There is noevlib.tracing_configin Python. To control Rust log verbosity from Python, set theRUST_LOGenvironment variable before importing evlib (for exampleos.environ['RUST_LOG'] = 'evlib=debug').
evlib uses the tracing crate for structured, configurable logging. This provides better control over log verbosity, structured output, and integration with external logging systems.
Quick Start¶
Basic Setup¶
use evlib::tracing_config;
// Initialize with sensible defaults
tracing_config::init();
// Now load events - logging will be structured and configurable
let events = evlib::ev_formats::load_events_with_config("tests/data/eTram/h5/val_2/val_night_011_td.h5", &config)?;
Environment Variable Control¶
Control logging via the RUST_LOG environment variable:
# Default: INFO level for evlib, WARN for everything else
cargo run
# Enable debug logging for evlib
RUST_LOG=evlib=debug cargo run
# Only show warnings and errors
RUST_LOG=evlib=warn cargo run
# Very detailed tracing for specific module
RUST_LOG=evlib::ev_formats::prophesee_ecf_codec=trace cargo run
# Multiple module control
RUST_LOG="evlib::ev_formats=debug,evlib::ev_representations=info" cargo run
Log Levels¶
evlib uses the following log levels:
ERROR - Critical Failures¶
- Model loading failures
- File parsing errors
- System-level problems
- Fallback mechanism failures
Example output:
2024-01-15T10:30:45.123456Z ERROR evlib::ev_formats::mod: Python fallback failed error="File not found"
WARN - Warnings and Fallbacks¶
- Fallback behaviors activated
- Unsupported file formats
- Missing optional dependencies
- Performance degradation warnings
Example output:
2024-01-15T10:30:45.123456Z WARN evlib::ev_formats::prophesee_ecf_codec: Unknown delta_bits value in ECF decoder delta_bits=7
INFO - Status and Progress¶
- File loading progress
- Model downloading status
- Successful operations
- Stream status updates
Example output:
2024-01-15T10:30:45.123456Z INFO evlib::ev_formats::mod: Native Rust ECF decoder loaded events events=1048576
DEBUG - Development Information¶
- Detailed ECF decoding steps
- WebSocket connection details
- Model verification results
- Internal state information
Example output:
2024-01-15T10:30:45.123456Z DEBUG evlib::ev_formats::prophesee_ecf_codec: ECF base timestamp base_timestamp=1627849200000000
TRACE - Very Detailed Debug¶
- Low-level operations
- Performance timing
- Memory allocation details
Note: Currently no TRACE level logs in evlib, reserved for future use.
Configuration Options¶
Default Configuration¶
use evlib::tracing_config;
// Standard configuration - good for most use cases
tracing_config::init();
Debug Configuration¶
use evlib::tracing_config;
// Enables debug logging with file/line information
tracing_config::init_debug();
Custom Configuration¶
use evlib::tracing_config;
// Fine-grained control over specific modules
tracing_config::init_with_filter("evlib::ev_formats=trace,evlib=info");
Production Configuration¶
use evlib::tracing_config::examples;
// JSON output suitable for log aggregation
examples::init_production();
Development Configuration¶
use evlib::tracing_config::examples;
// Pretty-printed output with colors and extra context
examples::init_development();
Integration Examples¶
With env_logger style¶
use tracing_subscriber::{EnvFilter, fmt};
// Similar to env_logger but with structured output
fmt()
.with_env_filter(EnvFilter::from_default_env())
.init();
With syslog¶
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
tracing_subscriber::registry()
.with(tracing_syslog::layer())
.with(EnvFilter::from_default_env())
.init();
With File Output¶
use tracing_subscriber::{fmt, EnvFilter};
use std::fs::File;
let file = File::create("evlib.log")?;
fmt()
.with_writer(file)
.with_env_filter(EnvFilter::from_default_env())
.init();
With JSON for Kubernetes/Docker¶
use tracing_subscriber::{fmt, EnvFilter};
fmt()
.json()
.with_env_filter(EnvFilter::from_default_env())
.init();
Testing Integration¶
#[cfg(test)]
mod tests {
use evlib::tracing_config;
#[test]
fn test_event_loading() {
// Initialize tracing for tests
tracing_config::init_test();
// Test code here - logs will be captured in test output
let events = evlib::ev_formats::load_events_from_text("tests/data/test.txt")?;
}
}
Python Integration¶
When using evlib from Python, you can still control Rust logging:
import os
import evlib
# Set logging level before importing/using evlib
os.environ['RUST_LOG'] = 'evlib=debug'
# Initialize tracing from Python (if exposed)
# Note: This requires exposing tracing_config functions to Python
# evlib.tracing_config.init()
# Load events - Rust logs will be controlled by RUST_LOG
events = evlib.load_events('tests/data/eTram/h5/val_2/val_night_011_td.h5')
print(f"Loaded events with shape: {events.collect().shape}")
Performance Considerations¶
Runtime Overhead¶
trace!anddebug!macros compile to no-ops when disabledinfo!,warn!,error!have minimal overhead when disabled- Structured logging is more efficient than string formatting
- Filtering happens at compile time when possible
Memory Usage¶
- Structured logs use less memory than formatted strings
- Span context tracking has minimal overhead
- Field values are lazily formatted only when logged
Common Patterns¶
Module-Specific Debugging¶
# Debug only ECF decoding
RUST_LOG=evlib::ev_formats::prophesee_ecf_codec=debug cargo run
# Debug all format readers
RUST_LOG=evlib::ev_formats=debug cargo run
# Debug HDF5 reading specifically
RUST_LOG=evlib::ev_formats::hdf5_reader=debug cargo run
The deep-learning models (E2VID, RVT) are implemented in Python under
python/evlib/models/, not in the Rust crate, so they are not controlled by
RUST_LOG. To debug model loading, configure Python logging instead:
Production Logging¶
# Minimal logging for production
RUST_LOG=evlib=warn cargo run
# Structured JSON for log aggregation
RUST_LOG=evlib=info cargo run > logs.json
Development Debugging¶
# Comprehensive debugging
RUST_LOG=evlib=debug cargo run
# Very detailed tracing
RUST_LOG=evlib=trace cargo run
Migration from println!/eprintln!¶
Old code using print statements:
New structured logging:
use tracing::{info, error};
info!(events = events.len(), "Loading events from file");
error!(error = %error, "ECF decoder failed");
Benefits¶
- Configurable Verbosity: Control logging at runtime without recompilation
- Structured Output: Key-value pairs for better parsing and filtering
- Performance: Debug logs compile to no-ops when disabled
- Integration: Works with existing Rust logging ecosystem
- Consistency: Uniform logging patterns across the entire library
- Observability: Better debugging and monitoring capabilities
Troubleshooting¶
No Logs Appearing¶
- Check that tracing is initialized:
tracing_config::init() - Verify
RUST_LOGenvironment variable:RUST_LOG=evlib=debug - Ensure log level is appropriate for desired messages
Too Many Logs¶
- Increase filter level:
RUST_LOG=evlib=warn - Use module-specific filtering:
RUST_LOG=evlib::ev_formats=info - Switch to production configuration for cleaner output
JSON Parsing Issues¶
- Use
fmt().json()for consistent JSON output - Ensure no mixed output formats in configuration
- Consider using dedicated JSON logging libraries for complex parsing
For more information, see the tracing documentation and tracing-subscriber documentation.