Skip to content

Migrate to fully programmatic approach for Log4J configuration#1

Closed
usmansaleem wants to merge 5 commits intoyashhzd:feat/logging-format-cli-optionfrom
usmansaleem:pr-9803-execution-strategy-refactor
Closed

Migrate to fully programmatic approach for Log4J configuration#1
usmansaleem wants to merge 5 commits intoyashhzd:feat/logging-format-cli-optionfrom
usmansaleem:pr-9803-execution-strategy-refactor

Conversation

@usmansaleem
Copy link
Copy Markdown

Building on PR besu-eth#9803's --logging-format option, this PR completes the migration by:

  • Removing static state and two-phase initialization
  • Using execution strategy for proper logging initialization timing
  • Adding full Splunk HTTP Event Collector (HEC) support
  • Enabling all logging configuration via environment variables

Changes

1. Programmatic Configuration (LoggingConfigurator)

  • All log4j2.xml features migrated to Java code using ConfigurationBuilder API
  • Console appender with PLAIN or ECS/JSON formats
  • Splunk HEC appender with full configurability
  • All 6 logger filters preserved:
    • DNS query filters (DNSTimerTask, DNSResolver)
    • Invalid transaction removal marker filter
    • OpenTelemetry B3 propagation filter
    • Bonsai worldstate stack trace filter

2. Execution Strategy Pattern (BesuCommand)

  • Removed static selectedLoggingFormat field
  • Added createLoggingInitializationTask() execution strategy
  • Proper initialization order: CLI parse → logging setup → command execution
  • Skips logging init for help/version commands

3. Cleanup

  • Removed BesuLoggingConfigurationFactory (two-phase initialization no longer needed)
  • Removed XmlExtensionConfiguration and related tests
  • Removed evmtool's log4j2.xml (was interfering with programmatic config)
  • Removed applyLoggingFormat() methods from util classes

Configuration

Console Logging (default)

besu --logging-format=PLAIN  # Default colored console output
besu --logging-format=ECS    # JSON structured logging

## Breaking Changes

None. All existing functionality preserved:
- Default console logging unchanged
- Custom log4j2.xml still supported
- All CLI options work as before
- Environment variables are opt-in

## Migration Notes

For users currently using custom log4j2.xml files:
1. No action required - custom configs still work via `JAVA_OPTS="-Dlog4j2.configurationFile=customlog4j2.xml"`
2. To use new Splunk support, set LOGGER=Splunk environment variable
3. EvmTool users: No impact (tool explicitly disables logging anyway)

This refactoring changes from a two-phase ConfigurationFactory approach
to an execution strategy pattern. This fixes timing issues where logging
was initialized before CLI arguments were available.

Key changes:
- Add LoggingConfigurator with fully programmatic Log4j2 configuration
- Migrate all log4j2.xml content to Java (filters, Splunk, appenders)
- Add execution strategy for logging initialization (correct timing)
- Add isHelpOrVersionRequested() to walk subcommand tree
- Remove two-phase initialization (ConfigurationFactory + applyFormat)
- Remove BesuLoggingConfigurationFactory and XmlExtensionConfiguration
- Remove log4j2.xml (all config now in Java)
- Deprecate configureLogging() (now just announces via logger)
- Remove static selectedLoggingFormat field

Benefits:
- Single-phase initialization at correct time (after CLI parsing)
- No static state required
- Fully programmatic (type-safe, refactorable)
- Simpler codebase (-108 net lines)

All existing features preserved:
- --logging / -l flag (log level)
- --logging-format flag (PLAIN, ECS, GCP, LOGSTASH, GELF)
- --color-enabled flag and NO_COLOR env var
- LOGGER=Splunk environment variable
- LOG4J_CONFIGURATION_FILE custom config override
- All 6 logger filters (DNS, transactions, Bonsai, etc.)

Related to PR besu-eth#9803 and issue besu-eth#9626

Signed-off-by: Usman Saleem <usman@usmans.info>
This change migrates Besu from XML-based Log4j2 configuration to a fully
programmatic approach using execution strategy pattern, similar to Web3Signer.

