Node Configuration
After setting up your application code, you need to configure your node’s settings to enable debug logging and memlogger functionality.
Overview
Configuration requires modifying two files in your chain directory:
$CHAIN_DIR/config/config.toml- Core node logging configuration$CHAIN_DIR/config/app.toml- Memlogger-specific settings
Configuration Files
config.toml Settings
Open $CHAIN_DIR/config/config.toml and update the following settings:
#######################################################
### Logging Configuration ###
#######################################################
# Output level for logging, including package level options
log_level = "debug"
# Output format: 'plain' (colored text) or 'json'
log_format = "json"Why These Settings?
- log_level = “debug”: Enables detailed logging for state changes and consensus events
- log_format = “json”: Structured format required for efficient parsing and shipping
app.toml Settings
Open $CHAIN_DIR/config/app.toml and add/update the memlogger section:
###############################################################################
### Memlogger ###
###############################################################################
[memlogger]
# Enable defines if the in-memory compressing logger should be used.
enabled = true
# Filter controls whether memlogger filters messages by an allow-list.
# Set to true to apply filtering; false disables it.
filter = true
# Interval controls how often the current in-memory buffer is compressed
# and appended to the WAL. Examples: "2s", "1m". Set to "0" to disable
# time-based flushing (size-only mode, if memory-bytes > 0).
interval = "2s"
# MemoryBytes caps the uncompressed bytes held in memory. When reached,
# the buffer is immediately compressed and appended to the WAL. 0 disables
# the size trigger (timer-only).
memory-bytes = 0Configuration Parameters Explained
enabled
- Type: boolean
- Default: false
- Description: Master switch for memlogger functionality
- Recommendation: Set to
truefor apphash.io integration
filter
- Type: boolean
- Default: false
- Description: When enabled, only logs consensus-critical messages
- Recommendation: Set to
trueto reduce log volume while maintaining essential data - Impact: Filters out non-critical debug messages, keeping only state changes and consensus events
interval
- Type: duration string
- Default: “0” (disabled)
- Examples: “2s”, “5s”, “1m”
- Description: How often to compress and flush the in-memory buffer to disk
- Recommendation: “2s” for most use cases
- Trade-offs:
- Shorter intervals: More frequent disk writes, less memory usage
- Longer intervals: Better compression ratios, slightly higher memory usage
memory-bytes
- Type: integer (bytes)
- Default: 0 (disabled)
- Description: Maximum uncompressed bytes in memory before forced flush
- Recommendation: 0 (rely on time-based flushing)
- Use case: Set to a positive value if you want size-based flushing instead of time-based
Performance Considerations
Will Debug Logging Impact Performance?
No significant impact on performance - This has been verified in production environments.
According to benchmark results:
- Memory impact: Slight increase (configurable, typically 10-50MB)
- CPU overhead: Negligible (asynchronous compression)
- Disk I/O: Minimal (compressed, batched writes)
- Network impact: None (local processing only)
Why Is It Safe for Production?
- Asynchronous processing: Log compression happens in background goroutines
- Efficient compression: Gzip compression reduces disk usage by 90%+
- Batched writes: Reduces disk I/O operations
- Filtered logging: Only consensus-critical events when filter=true
- Non-blocking: Never blocks the consensus or state machine
Log File Location
After configuration, logs will be generated in:
$CHAIN_DIR/data/log.wal/<node-id>/<yyyy-mm-dd>/seg-XXXXXX.wal.gz
$CHAIN_DIR/data/log.wal/<node-id>/<yyyy-mm-dd>/seg-XXXXXX.wal.idxDirectory Structure Example
$CHAIN_DIR/
└── data/
└── log.wal/
└── node-e687dd88b46b950a919304190786e03f667347ce/
└── 2025-11-23/
├── seg-000001.wal.gz
├── seg-000001.wal.idx
├── seg-000002.wal.gz
├── seg-000002.wal.idx
└── ...File Types
.wal.gz: Compressed log data (gzip format).wal.idx: Index file for efficient log replay and searching
Log Rotation
Logs are automatically organized by:
- Node ID: Each node has its own directory
- Date: Daily directories (YYYY-MM-DD format)
- Segments: Sequential numbered segments within each day
This structure makes it easy to:
- Archive old logs
- Ship logs to apphash.io platform
- Clean up disk space
- Identify which node generated which logs
Verification
After configuring, start your node and verify logs are being generated:
# Start your node
./build/chaind start
# In another terminal, check log files are being created
ls -lh $CHAIN_DIR/data/log.wal/You should see directories being created with your node ID and today’s date.
Example Configuration Files
Complete config.toml Example
# ... other settings ...
#######################################################
### Logging Configuration ###
#######################################################
log_level = "debug"
log_format = "json"
# ... rest of config.toml ...Complete app.toml Example
# ... other settings ...
###############################################################################
### Memlogger ###
###############################################################################
[memlogger]
enabled = true
filter = true
interval = "2s"
memory-bytes = 0
# ... rest of app.toml ...Configuration Recommendations by Environment
Development
[memlogger]
enabled = true
filter = false # See all debug messages
interval = "5s" # Less frequent writes
memory-bytes = 0Testnet
[memlogger]
enabled = true
filter = true # Filter to important messages
interval = "2s" # Balanced flushing
memory-bytes = 0Production
[memlogger]
enabled = true
filter = true # Filter to important messages
interval = "2s" # Recommended for production
memory-bytes = 0Existing Log Files
The memlogger operates independently of your existing log files:
- Standard logs (info, warn, error) still go to your usual log files
- Debug logs are captured by memlogger and compressed
- Both can coexist without interference
This means you can:
- Continue using your existing log monitoring tools
- Add apphash.io monitoring without disrupting current setup
- Disable memlogger without affecting standard logging
Next Steps
Now that your node is configured:
- Start your node and verify logs are being generated
- Set up walship to send logs to apphash.io
- Access the apphash.io dashboard to monitor your chain
Troubleshooting
Logs Not Being Generated
If logs are not appearing in $CHAIN_DIR/data/log.wal/:
- Verify
enabled = truein app.toml - Check that log_level is set to “debug” in config.toml
- Ensure you’ve rebuilt your chain after code changes
- Check node logs for any memlogger-related errors
Disk Space Concerns
If worried about disk usage:
- Compressed logs are typically 90%+ smaller than raw logs
- Implement log rotation/archival (daily directories make this easy)
- Monitor
$CHAIN_DIR/data/log.wal/size - Old directories can be safely archived or deleted
High Memory Usage
If experiencing high memory usage:
- Check your
intervalsetting (make it shorter) - Set
memory-bytesto a specific limit (e.g., 50000000 for 50MB) - Verify
filter = trueto reduce log volume