log_args
A procedural macro for structured logging of function arguments using the tracing
crate, with truly automatic context inheritance across all boundaries.
This crate provides a procedural macro attribute #[params]
that can be applied to functions to automatically log their arguments and propagate context. It seamlessly integrates with the tracing
ecosystem for structured logging, offering enhanced flexibility for both synchronous and asynchronous functions.
- ๐ฏ Truly Automatic Context Inheritance - Child functions inherit parent context with just
#[params]
- ๐ Cross-Boundary Propagation - Works across closures, async spawns, and WebSocket upgrades
- ๐ Zero-overhead logging - Compile-time macro expansion
- ๐ง Flexible field selection - Log only what you need with
fields(...)
- ๐ท๏ธ Custom metadata - Add static fields with
custom(...)
- ๐ Span context propagation - Automatic context inheritance with
span
- โก Full async support - Works seamlessly with async/await
- ๐ฏ Function name logging - Configurable casing styles via Cargo features
- ๐ Security-conscious - Selective logging to exclude sensitive data
- ๐ Structured JSON output - Perfect for log aggregation and analysis
- ๐ ๏ธ Production-ready - Comprehensive examples and robust error handling
๐ Quick Start
Basic Usage
By default, #[params]
only enables span propagation and function name logging:
use params;
use info;
// Default behavior: Only span propagation and function name logging
// Selective parameter logging with fields()
// All parameter logging with 'all' attribute
Output:
Key Benefits
โ
Zero Code Changes: Child functions need only #[params]
- no manual context handling
โ
Cross-Boundary: Works across closures, async spawns, WebSocket upgrades, and more
โ
Automatic: Context propagation happens transparently in the library
โ
Robust: No more context=""
in your logs
โ
Production-Ready: Handles complex async scenarios seamlessly
๐ Usage Guide
1. Basic Parameter Logging
The #[params]
attribute automatically logs all function parameters:
use params;
use ;
### Logging Options
The ` ` macro redefines the following `tracing` macros within the function body:
- `info!`
- `warn!`
- `error!`
- `debug!`
- `trace!`
Use these macros as you normally would - the function arguments will be automatically included in the output.
---
## ๐ Examples
The `examples/` directory contains runnable programs demonstrating each feature. Run them with `cargo run --example <name>`.
### Core Examples
- `basic_usage.rs` โ minimal ` ` usage
- `selective_fields.rs` โ log only selected parameters
- `custom_fields.rs` โ attach static metadata
### Context Propagation
- `span_propagation.rs` โ inherit context across async/await and spawned tasks
### Advanced/Other
- `all_parameters.rs` โ log all params
- `auto_capture.rs` โ auto-capture current context for nested/indirect calls
- `method_support.rs` โ using ` ` on
๐ Advanced Field Expressions
The macro supports unlimited nesting depth and complex expressions in field specifications:
Unlimited Nesting
Method Calls and Complex Expressions
Custom Fields with Expressions
Selective Logging Benefits
- Security: Exclude sensitive data (passwords, tokens, keys)
- Privacy: Log only necessary fields for debugging
- Performance: Reduce log volume and processing overhead
- Compliance: Fine-grained control over logged data
๐ How It Works
The #[params]
macro:
- Analyzes the function signature to find available arguments
- Processes attribute options like
fields(...)
andcustom(...)
- Redefines tracing macros within the function scope to automatically include the specified fields
- With
clone_upfront
, ensures values are safely cloned to prevent ownership issues in async contexts
The macro does not add overhead beyond the normal cost of logging and cloning when needed.
๐งช Testing and Integration
Running Tests
# Run all tests
# Run integration tests
# Run with output
Integration with Tracing Ecosystem
The macro works seamlessly with the entire tracing
ecosystem:
use ;
use params;
// Set up structured JSON logging
Log Aggregation and Monitoring
The flattened JSON structure works perfectly with log aggregation tools:
Performance Considerations
- Zero Runtime Overhead: Field selection happens at compile time
- Minimal Memory Impact: Only specified fields are cloned/logged
- Async Safe:
clone_upfront
prevents ownership issues in async contexts - Span Efficiency: Context propagation uses thread-local/task-local storage
Production Deployment
// Configure for production
fmt
.json
.with_env_filter
.with_target
.init;
โ ๏ธ Limitations
- The
#[params]
macro redefines tracing macros within function scope, which may generate unused macro warnings if not all redefined macros are used (these are suppressed internally) - When using
clone_upfront
, fields must implementClone
- Array indexing syntax (e.g.,
users[0].name
) is not supported; use iterator methods or access collections as whole fields instead
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐งต Example: End-to-End
use log_args;
use tracing_subscriber;
Logs:
INFO login: user_id=42 user_name="Alice" service="auth" Login started
WARN login: user_id=42 user_name="Alice" service="auth" Invalid password
โ Incorrect usage:
Always import the macros you use:
use ;
๐ฎ Future Enhancements
#[log_args(span = true)]
: Optional span-based logging for subfunction support#[log_args(log_return)]
: Auto-log return values- Integration with
opentelemetry
and structured span hierarchy
โ License
MIT or Apache 2.0 โ your choice.
๐ Contributions
PRs, issues, and feedback are welcome. Letโs make logging in Rust ergonomic and powerful, together.
๐ซ Contact
Maintained by [MKJS Tech](mailto:mkjsm57@gmail.com) โข Feel free to reach out via mail or GitHub Issues.