Key changes:
- Add LoggingConfigurator with programmatic configuration for Console and Splunk appenders
- Implement execution strategy in BesuCommand for proper initialization timing
- Remove evmtool's log4j2.xml which was interfering with programmatic config
- Add support for Splunk HTTP Event Collector via LOGGER environment variable

Splunk configuration via environment variables:
- LOGGER=Splunk enables Splunk appender
- SPLUNK_URL: Base URL (e.g., https://localhost:8088) - library appends path internally
- SPLUNK_TOKEN: HEC token value
- SPLUNK_INDEX: Target index (default: main)
- SPLUNK_SOURCE: Event source (default: besu)
- SPLUNK_SOURCETYPE: Event sourcetype (default: besu)
- SPLUNK_MESSAGE_FORMAT: Message format text/json (default: text)
- SPLUNK_BATCH_SIZE_BYTES: Batch size in bytes (default: 65536)
- SPLUNK_BATCH_SIZE_COUNT: Batch size in events (default: 1000)
- SPLUNK_BATCH_INTERVAL: Batch interval in ms (default: 500)
- SPLUNK_SKIPTLSVERIFY: Skip TLS verification (default: false)

All log4j2.xml filters migrated to programmatic configuration:
- DNS query filters for DNSTimerTask and DNSResolver
- Invalid transaction removal marker filter
- OpenTelemetry B3 propagation filter
- Bonsai worldstate stack trace filter

Custom log4j2.xml override still supported via -Dlog4j2.configurationFile

Tested with:
- Console logging with PLAIN and ECS formats
- Custom log4j2.xml override
- Splunk HEC integration with real Splunk Enterprise instance

Signed-off-by: Usman Saleem <usman@usmans.info>
Changes:
- Initialize logging BEFORE plugin registration (was backwards)
  - Plugins can now log properly during registration
  - Plugin logs respect --logging-format and LOGGER env var
  - Fixes issue where plugins used auto-discovered Log4j2 config

- Remove suppressInfoLog() hack (no longer needed with correct order)
  - Previous workaround to prevent plugin logs before help/version
  - Now unnecessary since logging is initialized after help check

- Remove "Starting Besu version" log from initializeLogging()
  - Prevents log output appearing before --Xhelp (hidden options)
  - Version still logged elsewhere during normal startup
  - Keeps help/version output clean

Execution order is now:
1. Parse CLI
2. Initialize logging (skip if help/version requested)
3. Register plugins (skip if help/version requested)
4. Execute command

Signed-off-by: Usman Saleem <usman@usmans.info>
Issue: Logger filters were hardcoded to Level.INFO, causing them to always
log at INFO regardless of --logging setting (e.g., --logging=WARN still
showed INFO messages from TransactionPoolFactory).

Root cause: During migration from log4j2.xml to programmatic configuration,
incorrectly added explicit Level.INFO to logger definitions. Original XML
had no level attribute, allowing loggers to inherit from root.

Fix: Remove hardcoded Level.INFO from all logger filter configurations:
- org.apache.tuweni.discovery.DNSTimerTask
- org.apache.tuweni.discovery.DNSResolver
- io.vertx.core.dns.DnsException
- org.hyperledger.besu.ethereum.eth.transactions
- io.opentelemetry.extension.trace.propagation.B3PropagatorExtractorMultipleHeaders
- org.hyperledger.besu.ethereum.trie.pathbased.bonsai.storage.BonsaiSnapshotWorldStateKeyValueStorage

Loggers now inherit root level while still filtering specific message patterns.

Before: --logging=WARN still showed INFO messages from filtered loggers
After: --logging=WARN correctly shows only WARN+ messages
Signed-off-by: Usman Saleem <usman@usmans.info>
- Fix parseLevel() to use Level.toLevel() with default instead of getLevel() that returns null
- Add isSplunkConfigValid() to validate required Splunk environment variables (URL and TOKEN)
- Add fallback to console logging with warning when Splunk config is invalid
- Track actual appender used vs requested for root logger reference
- Make SPLUNK_INDEX optional (only add attribute if set, uses Splunk default otherwise)

Signed-off-by: Usman Saleem <usman@usmans.info>
@usmansaleem usmansaleem closed this Mar 3, 2026
@usmansaleem usmansaleem deleted the pr-9803-execution-strategy-refactor branch March 3, 2026 02:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant