Repositories
BFT Labs maintains repositories with memlogger integration for easy adoption and reference.
Cosmos SDK
The core Cosmos SDK with memlogger integration.
Repository: github.com/bft-labs/cosmos-sdk
Available Releases:
- v0.53.4-bft-labs-memlogger
- See all releases for other versions
Integration Commit: 2a53c378
Usage
// In your go.mod
replace (
github.com/cosmos/cosmos-sdk => github.com/bft-labs/cosmos-sdk v0.53.4-bft-labs-memlogger
cosmossdk.io/log => github.com/bft-labs/cosmos-sdk/log v0.0.0-20250101000000-2a53c378ae57
cosmossdk.io/store => github.com/bft-labs/cosmos-sdk/store v0.0.0-20250101000000-2a53c378ae57
)Features
- Full memlogger implementation
- Configurable filtering
- Production-ready performance
- Backward compatible
Performance
Based on production benchmarks:
- Memory overhead: +10-50MB
- CPU overhead: less than 1%
- Compression ratio: ~90%
- No impact on block time
EVM Chain (Reference Implementation)
Complete reference implementation showing memlogger integration in a real chain.
Repository: github.com/bft-labs/evm
Release: v0.5.0-bft-labs-memlogger
Integration Commit: 9ba9acdf
What to Look For
1. go.mod Changes
The dependency update:
require (
// ... other dependencies ...
)
replace (
github.com/cosmos/cosmos-sdk => github.com/bft-labs/cosmos-sdk v0.53.4-bft-labs-memlogger
cosmossdk.io/log => github.com/bft-labs/cosmos-sdk/log v0.0.0-20250101000000-2a53c378ae57
cosmossdk.io/store => github.com/bft-labs/cosmos-sdk/store v0.0.0-20250101000000-2a53c378ae57
// ... other replaces ...
)2. app.go Integration
Location: app/app.go
The streaming listener setup:
// After baseApp initialization
bApp := baseapp.NewBaseApp(...)
// Add streaming listeners
{
var exposeStoreKeys []storetypes.StoreKey
for _, k := range keys {
exposeStoreKeys = append(exposeStoreKeys, k)
}
bApp.CommitMultiStore().AddListeners(exposeStoreKeys)
sm := bApp.StreamingManager()
sm.ABCIListeners = append(sm.ABCIListeners, &streamingabci.DebugChangeLogger{})
bApp.SetStreamingManager(sm)
}3. Required Imports
Added to app/app.go:
import (
// ... existing imports ...
storetypes "cosmossdk.io/store/types"
streamingabci "cosmossdk.io/store/streaming/abci"
)4. Configuration Files
config.toml changes:
log_level = "debug"
log_format = "json"app.toml additions:
[memlogger]
enabled = true
filter = true
interval = "2s"
memory-bytes = 0Analyzer Shipper
Ships logs from your node to the apphash.io platform.
Repository: github.com/bft-labs/walship
Purpose: Monitors WAL directory and uploads compressed logs to apphash.io
Features:
- Automatic log detection
- Retry logic with exponential backoff
- Checkpointing for reliability
- Configurable shipping intervals
Key Integration Patterns
Single Commit Integration
The entire integration is contained in a single commit:
- Easy to review
- Simple to cherry-pick
- Clear diff to understand changes
Minimal Changes
Only three areas modified:
- go.mod (SDK dependency)
- app.go (streaming setup)
- Configuration files (settings)
No Breaking Changes
- Existing functionality unaffected
- App structure preserved
- Module initialization unchanged
Common Patterns
Store Key Collection
All implementations follow this pattern:
var exposeStoreKeys []storetypes.StoreKey
for _, k := range keys {
exposeStoreKeys = append(exposeStoreKeys, k)
}Purpose: Collect all KV stores for monitoring
Streaming Manager Setup
Standard approach:
sm := bApp.StreamingManager()
sm.ABCIListeners = append(sm.ABCIListeners, &streamingabci.DebugChangeLogger{})
bApp.SetStreamingManager(sm)Purpose: Attach logger to receive state changes
Configuration
Recommended settings:
[memlogger]
enabled = true # Enable memlogger
filter = true # Filter to critical messages
interval = "2s" # Flush every 2 seconds
memory-bytes = 0 # Time-based onlyIntegration Checklist
Use this when integrating your chain:
Phase 1: Dependency
- Update go.mod with SDK replace
- Add cosmossdk.io/log replace
- Add cosmossdk.io/store replace
- Run
go mod download - Verify build:
go build ./...
Phase 2: Code Changes
- Add imports to app.go
- Insert streaming listener code after baseApp init
- Verify all store keys are collected
- Test build:
go build ./...
Phase 3: Configuration
- Update config.toml (log_level, log_format)
- Add memlogger section to app.toml
- Set appropriate interval and filter settings
Phase 4: Testing
- Start node in testnet
- Verify logs appear in
$CHAIN_DIR/data/log.wal/ - Check log file sizes and compression
- Monitor memory usage
- Validate no consensus impact
Phase 5: Production
- Deploy to validator nodes
- Set up log shipping
- Configure apphash.io monitoring
- Establish alerting rules
Code Snippets
Full app.go Integration
func NewApp(
logger log.Logger,
db dbm.DB,
traceStore io.Writer,
loadLatest bool,
appOpts servertypes.AppOptions,
baseAppOptions ...func(*baseapp.BaseApp),
) *App {
// ... setup code ...
// Create base app
bApp := baseapp.NewBaseApp(
appName,
logger,
db,
txConfig.TxDecoder(),
baseAppOptions...,
)
// ========== MEMLOGGER INTEGRATION START ==========
// Enable in-memory listeners for state change tracking
{
var exposeStoreKeys []storetypes.StoreKey
for _, k := range keys {
exposeStoreKeys = append(exposeStoreKeys, k)
}
bApp.CommitMultiStore().AddListeners(exposeStoreKeys)
// Add debug change logger
sm := bApp.StreamingManager()
sm.ABCIListeners = append(sm.ABCIListeners,
&streamingabci.DebugChangeLogger{})
bApp.SetStreamingManager(sm)
}
// ========== MEMLOGGER INTEGRATION END ==========
// ... rest of initialization ...
return app
}Import Block
import (
// Standard library
"io"
// Cosmos SDK
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
streamingabci "cosmossdk.io/store/streaming/abci"
"github.com/cosmos/cosmos-sdk/baseapp"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
// ... other imports ...
)go.mod Replace
module github.com/your-org/your-chain
go 1.21
require (
github.com/cosmos/cosmos-sdk v0.53.4
// ... other dependencies ...
)
replace (
// Use BFT Labs SDK with memlogger
github.com/cosmos/cosmos-sdk => github.com/bft-labs/cosmos-sdk v0.53.4-bft-labs-memlogger
cosmossdk.io/log => github.com/bft-labs/cosmos-sdk/log v0.0.0-20250101000000-2a53c378ae57
cosmossdk.io/store => github.com/bft-labs/cosmos-sdk/store v0.0.0-20250101000000-2a53c378ae57
// ... other replaces ...
)Troubleshooting
Issue: Import Not Found
Error:
package cosmossdk.io/store/streaming/abci is not in GOROOTSolution:
# Verify SDK replace directive
grep cosmos-sdk go.mod
# Should show bft-labs/cosmos-sdk
# Re-download dependencies
go mod download
go mod tidyIssue: No Logs Generated
Check:
- Verify enabled in app.toml:
enabled = true - Check log level in config.toml:
log_level = "debug" - Confirm code placement (after baseApp init)
- Check directory permissions
Debug:
# Check if directory is created
ls -la $CHAIN_DIR/data/log.wal/
# Monitor in real-time
watch -n 1 'ls -lh $CHAIN_DIR/data/log.wal/node-*/$(date +%Y-%m-%d)/'Issue: High Memory Usage
Check Configuration:
[memlogger]
interval = "1s" # Reduce if needed
memory-bytes = 50000000 # Add size limit: 50MB
filter = true # Ensure filtering enabledMonitor:
# Watch memory usage
watch -n 5 'ps aux | grep chaind | grep -v grep'Best Practices
Development Environment
[memlogger]
enabled = true
filter = false # See all messages
interval = "5s" # Less frequent flushes
memory-bytes = 0Production Environment
[memlogger]
enabled = true
filter = true # Reduce volume
interval = "2s" # Balanced
memory-bytes = 0 # Time-based onlyTesting
Before deploying:
- Run on testnet for 24-48 hours
- Monitor disk usage growth
- Check memory stability
- Verify log shipping works
- Test log analysis tools
Additional Resources
- EVM Commit Diff - See exact changes
- Cosmos SDK PR - Original implementation
- Performance Benchmarks - Production metrics
Next Steps
- Setup Guide - Step-by-step integration
- FAQ - Common questions