Debug Logging Guide
Comprehensive guide to debug logging throughout the Armature framework.
Table of Contents
Overview
Armature includes comprehensive debug logging throughout the framework to help with:
- Development - Understanding application flow
- Debugging - Tracking down issues
- Monitoring - Observing production behavior
- Performance - Identifying bottlenecks
All logging uses the tracing ecosystem for structured, high-performance logging.
Enabling Debug Logging
Development Mode
Enable debug logging for development:
use armature_core::*;
#[tokio::main]
async fn main() {
// Pretty format with debug level
let config = LogConfig::new()
.level(LogLevel::Debug)
.format(LogFormat::Pretty)
.with_colors(true)
.with_targets(true)
.with_file_line(true);
let _guard = Application::init_logging_with_config(config);
// Your application code
}
Via Environment Variable
Set log level via RUST_LOG:
# Debug for all
RUST_LOG=debug cargo run
# Debug for Armature only
RUST_LOG=armature=debug cargo run
# Trace for specific module
RUST_LOG=armature_core::application=trace cargo run
# Mixed levels
RUST_LOG=armature=debug,hyper=info cargo run
Logged Components
1. Application Bootstrap
What's Logged:
- Module registration
- Provider registration
- Controller registration
- Lifecycle hook execution
- Application startup
Log Levels:
INFO- High-level bootstrap stepsDEBUG- Module/provider/controller detailsTRACE- Internal operations
Example Output:
{
"timestamp": "2024-12-06T12:00:00.123Z",
"level": "INFO",
"message": "Bootstrapping Armature application"
}
{
"level": "DEBUG",
"module_type": "app::AppModule",
"message": "Creating application from root module"
}
{
"level": "DEBUG",
"message": "DI container initialized"
}
{
"level": "DEBUG",
"module_type": "app::AppModule",
"import_count": 2,
"message": "Registering imported modules"
}
{
"level": "DEBUG",
"module_type": "app::AppModule",
"provider_count": 5,
"message": "Registering providers"
}
{
"level": "DEBUG",
"module_type": "app::AppModule",
"provider": "UserService",
"message": "Provider registered"
}
{
"level": "DEBUG",
"module_type": "app::AppModule",
"controller_count": 3,
"message": "Registering controllers"
}
{
"level": "DEBUG",
"controller": "UserController",
"base_path": "/users",
"message": "Controller registered"
}
{
"level": "INFO",
"message": "Application bootstrap complete"
}
2. Dependency Injection Container
What's Logged:
- Provider registration
- Provider resolution
- Factory invocations
- Provider lookups
Log Levels:
DEBUG- Registration and resolutionTRACE- Lock acquisition, existence checks
Example Output:
{
"level": "DEBUG",
"message": "Creating new DI container"
}
{
"level": "DEBUG",
"provider": "UserService",
"message": "Provider registered in DI container"
}
{
"level": "TRACE",
"provider": "DatabaseService",
"message": "Attempting to resolve provider"
}
{
"level": "DEBUG",
"provider": "DatabaseService",
"message": "Provider resolved successfully"
}
{
"level": "DEBUG",
"provider": "NonExistentService",
"message": "Provider not found in container"
}
3. HTTP Server
What's Logged:
- Server binding and startup
- Connection acceptance
- TLS handshakes
- Connection errors
Log Levels:
INFO- Server startedDEBUG- Binding details, TLS successTRACE- Connection acceptanceERROR- Connection/TLS failures
Example Output:
{
"level": "DEBUG",
"address": "0.0.0.0:3000",
"message": "Binding to address"
}
{
"level": "INFO",
"address": "0.0.0.0:3000",
"message": "HTTP server listening"
}
{
"level": "TRACE",
"client_address": "192.168.1.100:54321",
"message": "Connection accepted"
}
{
"level": "ERROR",
"error": "connection reset by peer",
"client": "192.168.1.100:54321",
"message": "Error serving connection"
}
4. HTTP Request Handling
What's Logged:
- Request receipt
- Header parsing
- Body parsing
- Routing
- Response generation
- Request duration
Log Levels:
DEBUG- Request routing and completionTRACE- Request details, headers, bodyWARN- Request handling failures
Example Output:
{
"level": "TRACE",
"method": "POST",
"path": "/api/users",
"message": "Incoming request"
}
{
"level": "TRACE",
"header_count": 8,
"message": "Headers parsed"
}
{
"level": "TRACE",
"body_size": 256,
"message": "Request body received"
}
{
"level": "DEBUG",
"method": "POST",
"path": "/api/users",
"message": "Routing request"
}
{
"level": "DEBUG",
"method": "POST",
"path": "/api/users",
"status": 201,
"message": "Request handled successfully"
}
{
"level": "DEBUG",
"method": "POST",
"path": "/api/users",
"status": 201,
"duration_ms": 45,
"message": "Request completed"
}
5. Lifecycle Hooks
What's Logged:
- Hook execution start/completion
- Hook failures
- Shutdown sequence
Log Levels:
INFO- Lifecycle phase changesDEBUG- Individual hook executionWARN- Hook failuresERROR- Hook errors with details
Example Output:
{
"level": "INFO",
"message": "Executing lifecycle hooks"
}
{
"level": "DEBUG",
"message": "Calling OnModuleInit hooks"
}
{
"level": "DEBUG",
"message": "All OnModuleInit hooks completed successfully"
}
{
"level": "DEBUG",
"message": "Calling OnApplicationBootstrap hooks"
}
{
"level": "ERROR",
"hook_name": "DatabaseService::on_bootstrap",
"error": "Connection refused",
"message": "Bootstrap hook failed"
}
{
"level": "INFO",
"signal": "SIGTERM",
"message": "Gracefully shutting down application"
}
{
"level": "DEBUG",
"message": "Calling OnApplicationShutdown hooks"
}
{
"level": "INFO",
"message": "Application shutdown complete"
}
Log Levels
TRACE (Most Verbose)
When to use: Deep debugging, tracking exact execution flow
What's logged:
- Connection acceptance details
- Request/response headers and bodies
- Lock acquisition
- Provider existence checks
- Internal state transitions
Example:
{"level": "TRACE", "client_address": "192.168.1.100:54321", "message": "Connection accepted"}
DEBUG
When to use: Development, troubleshooting, understanding behavior
What's logged:
- Module/provider/controller registration
- Provider resolution
- Request routing
- Hook execution
- TLS handshakes
- Request completion with metrics
Example:
{"level": "DEBUG", "provider": "UserService", "message": "Provider registered in DI container"}
INFO
When to use: Production monitoring, high-level tracking
What's logged:
- Application bootstrap
- Server startup
- Lifecycle phase changes
- Shutdown sequence
Example:
{"level": "INFO", "address": "0.0.0.0:3000", "message": "HTTP server listening"}
WARN
When to use: Potential issues, degraded performance
What's logged:
- Hook failures (non-fatal)
- Request handling issues
- Retry attempts
Example:
{"level": "WARN", "error_count": 2, "message": "Some module init hooks failed"}
ERROR
When to use: Failures, exceptions, errors
What's logged:
- Connection errors
- TLS handshake failures
- Hook failures with details
- Provider instantiation failures
- Request routing errors
Example:
{"level": "ERROR", "error": "connection reset", "client": "192.168.1.100:54321", "message": "Error serving connection"}
Examples
Example 1: Debug Application Bootstrap
use armature_core::*;
#[tokio::main]
async fn main() {
// Enable debug logging
let config = LogConfig::new()
.level(LogLevel::Debug)
.format(LogFormat::Pretty)
.with_colors(true);
let _guard = Application::init_logging_with_config(config);
// Bootstrap application - watch logs
let app = Application::create::<AppModule>().await;
// Start server
app.listen(3000).await.unwrap();
}
Output:
DEBUG Creating new DI container
DEBUG module_type="app::AppModule" Creating application from root module
DEBUG DI container initialized
DEBUG Router initialized
...
Example 2: Track Request Handling
let config = LogConfig::new()
.level(LogLevel::Trace) // TRACE for full request details
.format(LogFormat::Json);
let _guard = Application::init_logging_with_config(config);
Output:
{"level":"TRACE","method":"POST","path":"/api/users","message":"Incoming request"}
{"level":"TRACE","header_count":8,"message":"Headers parsed"}
{"level":"TRACE","body_size":256,"message":"Request body received"}
{"level":"DEBUG","method":"POST","path":"/api/users","message":"Routing request"}
{"level":"DEBUG","method":"POST","path":"/api/users","status":201,"duration_ms":45,"message":"Request completed"}
Example 3: Monitor Dependency Injection
let config = LogConfig::new()
.level(LogLevel::Debug)
.format(LogFormat::Pretty)
.with_env_filter("armature_core::container=debug");
let _guard = Application::init_logging_with_config(config);
Output:
DEBUG armature_core::container: provider="UserService" Provider registered in DI container
DEBUG armature_core::container: provider="DatabaseService" Attempting to resolve provider
DEBUG armature_core::container: provider="DatabaseService" Provider resolved successfully
Example 4: Debug Lifecycle Issues
let config = LogConfig::new()
.level(LogLevel::Debug)
.with_env_filter("armature=debug");
let _guard = Application::init_logging_with_config(config);
let app = Application::create::<AppModule>().await;
// Later, trigger shutdown
app.shutdown(Some("SIGTERM".to_string())).await.unwrap();
Output:
{"level":"DEBUG","message":"Calling OnModuleInit hooks"}
{"level":"DEBUG","message":"All OnModuleInit hooks completed successfully"}
...
{"level":"INFO","signal":"SIGTERM","message":"Gracefully shutting down application"}
{"level":"DEBUG","message":"Calling BeforeApplicationShutdown hooks"}
{"level":"DEBUG","message":"All BeforeApplicationShutdown hooks completed successfully"}
Troubleshooting
No Logs Appearing
Problem: Logs not showing up
Solutions:
Ensure logging is initialized:
let _guard = Application::init_logging(); // Don't drop!Check log level:
LogConfig::new().level(LogLevel::Debug) // Not Info!Check environment variable:
RUST_LOG=debug cargo run
Too Many Logs
Problem: Overwhelming log output
Solutions:
Filter by module:
.with_env_filter("armature_core::application=debug")Increase log level:
.level(LogLevel::Info) // Less verboseFilter out noisy crates:
.with_env_filter("armature=debug,hyper=warn,tokio=warn")
JSON Not Formatting
Problem: JSON logs not pretty-printing
Solution: JSON is meant for machines, use Pretty for humans:
LogConfig::new().format(LogFormat::Pretty)
Missing Structured Fields
Problem: Not seeing context fields in logs
Solutions:
Enable target to see module:
.with_targets(true)Use JSON format to see all fields:
.format(LogFormat::Json)
Summary
Key Takeaways
โ Comprehensive Coverage - All major components log their operations โ Structured Logging - Rich context with key-value pairs โ Multiple Levels - TRACE to ERROR for different needs โ Production Ready - Low overhead, configurable โ Easy Debugging - Clear, informative messages
Quick Reference
| Component | Log Level | What's Logged |
|---|---|---|
| Bootstrap | INFO | High-level steps |
| Bootstrap | DEBUG | Module/provider/controller details |
| DI Container | DEBUG | Registration and resolution |
| DI Container | TRACE | Internal operations |
| HTTP Server | INFO | Server startup |
| HTTP Server | DEBUG | Binding, TLS details |
| HTTP Server | TRACE | Connection acceptance |
| HTTP Requests | DEBUG | Routing, completion, metrics |
| HTTP Requests | TRACE | Headers, body, full details |
| Lifecycle | INFO | Phase changes |
| Lifecycle | DEBUG | Hook execution |
| Lifecycle | ERROR | Hook failures |
Recommended Configurations
Development:
LogConfig::new()
.level(LogLevel::Debug)
.format(LogFormat::Pretty)
.with_colors(true)
.with_file_line(true)
Production:
LogConfig::new()
.level(LogLevel::Info)
.format(LogFormat::Json)
.output(LogOutput::RollingFile { ... })
Troubleshooting:
LogConfig::new()
.level(LogLevel::Trace)
.format(LogFormat::Pretty)
.with_env_filter("armature=trace,problematic_module=trace")
Happy debugging! ๐โจ