ReferenceRepositories

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:

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 = 0

Analyzer 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:

  1. go.mod (SDK dependency)
  2. app.go (streaming setup)
  3. 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 only

Integration 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 GOROOT

Solution:

# Verify SDK replace directive
grep cosmos-sdk go.mod
 
# Should show bft-labs/cosmos-sdk
 
# Re-download dependencies
go mod download
go mod tidy

Issue: No Logs Generated

Check:

  1. Verify enabled in app.toml: enabled = true
  2. Check log level in config.toml: log_level = "debug"
  3. Confirm code placement (after baseApp init)
  4. 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 enabled

Monitor:

# 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 = 0

Production Environment

[memlogger]
enabled = true
filter = true          # Reduce volume
interval = "2s"        # Balanced
memory-bytes = 0       # Time-based only

Testing

Before deploying:

  1. Run on testnet for 24-48 hours
  2. Monitor disk usage growth
  3. Check memory stability
  4. Verify log shipping works
  5. Test log analysis tools

Additional Resources

Next Steps

© 2025 apphash.io Documentation