Filtering Swarm Logs
Problem
Swarm generates a lot of informational logging that can clutter your application logs, making it difficult to see important application messages. Common Swarm log noise includes:
- Node registration/unregistration messages
 - Ring rebalancing information
 - Distribution strategy updates
 - Tracker synchronization messages
 
Solution: Multi-Layer Filtering
We implement multiple layers of filtering to ensure only Swarm error messages are shown:
1. Application-Level Configuration
Set Swarm's own log level to :error:
# config/config.exs or config/dev.exs
config :swarm,
  log_level: :error,
  logger: true2. Compile-Time Purging
Remove lower-level messages at compile time for specific Swarm modules:
# config/config.exs
config :logger,
  compile_time_purge_matching: [
    # Swarm modules - only show errors
    [module: Swarm.Distribution.Ring, level_lower_than: :error],
    [module: Swarm.Distribution.Strategy, level_lower_than: :error],
    [module: Swarm.Registry, level_lower_than: :error],
    [module: Swarm.Tracker, level_lower_than: :error],
    [module: Swarm.Distribution.StaticQuorumRing, level_lower_than: :error],
    [module: Swarm.Distribution.Handler, level_lower_than: :error],
    [module: Swarm.IntervalTreeClock, level_lower_than: :error],
    [module: Swarm, level_lower_than: :error]
  ]3. Runtime Filtering with BCUtils.LoggerFilters
Use the custom logger filter from bc_utils for dynamic filtering:
# config/dev.exs
config :logger, :console,
  format: "$time ($metadata) [$level] $message\\n",
  metadata: [:mfa],
  level: :info,
  # Filter out Swarm noise using BCUtils filter
  filters: [swarm_noise: {BCUtils.LoggerFilters, :filter_swarm}]BCUtils.LoggerFilters
The BCUtils.LoggerFilters module provides several pre-configured filters:
filter_swarm/1
Filters out all Swarm messages except errors:
config :logger, :console,
  filters: [swarm_filter: {BCUtils.LoggerFilters, :filter_swarm}]filter_libcluster/1
Similar filtering for LibCluster messages:
config :logger, :console,
  filters: [libcluster_filter: {BCUtils.LoggerFilters, :filter_libcluster}]filter_verbose_libs/1
Combined filter for both Swarm and LibCluster:
config :logger, :console,
  filters: [verbose_libs: {BCUtils.LoggerFilters, :filter_verbose_libs}]errors_and_warnings_only/1
More aggressive filtering - only allows errors and warnings from noisy libraries:
config :logger, :console,
  filters: [errors_only: {BCUtils.LoggerFilters, :errors_and_warnings_only}]Integration with ExESDB Consensus Filters
When using BCUtils.LoggerFilters with ExESDB, you can combine both sets of filters for comprehensive noise reduction:
# ExESDB defines its own filters for Ra/Khepri consensus libraries
# BCUtils provides filters for clustering libraries (Swarm/LibCluster)
# They work together seamlessly
config :logger, :console,
  level: :info,
  filters: [
    # BCUtils filters for clustering libraries
    swarm_noise: {BCUtils.LoggerFilters, :filter_swarm},
    libcluster_noise: {BCUtils.LoggerFilters, :filter_libcluster},
    # ExESDB filters for consensus libraries (if using ExESDB)
    ra_noise: {ExESDB.LoggerFilters, :filter_ra},
    khepri_noise: {ExESDB.LoggerFilters, :filter_khepri}
  ]Application-Level Configuration for ExESDB + BCUtils
# Reduce noise at the source
config :swarm, log_level: :error        # BCUtils handles this
config :ra, log_level: :warning          # ExESDB handles this
config :khepri, log_level: :warning      # ExESDB handles thisComplete Example Configuration
ExESDB Server (config/dev.exs)
import Config
# Swarm configuration - errors only
config :swarm,
  log_level: :error,
  logger: true
# Logger console configuration with Swarm filter
config :logger, :console,
  format: "$time ($metadata) [$level] $message\\n",
  metadata: [:mfa],
  level: :info,
  filters: [swarm_noise: {BCUtils.LoggerFilters, :filter_swarm}]
# Additional logger settings
config :logger,
  level: :info,
  backends: [:console],
  handle_otp_reports: true,
  handle_sasl_reports: falseExESDB Gateway (config/dev.exs)
import Config
# Swarm configuration - errors only  
config :swarm,
  log_level: :error,
  logger: true
# Logger console configuration with Swarm filter
config :logger, :console,
  format: "$time ($metadata) [$level] $message\\n",
  metadata: [:mfa],
  level: :info,
  filters: [swarm_noise: {BCUtils.LoggerFilters, :filter_swarm}]Both Applications (config/config.exs)
import Config
# Compile-time purging for Swarm modules
config :logger,
  compile_time_purge_matching: [
    [module: Swarm.Distribution.Ring, level_lower_than: :error],
    [module: Swarm.Distribution.Strategy, level_lower_than: :error],
    [module: Swarm.Registry, level_lower_than: :error],
    [module: Swarm.Tracker, level_lower_than: :error],
    [module: Swarm.Distribution.StaticQuorumRing, level_lower_than: :error],
    [module: Swarm.Distribution.Handler, level_lower_than: :error],
    [module: Swarm.IntervalTreeClock, level_lower_than: :error],
    [module: Swarm, level_lower_than: :error]
  ]Verification
To verify the configuration is working:
- Start your application and observe the logs
 - Look for Swarm messages - you should only see error-level messages
 - Test Swarm functionality - workers should still register/unregister properly
 - Check log volume - overall log noise should be significantly reduced
 
Testing Swarm Errors
To verify error messages still come through, you can temporarily create a Swarm error:
# This should still show up in logs as an error
Swarm.register_name(:invalid_name, :invalid_pid)Troubleshooting
Still Seeing Swarm Messages?
- Check configuration order - Make sure logger filters are applied after other logger config
 - Verify bc_utils version - Ensure you're using a version that includes 
BCUtils.LoggerFilters - Check for multiple logger configurations - Some configs might override others
 
Missing Important Swarm Information?
If you need to see more Swarm information temporarily:
# Temporarily increase Swarm log level
config :swarm,
  log_level: :info  # or :debug for very verbose
# Or remove the filter temporarily
config :logger, :console,
  # filters: [swarm_noise: {BCUtils.LoggerFilters, :filter_swarm}]  # commented outPerformance Impact
The logger filters have minimal performance impact:
- Compile-time purging: No runtime cost
 - Runtime filters: Very small per-message overhead
 - Swarm config: No additional overhead
 
Environment-Specific Configuration
Development
- Use runtime filters for flexibility
 - Allow some Swarm warnings if debugging clustering
 
Production
- Use compile-time purging for best performance
 - Strict error-only filtering
 - Consider structured logging for better analysis
 
Testing
- May want to disable filters to ensure proper Swarm behavior
 - Use debug level for integration tests
 
Summary
This multi-layer approach ensures:
- ✅ No Swarm noise in normal operation
 - ✅ Important errors still visible
 - ✅ Minimal performance impact
 - ✅ Easy to adjust per environment
 - ✅ Reusable across BEAM Campus projects
 
The configuration significantly improves log readability while maintaining visibility into actual problems.