This document describes the structured logging implementation in AnchorKit, including debug mode toggle and request/response logging with sensitive data redaction.
- Multiple log levels: ERROR, WARN, INFO, DEBUG, TRACE
- Structured data: JSON-formatted metadata and context
- Request correlation: Request IDs for distributed tracing
- Timestamp tracking: Automatic timestamping of all log entries
- Actor tracking: Log which address performed each operation
- CLI flags:
--debugand--verbosefor enabling debug output - Runtime configuration: Configure logging via contract methods
- Level filtering: Debug/trace logs filtered out in production mode
- Performance optimized: No overhead when debug mode is disabled
- HTTP request logging: Method, endpoint, payload, timing
- HTTP response logging: Status, duration, response payload
- Timing information: Automatic duration calculation
- Payload size tracking: Monitor request/response sizes
- Correlation: Link requests and responses via request IDs
- Pattern-based redaction: Automatically detect sensitive fields
- Configurable: Enable/disable redaction per environment
- Security-first: Redaction enabled by default
- Truncation: Limit log size to prevent memory issues
# Enable debug mode
anchorkit --debug build
anchorkit --debug --verbose deploy --network testnet
# Disable request logging (reduce log volume)
anchorkit --debug --no-request-logging health
# Disable redaction (development only)
anchorkit --debug --no-redaction attest --subject GUSER123 --payload-hash abc123use anchorkit::{Logger, LoggingConfig, RequestId};
// Configure logging
let config = LoggingConfig {
debug_mode: true,
log_requests: true,
log_responses: true,
redact_sensitive: true,
max_log_size: 2048,
};
AnchorKitContract::configure_logging(env, config)?;
// Log operations
let request_id = RequestId::generate(&env);
Logger::info(&env, String::from_str(&env, "Operation started"), Some(request_id));
Logger::error(&env, String::from_str(&env, "Operation failed"), Some(request_id), Some(error));// Automatic operation tracking
Logger::operation_start(&env, operation_name, actor, request_id, params);
// ... perform operation ...
Logger::operation_complete(&env, operation_name, actor, request_id, duration_ms, success);// Log HTTP requests
Logger::log_request(&env, request_id, method, endpoint, payload);
// Log HTTP responses
Logger::log_response(&env, request_id, status, duration_ms, response_payload);pub struct LoggingConfig {
pub debug_mode: bool, // Enable debug/trace logs
pub log_requests: bool, // Log HTTP requests
pub log_responses: bool, // Log HTTP responses
pub redact_sensitive: bool, // Redact sensitive data
pub max_log_size: u32, // Maximum log entry size
}LoggingConfig {
debug_mode: false, // Production-safe default
log_requests: true, // Monitor network activity
log_responses: true, // Monitor network activity
redact_sensitive: true, // Security-first approach
max_log_size: 1024, // Reasonable size limit
}| Level | Description | When to Use |
|---|---|---|
| ERROR | System errors, failures | Always logged, triggers alerts |
| WARN | Warnings, degraded performance | Always logged, monitoring |
| INFO | Normal operations, state changes | Always logged, audit trail |
| DEBUG | Detailed debugging information | Only in debug mode |
| TRACE | Very detailed execution flow | Only in debug mode |
The following patterns are automatically redacted when redact_sensitive: true:
passwordsecretkeytokenauthcredentialprivateseedmnemonic
All logs are published as Soroban events for external consumption:
// Log entries
env.events().publish(("log", "entry"), LogEntry { ... });
// HTTP requests
env.events().publish(("http", "request"), RequestLog { ... });
// HTTP responses
env.events().publish(("http", "response"), RequestLog { ... });- Debug/trace logs are filtered at the source when debug mode is disabled
- No performance overhead for disabled log levels
- String formatting only occurs when logs will be emitted
- Configurable maximum log size prevents memory issues
- Large payloads are truncated with
[TRUNCATED]indicator - Payload size is always tracked regardless of truncation
- Request IDs enable distributed tracing
- Minimal overhead for ID generation
- Optional correlation - can be omitted for performance
LoggingConfig {
debug_mode: false, // Disable verbose logging
log_requests: true, // Monitor for security
log_responses: true, // Monitor for security
redact_sensitive: true, // Always redact in production
max_log_size: 1024, // Limit log size
}LoggingConfig {
debug_mode: true, // Enable debugging
log_requests: true, // Full request logging
log_responses: true, // Full response logging
redact_sensitive: false, // Optional: disable for debugging
max_log_size: 4096, // Larger logs for debugging
}# Capture Soroban events for monitoring
soroban events --start-ledger 1000 --filter "log" | jq '.[] | select(.type == "contract")'# Stream logs to external system
soroban events --start-ledger 1000 --filter "log" | \
while read event; do
curl -X POST https://logs.example.com/ingest \
-H "Content-Type: application/json" \
-d "$event"
done# Alert on ERROR level logs
soroban events --start-ledger 1000 --filter "log" | \
jq -r '.[] | select(.data.level == "Error") | .data.message' | \
while read error; do
echo "ALERT: $error" | mail -s "AnchorKit Error" [email protected]
donecargo test logging_testscargo run --example logging_example./examples/logging_demo.shIf you have existing logging code, you can migrate gradually:
// Old approach
println!("Operation completed");
// New approach
Logger::info(&env, String::from_str(&env, "Operation completed"), Some(request_id));Update your event listeners to capture the new log events:
// Listen for log entries
env.events().subscribe(("log", "entry"), |event| {
// Process structured log entry
});
// Listen for HTTP logs
env.events().subscribe(("http", "request"), |event| {
// Process HTTP request log
});-
Debug logs not appearing
- Ensure
debug_mode: truein configuration - Check that you're using
--debugCLI flag
- Ensure
-
Sensitive data not redacted
- Verify
redact_sensitive: truein configuration - Check that sensitive patterns are recognized
- Verify
-
Logs truncated
- Increase
max_log_sizein configuration - Consider if full payload logging is necessary
- Increase
-
Performance impact
- Disable debug mode in production
- Reduce
max_log_sizeif needed - Consider disabling request/response logging for high-volume endpoints
# Check current logging configuration
anchorkit --debug query --id 1 # Should show debug logs
# Test redaction
anchorkit --debug --no-redaction attest --subject GUSER123 --payload-hash abc123
# Test without request logging
anchorkit --debug --no-request-logging health- Log rotation and archival
- Custom redaction patterns
- Log sampling for high-volume scenarios
- Integration with OpenTelemetry
- Structured query interface
- Real-time log streaming
- Log-based metrics and dashboards