log_args
Procedural macro crate providing the #[params]
attribute for automatic parameter logging and context propagation in Rust applications.
Note: This is part of the log-args workspace. For complete setup and examples, see the main documentation.
✨ Key Features
- Automatic Context Inheritance: Child functions inherit parent context with
#[params(span(...))]
- Cross-Boundary Propagation: Works across async/await, spawned tasks, and closures
- Selective Logging: Choose specific parameters with
fields(...)
- Custom Fields: Add computed metadata with
custom(...)
- Secure by Default: Sensitive parameters excluded unless explicitly specified
- Zero Runtime Overhead: Compile-time macro expansion
🚀 Getting Started
Step 1: Installation
Add these dependencies to your Cargo.toml
:
[]
= "0.1.6"
= { = "0.1.4", = ["with_context"] }
= "0.1"
= { = "0.3", = ["json"] }
Step 2: Basic Setup
Set up structured JSON logging in your main.rs
:
use params;
use ;
Step 3: Start Simple
Begin with the secure default behavior:
// Secure: no parameters logged
Step 4: Add Context Propagation
Enable automatic context inheritance:
// Set up context
// Inherits request_id and user_id automatically
Step 5: Add Selective Logging (Production-Ready)
Log only specific parameters:
// Only log safe parameters
🎉 Congratulations! You now have automatic context propagation and secure parameter logging set up.
🚀 Quick Start
use params;
use ;
// Default behavior - context propagation only
// Span context propagation
## 📖 Complete Attribute Reference
The ` ` macro supports multiple attributes that can be combined to create flexible logging strategies. Here's a comprehensive guide to all available attributes:
### ` ` - Default Behavior
**Purpose**: Enables context inheritance without logging any parameters.
```rust
When to use:
- ✅ Production functions with sensitive data
- ✅ When you only need context inheritance
- ✅ Default choice for security
#[params(fields(...))]
- Selective Parameter Logging
Purpose: Log only specific function parameters as individual fields.
When to use:
- ✅ Production logging with specific data needs
- ✅ When you need precise control over logged data
- ✅ Compliance and security requirements
#[params(span(...))]
- Context Propagation
Purpose: Set up automatic context inheritance for child functions.
Cross-boundary support:
- ✅ Async/await boundaries
- ✅ Spawned tasks (
tokio::spawn
) - ✅ Closures and iterators
- ✅ Thread boundaries
When to use:
- ✅ Distributed tracing
- ✅ Request/session tracking
- ✅ Microservices architecture
#[params(custom(...))]
- Computed Fields
Purpose: Add computed fields using custom expressions.
When to use:
- ✅ Adding metadata and timestamps
- ✅ Computed values and flags
- ✅ Environment information
Performance tip: Keep expressions lightweight as they're evaluated on every log call.
#[params(all)]
- Log All Parameters
Purpose: Log all function parameters as individual fields.
// ⚠️ Use with caution!
⚠️ Security Warning: This logs ALL parameters, including sensitive data!
When to use:
- ✅ Development and debugging
- ✅ Non-production environments
- ❌ Production environments
- ❌ Functions with sensitive parameters
#[params(clone_upfront)]
- Async-Safe Parameter Cloning
Purpose: Clone parameters before async operations to prevent ownership issues.
async
When to use:
- ✅ Async functions with spawned tasks
- ✅ When parameters need to be moved into closures
- ✅ Complex async workflows
Performance note: Only use when necessary as it adds cloning overhead.
#[params(auto_capture)]
- Automatic Context Capture
Purpose: Automatically capture context in closures and spawned tasks.
When to use:
- ✅ Complex async workflows
- ✅ Iterator chains with closures
- ✅ Nested task spawning
🔧 Combining Attributes
You can combine multiple attributes for powerful logging strategies:
async
🔧 Troubleshooting
Fields Not Appearing in Logs?
Problem: Your fields aren't showing up in the JSON output.
Solution: Ensure your tracing subscriber is configured correctly:
// ✅ Correct setup
fmt
.json
.flatten_event // This is crucial!
.init;
// ❌ Wrong - fields will be nested
fmt
.json
// Missing .flatten_event(true)
.init;
Context Not Propagating?
Problem: Child functions aren't inheriting context from parent functions.
Solution: Use span(...)
for propagation, not fields(...)
:
// ❌ Wrong - fields() doesn't propagate context
// ✅ Correct - span() propagates context
Compilation Errors?
Problem: Field names don't match parameter names.
// ❌ Error - field name doesn't exist
// user_id ≠ nonexistent_field
// ✅ Correct - field names match parameters
Quick Debug Tips
- Start simple: Begin with
#[params]
and add complexity gradually - Check field names: Ensure they exactly match parameter names
- Verify setup: Make sure
flatten_event(true)
is enabled - Use examples: Run the workspace examples to see working code
📚 Examples
See the workspace examples for runnable demonstrations:
License
MIT - See LICENSE for details.