From ed81df8efcb0a502f30ae707fbf65806e44e22c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20L=C3=B3pez=20Le=C3=B3n?= Date: Fri, 11 Feb 2022 18:50:19 -0300 Subject: [PATCH] Replace Log4j2 with logback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Diego López León --- acceptance-tests/tests/build.gradle | 2 +- .../privacy/PrivacyGroupAcceptanceTest.java | 6 +- besu/build.gradle | 6 +- .../main/java/org/hyperledger/besu/Besu.java | 10 +- .../org/hyperledger/besu/cli/BesuCommand.java | 31 +++-- .../besu/cli/error/BesuExceptionHandler.java | 4 +- .../BesuLoggingConfigurationFactory.java | 34 ----- .../logging/XmlExtensionConfiguration.java | 119 ------------------ .../options/stable/ColorEnabledOption.java | 37 ++++++ .../options/stable/LoggingLevelOption.java | 4 +- .../cli/subcommands/RetestethSubCommand.java | 10 +- besu/src/main/resources/log4j2.xml | 46 ------- besu/src/main/resources/logback.xml | 25 ++++ .../hyperledger/besu/cli/BesuCommandTest.java | 6 +- .../stable/LoggingLevelOptionTest.java | 9 +- build.gradle | 7 -- .../merge/blockcreation/MergeReorgTest.java | 4 +- ethereum/api/build.gradle | 3 +- .../internal/methods/AdminChangeLogLevel.java | 8 +- .../methods/AdminChangeLogLevelTest.java | 13 +- ethereum/core/build.gradle | 1 - .../ethereum/vm/AbstractRetryingTest.java | 7 -- ethereum/evmtool/build.gradle | 2 +- .../besu/evmtool/EvmToolCommand.java | 10 +- .../besu/evmtool/StateTestSubCommand.java | 8 +- ethereum/p2p/build.gradle | 6 +- gradle/versions.gradle | 11 +- util/build.gradle | 3 +- .../besu/util/Log4j2ConfiguratorUtil.java | 108 ---------------- .../besu/util/LogbackConfiguratorUtil.java | 64 ++++++++++ .../besu/util/Slf4jLambdaHelperTest.java | 12 +- 31 files changed, 211 insertions(+), 405 deletions(-) delete mode 100644 besu/src/main/java/org/hyperledger/besu/cli/logging/BesuLoggingConfigurationFactory.java delete mode 100644 besu/src/main/java/org/hyperledger/besu/cli/logging/XmlExtensionConfiguration.java create mode 100644 besu/src/main/java/org/hyperledger/besu/cli/options/stable/ColorEnabledOption.java delete mode 100644 besu/src/main/resources/log4j2.xml create mode 100644 besu/src/main/resources/logback.xml delete mode 100644 util/src/main/java/org/hyperledger/besu/util/Log4j2ConfiguratorUtil.java create mode 100644 util/src/main/java/org/hyperledger/besu/util/LogbackConfiguratorUtil.java diff --git a/acceptance-tests/tests/build.gradle b/acceptance-tests/tests/build.gradle index cac08cad81f..f07e20e5aaa 100644 --- a/acceptance-tests/tests/build.gradle +++ b/acceptance-tests/tests/build.gradle @@ -48,6 +48,7 @@ dependencies { testImplementation project(':testutil') testImplementation project(':util') + testImplementation 'ch.qos.logback:logback-classic' testImplementation 'com.github.tomakehurst:wiremock-jre8-standalone' testImplementation 'commons-io:commons-io' testImplementation 'io.grpc:grpc-core' @@ -67,7 +68,6 @@ dependencies { testImplementation 'io.vertx:vertx-core' testImplementation 'junit:junit' testImplementation 'org.apache.commons:commons-compress' - testImplementation 'org.apache.logging.log4j:log4j-core' testImplementation 'org.apache.tuweni:tuweni-crypto' testImplementation 'org.assertj:assertj-core' testImplementation 'org.awaitility:awaitility' diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyGroupAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyGroupAcceptanceTest.java index 13e3a7fe567..2e0db962e1c 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyGroupAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivacyGroupAcceptanceTest.java @@ -20,7 +20,7 @@ import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; import org.hyperledger.besu.tests.web3j.generated.EventEmitter; -import org.hyperledger.besu.util.Log4j2ConfiguratorUtil; +import org.hyperledger.besu.util.LogbackConfiguratorUtil; import org.hyperledger.enclave.testutil.EnclaveType; import java.io.IOException; @@ -28,7 +28,7 @@ import java.util.Collection; import java.util.Optional; -import org.apache.logging.log4j.Level; +import ch.qos.logback.classic.Level; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -87,7 +87,7 @@ public PrivacyGroupAcceptanceTest(final EnclaveType enclaveType) throws IOExcept @Test public void nodeCanCreatePrivacyGroup() { - Log4j2ConfiguratorUtil.setLevel("", Level.DEBUG); + LogbackConfiguratorUtil.setLevel("", Level.DEBUG); final String privacyGroupId = alice.execute( privacyTransactions.createPrivacyGroup( diff --git a/besu/build.gradle b/besu/build.gradle index 378177d2896..3b4dcf97621 100644 --- a/besu/build.gradle +++ b/besu/build.gradle @@ -60,6 +60,7 @@ dependencies { implementation project(':services:kvstore') implementation project(':util') + implementation 'ch.qos.logback:logback-classic' implementation 'com.fasterxml.jackson.core:jackson-databind' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8' implementation 'com.google.guava:guava' @@ -67,7 +68,6 @@ dependencies { implementation 'info.picocli:picocli' implementation 'io.vertx:vertx-core' implementation 'io.vertx:vertx-web' - implementation 'org.apache.logging.log4j:log4j-core' implementation 'org.apache.tuweni:tuweni-bytes' implementation 'org.apache.tuweni:tuweni-config' implementation 'org.apache.tuweni:tuweni-toml' @@ -76,9 +76,11 @@ dependencies { implementation 'org.xerial.snappy:snappy-java' implementation 'net.consensys.services:quorum-mainnet-launcher' - runtimeOnly 'org.apache.logging.log4j:log4j-jul' runtimeOnly 'com.splunk.logging:splunk-library-javalogging' + runtimeOnly 'org.codehaus.janino:janino' + runtimeOnly 'org.codehaus.janino:commons-compiler' runtimeOnly 'org.fusesource.jansi:jansi' // for color logging in windows + runtimeOnly 'org.slf4j:jul-to-slf4j' testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') testImplementation project(path: ':crypto', configuration: 'testSupportArtifacts') diff --git a/besu/src/main/java/org/hyperledger/besu/Besu.java b/besu/src/main/java/org/hyperledger/besu/Besu.java index 69f0bb6128a..2d508183682 100644 --- a/besu/src/main/java/org/hyperledger/besu/Besu.java +++ b/besu/src/main/java/org/hyperledger/besu/Besu.java @@ -18,12 +18,11 @@ import org.hyperledger.besu.chainimport.JsonBlockImporter; import org.hyperledger.besu.chainimport.RlpBlockImporter; import org.hyperledger.besu.cli.BesuCommand; -import org.hyperledger.besu.cli.logging.BesuLoggingConfigurationFactory; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.services.BesuPluginContextImpl; import io.netty.util.internal.logging.InternalLoggerFactory; -import io.netty.util.internal.logging.Log4J2LoggerFactory; +import io.netty.util.internal.logging.Slf4JLoggerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import picocli.CommandLine.RunLast; @@ -54,14 +53,11 @@ public static void main(final String... args) { } private static Logger setupLogging() { - InternalLoggerFactory.setDefaultFactory(Log4J2LoggerFactory.INSTANCE); + InternalLoggerFactory.setDefaultFactory(Slf4JLoggerFactory.INSTANCE); try { System.setProperty( "vertx.logger-delegate-factory-class-name", - "io.vertx.core.logging.Log4j2LogDelegateFactory"); - System.setProperty( - "log4j.configurationFactory", BesuLoggingConfigurationFactory.class.getName()); - System.setProperty("log4j.skipJansi", String.valueOf(false)); + "io.vertx.core.logging.SLF4JLogDelegateFactory"); } catch (SecurityException e) { System.out.println( "Could not set logging system property as the security manager prevented it:" diff --git a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java index a24536431da..b92bb18cf50 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -52,6 +52,7 @@ import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty; import org.hyperledger.besu.cli.custom.RpcAuthFileValidator; import org.hyperledger.besu.cli.error.BesuExceptionHandler; +import org.hyperledger.besu.cli.options.stable.ColorEnabledOption; import org.hyperledger.besu.cli.options.stable.DataStorageOptions; import org.hyperledger.besu.cli.options.stable.EthstatsOptions; import org.hyperledger.besu.cli.options.stable.LoggingLevelOption; @@ -178,7 +179,7 @@ import org.hyperledger.besu.services.SecurityModuleServiceImpl; import org.hyperledger.besu.services.StorageServiceImpl; import org.hyperledger.besu.services.kvstore.InMemoryStoragePlugin; -import org.hyperledger.besu.util.Log4j2ConfiguratorUtil; +import org.hyperledger.besu.util.LogbackConfiguratorUtil; import org.hyperledger.besu.util.NetworkUtility; import org.hyperledger.besu.util.PermissioningConfigurationValidator; import org.hyperledger.besu.util.number.Fraction; @@ -217,6 +218,8 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; +import ch.qos.logback.classic.Level; +import ch.qos.logback.core.joran.spi.JoranException; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; import com.google.common.base.Suppliers; @@ -231,7 +234,6 @@ import net.consensys.quorum.mainnet.launcher.config.ImmutableLauncherConfig; import net.consensys.quorum.mainnet.launcher.exception.LauncherException; import net.consensys.quorum.mainnet.launcher.util.ParseArgsHelper; -import org.apache.logging.log4j.Level; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; import org.slf4j.Logger; @@ -291,6 +293,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { private final NodePrivateKeyFileOption nodePrivateKeyFileOption = NodePrivateKeyFileOption.create(); private final LoggingLevelOption loggingLevelOption = LoggingLevelOption.create(); + private final ColorEnabledOption colorEnabledOption = ColorEnabledOption.create(); private final RunnerBuilder runnerBuilder; private final BesuController.Builder controllerBuilderFactory; @@ -978,13 +981,6 @@ static class MetricsOptionGroup { "Deprecated in favor of --host-allowlist. Comma separated list of hostnames to allow for RPC access, or * to accept any host (default: ${DEFAULT-VALUE})") private final JsonRPCAllowlistHostsProperty hostsWhitelist = new JsonRPCAllowlistHostsProperty(); - @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) - @Option( - names = {"--color-enabled"}, - description = - "Force color output to be enabled/disabled (default: colorized only if printing to console)") - private static Boolean colorEnabled = null; - @Option( names = {"--reorg-logging-threshold"}, description = @@ -1465,6 +1461,7 @@ private void handleStableOptions() { commandLine.addMixin("Private key file", nodePrivateKeyFileOption); commandLine.addMixin("Logging level", loggingLevelOption); commandLine.addMixin("Data Storage Options", dataStorageOptions); + commandLine.addMixin("Color enabled", colorEnabledOption); } private void handleUnstableOptions() { @@ -1645,21 +1642,21 @@ private void validatePluginOptions() { public void configureLogging(final boolean announce) { // To change the configuration if color was enabled/disabled - Log4j2ConfiguratorUtil.reconfigure(); + try { + LogbackConfiguratorUtil.reconfigure(); + } catch (JoranException e) { + System.err.println("Unable to reconfigure logback: " + e.getMessage()); + } // set log level per CLI flags final Level logLevel = loggingLevelOption.getLogLevel(); if (logLevel != null) { if (announce) { - System.out.println("Setting logging level to " + logLevel.name()); + System.out.println("Setting logging level to " + logLevel); } - Log4j2ConfiguratorUtil.setAllLevels("", logLevel); + LogbackConfiguratorUtil.setAllLevels("", logLevel); } } - public static Optional getColorEnabled() { - return Optional.ofNullable(colorEnabled); - } - private void configureNativeLibs() { if (unstableNativeLibraryOptions.getNativeAltbn128() && AbstractAltBnPrecompiledContract.isNative()) { @@ -2824,7 +2821,7 @@ private void addShutdownHook(final Runner runner) { try { besuPluginContext.stopPlugins(); runner.close(); - Log4j2ConfiguratorUtil.shutdown(); + LogbackConfiguratorUtil.shutdown(); } catch (final Exception e) { logger.error("Failed to stop Besu"); } diff --git a/besu/src/main/java/org/hyperledger/besu/cli/error/BesuExceptionHandler.java b/besu/src/main/java/org/hyperledger/besu/cli/error/BesuExceptionHandler.java index da44caf2d8d..fa4c12081e5 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/error/BesuExceptionHandler.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/error/BesuExceptionHandler.java @@ -17,7 +17,7 @@ import java.util.List; import java.util.function.Supplier; -import org.apache.logging.log4j.Level; +import ch.qos.logback.classic.Level; import picocli.CommandLine; public class BesuExceptionHandler @@ -34,7 +34,7 @@ public BesuExceptionHandler(final Supplier levelSupplier) { public List handleParseException( final CommandLine.ParameterException ex, final String[] args) { final Level logLevel = levelSupplier.get(); - if (logLevel != null && Level.DEBUG.isMoreSpecificThan(logLevel)) { + if (logLevel != null && Level.DEBUG.isGreaterOrEqual(logLevel)) { ex.printStackTrace(err()); } else { err().println(ex.getMessage()); diff --git a/besu/src/main/java/org/hyperledger/besu/cli/logging/BesuLoggingConfigurationFactory.java b/besu/src/main/java/org/hyperledger/besu/cli/logging/BesuLoggingConfigurationFactory.java deleted file mode 100644 index f7e593a8270..00000000000 --- a/besu/src/main/java/org/hyperledger/besu/cli/logging/BesuLoggingConfigurationFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.cli.logging; - -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.ConfigurationFactory; -import org.apache.logging.log4j.core.config.ConfigurationSource; - -public class BesuLoggingConfigurationFactory extends ConfigurationFactory { - - @Override - protected String[] getSupportedTypes() { - return new String[] {".xml", "*"}; - } - - @Override - public Configuration getConfiguration( - final LoggerContext loggerContext, final ConfigurationSource source) { - return new XmlExtensionConfiguration(loggerContext, source); - } -} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/logging/XmlExtensionConfiguration.java b/besu/src/main/java/org/hyperledger/besu/cli/logging/XmlExtensionConfiguration.java deleted file mode 100644 index 69caa01a874..00000000000 --- a/besu/src/main/java/org/hyperledger/besu/cli/logging/XmlExtensionConfiguration.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.cli.logging; - -import org.hyperledger.besu.cli.BesuCommand; - -import java.io.IOException; -import java.util.stream.Stream; - -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.appender.ConsoleAppender; -import org.apache.logging.log4j.core.config.AbstractConfiguration; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.ConfigurationSource; -import org.apache.logging.log4j.core.config.xml.XmlConfiguration; -import org.apache.logging.log4j.core.layout.PatternLayout; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class XmlExtensionConfiguration extends XmlConfiguration { - - public XmlExtensionConfiguration( - final LoggerContext loggerContext, final ConfigurationSource configSource) { - super(loggerContext, configSource); - } - - @Override - protected void doConfigure() { - super.doConfigure(); - - createConsoleAppender(); - } - - @Override - public Configuration reconfigure() { - final Configuration refreshedParent = super.reconfigure(); - - if (refreshedParent != null - && AbstractConfiguration.class.isAssignableFrom(refreshedParent.getClass())) { - - try { - final XmlExtensionConfiguration refreshed = - new XmlExtensionConfiguration( - refreshedParent.getLoggerContext(), - refreshedParent.getConfigurationSource().resetInputStream()); - createConsoleAppender(); - return refreshed; - } catch (final IOException e) { - LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) - .error("Failed to reload the Log4j2 Xml configuration file", e); - } - } - - LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) - .warn("Cannot programmatically reconfigure loggers"); - return refreshedParent; - } - - private String dim(final String string) { - return String.format("%%style{%s}{DIM}", string); - } - - private String colorize(final String string) { - return String.format("%%highlight{%s}{TRACE=normal}", string); - } - - private final String SEP = dim(" | "); - - private void createConsoleAppender() { - if (customLog4jConfigFilePresent()) { - return; - } - - final PatternLayout patternLayout = - PatternLayout.newBuilder() - .withConfiguration(this) - .withDisableAnsi(!BesuCommand.getColorEnabled().orElse(!noColorSet())) - .withNoConsoleNoAnsi(!BesuCommand.getColorEnabled().orElse(false)) - .withPattern( - String.join( - SEP, - dim("%d{yyyy-MM-dd HH:mm:ss.SSSZZZ}"), - dim("%t"), - colorize("%-5level"), - dim("%c{1}"), - colorize("%msg%n%throwable"))) - .build(); - final ConsoleAppender consoleAppender = - ConsoleAppender.newBuilder().setName("Console").setLayout(patternLayout).build(); - consoleAppender.start(); - this.getRootLogger().addAppender(consoleAppender, null, null); - } - - private static boolean noColorSet() { - return System.getenv("NO_COLOR") != null; - } - - private boolean customLog4jConfigFilePresent() { - return Stream.of("LOG4J_CONFIGURATION_FILE", "log4j.configurationFile") - .flatMap( - configFileKey -> - Stream.of(System.getenv(configFileKey), System.getProperty(configFileKey))) - .flatMap(Stream::ofNullable) - .findFirst() - .isPresent(); - } -} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/ColorEnabledOption.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/ColorEnabledOption.java new file mode 100644 index 00000000000..c47e0af0b1c --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/ColorEnabledOption.java @@ -0,0 +1,37 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.cli.options.stable; + +import picocli.CommandLine; + +public class ColorEnabledOption { + + public static ColorEnabledOption create() { + return new ColorEnabledOption(); + } + + @CommandLine.Option( + names = {"--color-enabled"}, + arity = "1", + description = + "Force color output to be enabled/disabled (default: colorized only if printing to console)") + public void setColorEnabled(final boolean colorEnabled) { + if (colorEnabled) { + System.getProperties().remove("NO_COLOR"); + } else { + System.getProperties().put("NO_COLOR", "true"); + } + } +} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/LoggingLevelOption.java b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/LoggingLevelOption.java index 4b7bb0051ab..0e51ef24e94 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/stable/LoggingLevelOption.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/stable/LoggingLevelOption.java @@ -16,7 +16,7 @@ import java.util.Set; -import org.apache.logging.log4j.Level; +import ch.qos.logback.classic.Level; import picocli.CommandLine; import picocli.CommandLine.Model.CommandSpec; import picocli.CommandLine.Spec; @@ -41,7 +41,7 @@ public void setLogLevel(final String logLevel) { System.out.println("FATAL level is deprecated"); this.logLevel = Level.ERROR; } else if (ACCEPTED_VALUES.contains(logLevel.toUpperCase())) { - this.logLevel = Level.getLevel(logLevel.toUpperCase()); + this.logLevel = Level.toLevel(logLevel.toUpperCase()); } else { throw new CommandLine.ParameterException( spec.commandLine(), "Unknown logging value: " + logLevel); diff --git a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/RetestethSubCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/RetestethSubCommand.java index e63cf966739..f3aaf12cfa3 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/subcommands/RetestethSubCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/subcommands/RetestethSubCommand.java @@ -24,12 +24,12 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration; import org.hyperledger.besu.ethereum.retesteth.RetestethConfiguration; import org.hyperledger.besu.ethereum.retesteth.RetestethService; -import org.hyperledger.besu.util.Log4j2ConfiguratorUtil; +import org.hyperledger.besu.util.LogbackConfiguratorUtil; import java.net.InetAddress; import java.nio.file.Path; -import org.apache.logging.log4j.Level; +import ch.qos.logback.classic.Level; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import picocli.CommandLine.Command; @@ -106,8 +106,8 @@ private void prepareLogging() { // set log level per CLI flags final Level logLevel = loggingLevelOption.getLogLevel(); if (logLevel != null) { - System.out.println("Setting logging level to " + logLevel.name()); - Log4j2ConfiguratorUtil.setAllLevels("", logLevel); + System.out.println("Setting logging level to " + logLevel); + LogbackConfiguratorUtil.setAllLevels("", logLevel); } } @@ -130,7 +130,7 @@ public void run() { () -> { try { retestethService.close(); - Log4j2ConfiguratorUtil.shutdown(); + LogbackConfiguratorUtil.shutdown(); } catch (final Exception e) { LOG.error("Failed to stop Besu Retesteth"); } diff --git a/besu/src/main/resources/log4j2.xml b/besu/src/main/resources/log4j2.xml deleted file mode 100644 index 166b8efa389..00000000000 --- a/besu/src/main/resources/log4j2.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - ${env:LOG_LEVEL:-INFO} - ${env:LOGGER:-Console} - ${env:HOST:-${docker:containerId:-${hostName:-locahost}}} - ${env:SPLUNK_URL} - ${env:SPLUNK_TOKEN} - ${env:SPLUNK_INDEX} - ${env:SPLUNK_SOURCE:-besu} - ${env:SPLUNK_SOURCETYPE:-besu} - ${env:SPLUNK_BATCH_SIZE_BYTES:-65536} - ${env:SPLUNK_BATCH_SIZE_COUNT:-1000} - ${env:SPLUNK_BATCH_INTERVAL:-500} - ${env:SPLUNK_SKIPTLSVERIFY:-false} - - - - - - - - - - - - - - - - - - - - diff --git a/besu/src/main/resources/logback.xml b/besu/src/main/resources/logback.xml new file mode 100644 index 00000000000..af947cf2dc5 --- /dev/null +++ b/besu/src/main/resources/logback.xml @@ -0,0 +1,25 @@ + + + + + true + + %d{yyyy-MM-dd HH:mm:ss.SSSZZZ} | %thread | %highlight(%-5level) | %c{0} | %highlight(%msg%n%throwable) + + + + + %d{yyyy-MM-dd HH:mm:ss.SSSZZZ} | %thread | %-5level | %c{0} | %msg%n%throwable + + + + + + + + + + + + + \ No newline at end of file diff --git a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java index dce113a447e..f7b7852fc83 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -106,12 +106,12 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import ch.qos.logback.classic.Level; import com.google.common.collect.Lists; import com.google.common.io.Resources; import io.vertx.core.json.JsonObject; import org.apache.commons.io.FileUtils; import org.apache.commons.text.StringEscapeUtils; -import org.apache.logging.log4j.Level; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.toml.Toml; import org.apache.tuweni.toml.TomlParseResult; @@ -797,7 +797,7 @@ public void tomlThatConfiguresEverythingExceptPermissioningToml() throws IOExcep .describedAs("Option '%s' should be a configurable option.", tomlKey) .isNotNull(); // Verify TOML stores it by the appropriate type - if (optionSpec.type().equals(Boolean.class)) { + if (optionSpec.type().equals(Boolean.class) || optionSpec.type().equals(Boolean.TYPE)) { tomlResult.getBoolean(tomlKey); } else if (optionSpec.isMultiValue() || optionSpec.arity().max > 1) { tomlResult.getArray(tomlKey); @@ -3450,7 +3450,7 @@ public void colorCanBeEnabledOrDisabledExplicitly() { .forEach( bool -> { parseCommand("--color-enabled", bool.toString()); - assertThat(BesuCommand.getColorEnabled()).contains(bool); + assertThat(System.getProperties().containsKey("NO_COLOR")).isEqualTo(!bool); }); } diff --git a/besu/src/test/java/org/hyperledger/besu/cli/options/stable/LoggingLevelOptionTest.java b/besu/src/test/java/org/hyperledger/besu/cli/options/stable/LoggingLevelOptionTest.java index 78b2d4d55b8..4201a664a0a 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/options/stable/LoggingLevelOptionTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/options/stable/LoggingLevelOptionTest.java @@ -17,9 +17,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Answers.RETURNS_DEEP_STUBS; -import java.util.Arrays; +import java.util.stream.Stream; -import org.apache.logging.log4j.Level; +import ch.qos.logback.classic.Level; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; @@ -43,11 +43,10 @@ public void fatalLevelEqualsToError() { @Test public void setsExpectedLevels() { - Arrays.stream(Level.values()) - .filter(level -> !Level.FATAL.equals(level)) + Stream.of(Level.OFF, Level.ERROR, Level.WARN, Level.INFO, Level.DEBUG, Level.TRACE, Level.ALL) .forEach( level -> { - levelOption.setLogLevel(level.name()); + levelOption.setLogLevel(level.toString()); assertThat(levelOption.getLogLevel()).isEqualTo(level); }); } diff --git a/build.gradle b/build.gradle index 6633b2427a3..3f158947545 100644 --- a/build.gradle +++ b/build.gradle @@ -470,13 +470,6 @@ applicationDefaultJvmArgs = [ '-Dvertx.disableFileCPResolving=true', // BESU_HOME is replaced by a doFirst block in the run task. '-Dbesu.home=BESU_HOME', - // We shutdown log4j ourselves, as otherwise this shutdown hook runs before our own and whatever - // happens during shutdown is not logged. - '-Dlog4j.shutdownHookEnabled=false', - // Disable JNI lookups in log4j messages to improve security - '-Dlog4j2.formatMsgNoLookups=true', - // Redirect java.util.logging loggers to use log4j2. - '-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager', // Suppress Java JPMS warnings. Document the reason for each suppression. // Bouncy Castle needs access to sun.security.provider, which is not open by default. '--add-opens', diff --git a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java index a1fd7639e2e..0d553562341 100644 --- a/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java +++ b/consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeReorgTest.java @@ -40,7 +40,7 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; import org.hyperledger.besu.ethereum.mainnet.feemarket.LondonFeeMarket; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; -import org.hyperledger.besu.util.Log4j2ConfiguratorUtil; +import org.hyperledger.besu.util.LogbackConfiguratorUtil; import java.util.ArrayList; import java.util.List; @@ -106,7 +106,7 @@ public void setUp() { @Test public void reorgsAcrossTDDToDifferentTargetsWhenNotFinal() { // Add N blocks to chain from genesis, where total diff is < TTD - Log4j2ConfiguratorUtil.setLevelDebug(BlockHeaderValidator.class.getName()); + LogbackConfiguratorUtil.setLevelDebug(BlockHeaderValidator.class.getName()); List endOfWork = subChain(genesisState.getBlock().getHeader(), 10, Difficulty.of(100L)); endOfWork.stream().forEach(coordinator::executeBlock); assertThat(blockchain.getChainHead().getHeight()).isEqualTo(10L); diff --git a/ethereum/api/build.gradle b/ethereum/api/build.gradle index 24de67a263f..de0c468e78e 100644 --- a/ethereum/api/build.gradle +++ b/ethereum/api/build.gradle @@ -33,7 +33,6 @@ configurations { dependencies { api 'org.slf4j:slf4j-api' - api 'org.apache.logging.log4j:log4j-api' implementation project(':config') implementation project(':consensus:merge') @@ -53,6 +52,7 @@ dependencies { implementation project(':plugin-api') implementation project(':util') + implementation 'ch.qos.logback:logback-classic' implementation 'com.google.guava:guava' implementation 'com.graphql-java:graphql-java' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8' @@ -92,7 +92,6 @@ dependencies { testImplementation 'io.vertx:vertx-unit' testImplementation 'io.vertx:vertx-web-client' testImplementation 'junit:junit' - testImplementation 'org.apache.logging.log4j:log4j-core' testImplementation 'org.assertj:assertj-core' testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.mockito:mockito-core' diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevel.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevel.java index fe4958104e2..e44732f672d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevel.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevel.java @@ -21,13 +21,13 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; -import org.hyperledger.besu.util.Log4j2ConfiguratorUtil; +import org.hyperledger.besu.util.LogbackConfiguratorUtil; import java.util.Arrays; import java.util.Optional; import java.util.Set; -import org.apache.logging.log4j.Level; +import ch.qos.logback.classic.Level; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,7 +65,7 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } private void setLogLevel(final String logFilter, final Level logLevel) { - LOG.debug("Setting {} logging level to {} ", logFilter, logLevel.name()); - Log4j2ConfiguratorUtil.setAllLevels(logFilter, logLevel); + LOG.debug("Setting {} logging level to {} ", logFilter, logLevel); + LogbackConfiguratorUtil.setAllLevels(logFilter, logLevel); } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevelTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevelTest.java index 9de30690bf3..2540a0dd98e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevelTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminChangeLogLevelTest.java @@ -22,9 +22,9 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; -import org.hyperledger.besu.util.Log4j2ConfiguratorUtil; +import org.hyperledger.besu.util.LogbackConfiguratorUtil; -import org.apache.logging.log4j.Level; +import ch.qos.logback.classic.Level; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -40,7 +40,7 @@ public class AdminChangeLogLevelTest { @Before public void before() { adminChangeLogLevel = new AdminChangeLogLevel(); - Log4j2ConfiguratorUtil.setAllLevels("", Level.INFO); + LogbackConfiguratorUtil.setAllLevels("", Level.INFO); } @Test @@ -52,7 +52,8 @@ public void shouldReturnExpectedMethodName() { public void shouldReturnCorrectResponseWhenRequestHasLogLevel() { final JsonRpcRequestContext request = new JsonRpcRequestContext( - new JsonRpcRequest("2.0", "admin_changeLogLevel", new Object[] {Level.DEBUG.name()})); + new JsonRpcRequest( + "2.0", "admin_changeLogLevel", new Object[] {Level.DEBUG.toString()})); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(request.getRequest().getId()); @@ -71,7 +72,9 @@ public void shouldReturnCorrectResponseWhenRequestHasLogLevelAndFilters() { final JsonRpcRequestContext request = new JsonRpcRequestContext( new JsonRpcRequest( - "2.0", "admin_changeLogLevel", new Object[] {Level.DEBUG.name(), new String[] {"com"}})); + "2.0", + "admin_changeLogLevel", + new Object[] {Level.DEBUG.toString(), new String[] {"com"}})); final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(request.getRequest().getId()); diff --git a/ethereum/core/build.gradle b/ethereum/core/build.gradle index 6787ee772c8..ac76b0356ba 100644 --- a/ethereum/core/build.gradle +++ b/ethereum/core/build.gradle @@ -76,7 +76,6 @@ dependencies { testImplementation project(':testutil') testImplementation 'junit:junit' - testImplementation 'org.apache.logging.log4j:log4j-core' testImplementation 'org.apache.tuweni:tuweni-bytes' testImplementation 'org.apache.tuweni:tuweni-io' testImplementation 'org.apache.tuweni:tuweni-units' diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/AbstractRetryingTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/AbstractRetryingTest.java index e15887ddd67..0091c2acd97 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/AbstractRetryingTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/AbstractRetryingTest.java @@ -14,7 +14,6 @@ */ package org.hyperledger.besu.ethereum.vm; -import org.hyperledger.besu.util.Log4j2ConfiguratorUtil; import org.junit.Before; import org.junit.Test; @@ -49,7 +48,6 @@ public void resetLoggingToOriginalConfiguration() { } else { System.setProperty("evm.log.level", originalEvmLogLevel); } - resetLogging(); } /** Run the test case. */ @@ -63,7 +61,6 @@ public void execution() { // try again, this time with more logging so we can capture more information. System.setProperty("root.log.level", "trace"); System.setProperty("evm.log.level", "trace"); - resetLogging(); runTest(); } else { throw e; @@ -71,10 +68,6 @@ public void execution() { } } - private void resetLogging() { - Log4j2ConfiguratorUtil.reconfigure(); - } - /** Subclasses should implement this method to run the actual JUnit test. */ protected abstract void runTest(); } diff --git a/ethereum/evmtool/build.gradle b/ethereum/evmtool/build.gradle index 68c2b15e941..0b7dbb880ae 100644 --- a/ethereum/evmtool/build.gradle +++ b/ethereum/evmtool/build.gradle @@ -51,12 +51,12 @@ dependencies { implementation project(':services:kvstore') implementation project(':util') + implementation 'ch.qos.logback:logback-classic' implementation 'com.fasterxml.jackson.core:jackson-databind' implementation 'com.google.dagger:dagger' implementation 'com.google.guava:guava' implementation 'info.picocli:picocli' implementation 'io.vertx:vertx-core' - implementation 'org.apache.logging.log4j:log4j-core' annotationProcessor 'com.google.dagger:dagger-compiler' diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java index ff502d59ceb..47a46a8f7c9 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java @@ -36,7 +36,7 @@ import org.hyperledger.besu.evm.processor.MessageCallProcessor; import org.hyperledger.besu.evm.tracing.OperationTracer; import org.hyperledger.besu.evm.tracing.StandardJsonTracer; -import org.hyperledger.besu.util.Log4j2ConfiguratorUtil; +import org.hyperledger.besu.util.LogbackConfiguratorUtil; import java.io.File; import java.io.IOException; @@ -48,9 +48,9 @@ import java.util.List; import java.util.Optional; +import ch.qos.logback.classic.Level; import com.google.common.base.Stopwatch; import io.vertx.core.json.JsonObject; -import org.apache.logging.log4j.Level; import org.apache.tuweni.bytes.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -201,12 +201,12 @@ public void run() { .blockHeaderFunctions(new MainnetBlockHeaderFunctions()) .buildBlockHeader(); - Log4j2ConfiguratorUtil.setAllLevels("", repeat == 0 ? Level.INFO : Level.OFF); + LogbackConfiguratorUtil.setAllLevels("", repeat == 0 ? Level.INFO : Level.OFF); int repeat = this.repeat; - Log4j2ConfiguratorUtil.setLevel( + LogbackConfiguratorUtil.setLevel( "org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder", Level.OFF); final ProtocolSpec protocolSpec = component.getProtocolSpec().apply(0); - Log4j2ConfiguratorUtil.setLevel( + LogbackConfiguratorUtil.setLevel( "org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder", null); final PrecompileContractRegistry precompileContractRegistry = protocolSpec.getPrecompileContractRegistry(); diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java index 917c27be9ae..f4c68518ce3 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java @@ -41,7 +41,7 @@ import org.hyperledger.besu.evm.worldstate.WorldState; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import org.hyperledger.besu.evmtool.exception.UnsupportedForkException; -import org.hyperledger.besu.util.Log4j2ConfiguratorUtil; +import org.hyperledger.besu.util.LogbackConfiguratorUtil; import java.io.BufferedReader; import java.io.File; @@ -53,13 +53,13 @@ import java.util.Map; import java.util.concurrent.TimeUnit; +import ch.qos.logback.classic.Level; import com.fasterxml.jackson.core.JsonParser.Feature; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.base.Stopwatch; -import org.apache.logging.log4j.Level; import org.apache.tuweni.units.bigints.UInt256; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -152,10 +152,10 @@ private void executeStateTest(final Map genera } private void traceTestSpecs(final String test, final List specs) { - Log4j2ConfiguratorUtil.setLevel( + LogbackConfiguratorUtil.setLevel( "org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder", Level.OFF); final var referenceTestProtocolSchedules = ReferenceTestProtocolSchedules.create(); - Log4j2ConfiguratorUtil.setLevel( + LogbackConfiguratorUtil.setLevel( "org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder", null); final OperationTracer tracer = // You should have picked Mercy. diff --git a/ethereum/p2p/build.gradle b/ethereum/p2p/build.gradle index c74192dbe06..646b200926b 100644 --- a/ethereum/p2p/build.gradle +++ b/ethereum/p2p/build.gradle @@ -58,7 +58,11 @@ dependencies { annotationProcessor "org.immutables:value" implementation "org.immutables:value-annotations" - implementation 'tech.pegasys.discovery:discovery' + implementation('tech.pegasys.discovery:discovery') { + exclude group: 'org.apache.logging.log4j' + } + + runtimeOnly 'org.apache.logging.log4j:log4j-to-slf4j' // test dependencies. testImplementation project(path: ':ethereum:core', configuration: 'testArtifacts') diff --git a/gradle/versions.gradle b/gradle/versions.gradle index ca753057383..0e8779a0477 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -15,6 +15,8 @@ dependencyManagement { dependencies { + dependency 'ch.qos.logback:logback-classic:1.2.10' + dependency 'com.fasterxml.jackson.core:jackson-databind:2.13.2.2' dependency 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.2' @@ -112,10 +114,7 @@ dependencyManagement { dependency 'org.apache.commons:commons-compress:1.21' dependency 'org.apache.commons:commons-text:1.9' - dependency 'org.apache.logging.log4j:log4j-api:2.17.2' - dependency 'org.apache.logging.log4j:log4j-core:2.17.2' - dependency 'org.apache.logging.log4j:log4j-jul:2.17.2' - dependency 'org.apache.logging.log4j:log4j-slf4j-impl:2.17.2' + dependency 'org.apache.logging.log4j:log4j-to-slf4j:2.17.2' dependency 'org.apache.tuweni:tuweni-bytes:2.2.0' dependency 'org.apache.tuweni:tuweni-config:2.2.0' @@ -138,6 +137,9 @@ dependencyManagement { entry'bcprov-jdk15on' } + dependency 'org.codehaus.janino:janino:3.1.6' + dependency 'org.codehaus.janino:commons-compiler:3.1.6' + dependency 'org.fusesource.jansi:jansi:2.4.0' dependency 'org.hyperledger.besu:bls12-381:0.4.3' @@ -164,6 +166,7 @@ dependencyManagement { dependency 'org.rocksdb:rocksdbjni:6.29.5' + dependency 'org.slf4j:jul-to-slf4j:1.7.25' dependency 'org.slf4j:slf4j-api:1.7.25' dependency 'org.springframework.security:spring-security-crypto:5.6.2' diff --git a/util/build.gradle b/util/build.gradle index 483a778fb5f..37d2551c755 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -32,10 +32,9 @@ dependencies { implementation project(':plugin-api') + implementation 'ch.qos.logback:logback-classic' implementation 'com.google.guava:guava' implementation 'io.vertx:vertx-core' - implementation 'org.apache.logging.log4j:log4j-core' - implementation 'org.apache.logging.log4j:log4j-slf4j-impl' implementation 'org.apache.tuweni:tuweni-bytes' implementation 'org.apache.tuweni:tuweni-units' implementation 'org.xerial.snappy:snappy-java' diff --git a/util/src/main/java/org/hyperledger/besu/util/Log4j2ConfiguratorUtil.java b/util/src/main/java/org/hyperledger/besu/util/Log4j2ConfiguratorUtil.java deleted file mode 100644 index 88f0d5378db..00000000000 --- a/util/src/main/java/org/hyperledger/besu/util/Log4j2ConfiguratorUtil.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright contributors to Hyperledger Besu. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.util; - -import java.util.Map; -import java.util.Set; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.LoggerConfig; -import org.apache.logging.log4j.util.Strings; -import org.apache.logging.slf4j.Log4jLoggerFactory; -import org.slf4j.LoggerFactory; - -public class Log4j2ConfiguratorUtil { - - private Log4j2ConfiguratorUtil() {} - - public static void setAllLevels(final String parentLogger, final Level level) { - // 1) get logger config - // 2) if exact match, use it, if not, create it. - // 3) set level on logger config - // 4) update child logger configs with level - // 5) update loggers - final LoggerContext loggerContext = getLoggerContext(); - final Configuration config = loggerContext.getConfiguration(); - boolean set = setLevel(parentLogger, level, config); - for (final Map.Entry entry : config.getLoggers().entrySet()) { - if (entry.getKey().startsWith(parentLogger)) { - set |= setLevel(entry.getValue(), level); - } - } - if (set) { - loggerContext.updateLoggers(); - } - } - - public static void setLevelDebug(final String loggerName) { - setLevel(loggerName, Level.DEBUG); - } - - public static void setLevel(final String loggerName, final Level level) { - final LoggerContext loggerContext = getLoggerContext(); - if (Strings.isEmpty(loggerName)) { - setRootLevel(loggerContext, level); - } else if (setLevel(loggerName, level, loggerContext.getConfiguration())) { - loggerContext.updateLoggers(); - } - } - - private static boolean setLevel( - final String loggerName, final Level level, final Configuration config) { - boolean set; - LoggerConfig loggerConfig = config.getLoggerConfig(loggerName); - if (!loggerName.equals(loggerConfig.getName())) { - loggerConfig = new LoggerConfig(loggerName, level, true); - config.addLogger(loggerName, loggerConfig); - loggerConfig.setLevel(level); - set = true; - } else { - set = setLevel(loggerConfig, level); - } - return set; - } - - private static boolean setLevel(final LoggerConfig loggerConfig, final Level level) { - final boolean set = !loggerConfig.getLevel().equals(level); - if (set) { - loggerConfig.setLevel(level); - } - return set; - } - - private static void setRootLevel(final LoggerContext loggerContext, final Level level) { - final LoggerConfig loggerConfig = loggerContext.getConfiguration().getRootLogger(); - if (!loggerConfig.getLevel().equals(level)) { - loggerConfig.setLevel(level); - loggerContext.updateLoggers(); - } - } - - public static void reconfigure() { - getLoggerContext().reconfigure(); - } - - private static LoggerContext getLoggerContext() { - final Set loggerContexts = - ((Log4jLoggerFactory) LoggerFactory.getILoggerFactory()).getLoggerContexts(); - return (LoggerContext) loggerContexts.iterator().next(); - } - - public static void shutdown() { - getLoggerContext().terminate(); - } -} diff --git a/util/src/main/java/org/hyperledger/besu/util/LogbackConfiguratorUtil.java b/util/src/main/java/org/hyperledger/besu/util/LogbackConfiguratorUtil.java new file mode 100644 index 00000000000..26f66f43a61 --- /dev/null +++ b/util/src/main/java/org/hyperledger/besu/util/LogbackConfiguratorUtil.java @@ -0,0 +1,64 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.util; + +import java.net.URL; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.util.ContextInitializer; +import ch.qos.logback.core.joran.spi.JoranException; +import org.slf4j.LoggerFactory; + +public class LogbackConfiguratorUtil { + + private LogbackConfiguratorUtil() {} + + public static void setAllLevels(final String parentLogger, final Level level) { + LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); + for (Logger logger : loggerContext.getLoggerList()) { + if (logger.getName().startsWith(parentLogger)) { + logger.setLevel(level); + } + } + } + + public static void setLevelDebug(final String loggerName) { + setLevel(loggerName, Level.DEBUG); + } + + public static void setLevel(final String loggerName, final Level level) { + LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); + if (loggerName == null || loggerName.isBlank()) { + loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME).setLevel(level); + } else { + loggerContext.getLogger(loggerName).setLevel(level); + } + } + + public static void reconfigure() throws JoranException { + LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); + ContextInitializer ci = new ContextInitializer(loggerContext); + URL url = ci.findURLOfDefaultConfigurationFile(true); + loggerContext.reset(); + ci.configureByResource(url); + } + + public static void shutdown() { + LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); + loggerContext.stop(); + } +} diff --git a/util/src/test/java/org/hyperledger/besu/util/Slf4jLambdaHelperTest.java b/util/src/test/java/org/hyperledger/besu/util/Slf4jLambdaHelperTest.java index cac6336fac7..d69f49ec00a 100644 --- a/util/src/test/java/org/hyperledger/besu/util/Slf4jLambdaHelperTest.java +++ b/util/src/test/java/org/hyperledger/besu/util/Slf4jLambdaHelperTest.java @@ -22,7 +22,7 @@ import java.util.ArrayDeque; import java.util.function.Supplier; -import org.apache.logging.log4j.Level; +import ch.qos.logback.classic.Level; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; @@ -41,7 +41,7 @@ public void paramSetup() { @Test public void smokeDebugLambda() { - Log4j2ConfiguratorUtil.setLevel(LOG.getName(), Level.WARN); + LogbackConfiguratorUtil.setLevel(LOG.getName(), Level.WARN); debugLambda( LOG, "blah", @@ -49,7 +49,7 @@ public void smokeDebugLambda() { () -> { throw new RuntimeException("should not evaluate"); }); - Log4j2ConfiguratorUtil.setLevelDebug(LOG.getName()); + LogbackConfiguratorUtil.setLevelDebug(LOG.getName()); assertThat(paramStack.size()).isEqualTo(3); debugLambda(LOG, "blah {}", paramStack::pop); assertThat(paramStack.size()).isEqualTo(2); @@ -66,7 +66,7 @@ public void smokeTraceLambda() { () -> { throw new RuntimeException("should not evaluate"); }); - Log4j2ConfiguratorUtil.setLevel(LOG.getName(), Level.TRACE); + LogbackConfiguratorUtil.setLevel(LOG.getName(), Level.TRACE); assertThat(paramStack.size()).isEqualTo(3); traceLambda(LOG, "blah {}", paramStack::pop); assertThat(paramStack.size()).isEqualTo(2); @@ -76,7 +76,7 @@ public void smokeTraceLambda() { @Test public void smokeWarnLambda() { - Log4j2ConfiguratorUtil.setLevel(LOG.getName(), Level.OFF); + LogbackConfiguratorUtil.setLevel(LOG.getName(), Level.OFF); traceLambda( LOG, "blah", @@ -84,7 +84,7 @@ public void smokeWarnLambda() { () -> { throw new RuntimeException("should not evaluate"); }); - Log4j2ConfiguratorUtil.setLevel(LOG.getName(), Level.WARN); + LogbackConfiguratorUtil.setLevel(LOG.getName(), Level.WARN); assertThat(paramStack.size()).isEqualTo(3); warnLambda(LOG, "blah {}", paramStack::pop); assertThat(paramStack.size()).isEqualTo(2);