diff --git a/README.adoc b/README.adoc index 38b87ea11..d24e3d40a 100644 --- a/README.adoc +++ b/README.adoc @@ -54,7 +54,7 @@ The ideal place for questions or discussions about the HiveMQ Community Edition === Quick Start -* Download the latest https://github.com/hivemq/hivemq-community-edition/releases/download/2023.8/hivemq-ce-2023.8.zip[HiveMQ CE binary package]. +* Download the latest https://github.com/hivemq/hivemq-community-edition/releases/download/2023.9/hivemq-ce-2023.9.zip[HiveMQ CE binary package]. * Unzip the package. * Run the run.sh (Linux/OSX) or run.bat (Windows) in the bin folder of the package. @@ -140,7 +140,7 @@ If you use Gradle, include the following code in your `build.gradle(.kts)` file. ---- dependencies { - implementation("com.hivemq:hivemq-community-edition-embedded:2023.8") + implementation("com.hivemq:hivemq-community-edition-embedded:2023.9") } ---- @@ -156,7 +156,7 @@ If you use Maven, include the following code in your `pom.xml` file. com.hivemq hivemq-community-edition-embedded - 2023.8 + 2023.9 ... diff --git a/gradle.properties b/gradle.properties index f71d95dfb..0e19f38d2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=2023.8 +version=2023.9 # # tools # diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ab5d1db4a..d94f3ba5f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ equalsVerifier = "3.14.2" findsecbugs = "1.12.0" guava = "32.0.1-jre" guice = "5.1.0" -hivemq-extensionSdk = "4.21.0" +hivemq-extensionSdk = "4.22.0" jackson = "2.15.2" javassist = "3.29.2-GA" javax-annotation-api = "1.3.2" diff --git a/src/distribution/bin/diagnostics.bat b/src/distribution/bin/diagnostics.bat index 94ebfd16d..5c19ebccd 100755 --- a/src/distribution/bin/diagnostics.bat +++ b/src/distribution/bin/diagnostics.bat @@ -65,7 +65,8 @@ rem limitations under the License. set "JAVA_OPTS=%JAVA_OPTS% --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/sun.security.provider=ALL-UNNAMED --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED --add-exports java.base/jdk.internal.misc=ALL-UNNAMED" rem JMX Monitoring - set "JAVA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false %JAVA_OPTS%" + IF NOT DEFINED HIVEMQ_JMX_PORT SET "HIVEMQ_JMX_PORT=9010" + set "JAVA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=%HIVEMQ_JMX_PORT% -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false %JAVA_OPTS%" set "JAVA_OPTS=-DdiagnosticMode=true %JAVA_OPTS%" @@ -128,4 +129,4 @@ GOTO :EOF :RESOLVE SET %2=%~f1 -GOTO :EOF \ No newline at end of file +GOTO :EOF diff --git a/src/distribution/bin/diagnostics.sh b/src/distribution/bin/diagnostics.sh index a47f0338b..a513d4b7f 100755 --- a/src/distribution/bin/diagnostics.sh +++ b/src/distribution/bin/diagnostics.sh @@ -54,7 +54,7 @@ if hash java 2>/dev/null; then fi # JMX Monitoring - JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" + JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=${HIVEMQ_JMX_PORT:-9010} -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" JAVA_OPTS="$JAVA_OPTS -DdiagnosticMode=true" diff --git a/src/distribution/bin/run.bat b/src/distribution/bin/run.bat index 345855922..e12c4439e 100644 --- a/src/distribution/bin/run.bat +++ b/src/distribution/bin/run.bat @@ -65,7 +65,8 @@ rem limitations under the License. rem JMX Monitoring - set "JAVA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false %JAVA_OPTS%" + IF NOT DEFINED HIVEMQ_JMX_PORT SET "HIVEMQ_JMX_PORT=9010" + set "JAVA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=%HIVEMQ_JMX_PORT% -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false %JAVA_OPTS%" rem Uncomment for enabling diagnostic mode rem set "JAVA_OPTS=-DdiagnosticMode=true %JAVA_OPTS%" @@ -128,4 +129,4 @@ GOTO :EOF :RESOLVE SET %2=%~f1 -GOTO :EOF \ No newline at end of file +GOTO :EOF diff --git a/src/distribution/bin/run.sh b/src/distribution/bin/run.sh index 939b00357..d6be19698 100755 --- a/src/distribution/bin/run.sh +++ b/src/distribution/bin/run.sh @@ -52,7 +52,7 @@ if hash java 2>/dev/null; then fi # JMX Monitoring - JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" + JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=${HIVEMQ_JMX_PORT:-9010} -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" # Uncomment for enabling Diagnostic Mode #JAVA_OPTS="$JAVA_OPTS -DdiagnosticMode=true" diff --git a/src/distribution/third-party-licenses/licenses b/src/distribution/third-party-licenses/licenses index 69cb8488f..cf1a8d820 100644 --- a/src/distribution/third-party-licenses/licenses +++ b/src/distribution/third-party-licenses/licenses @@ -21,7 +21,7 @@ HiveMQ uses the following third party libraries: com.sun.activation:jakarta.activation | 1.2.2 | BSD-3-Clause | https://www.eclipse.org/org/documents/edl-v10.php com.sun.xml.bind:jaxb-impl | 2.3.8 | BSD-3-Clause | https://www.eclipse.org/org/documents/edl-v10.php commons-io:commons-io | 2.13.0 | Apache-2.0 | https://spdx.org/licenses/Apache-2.0.html - io.dropwizard.metrics:metrics-core | 4.2.19 | Apache-2.0 | https://spdx.org/licenses/Apache-2.0.html + io.dropwizard.metrics:metrics-core | 4.2.22 | Apache-2.0 | https://spdx.org/licenses/Apache-2.0.html io.dropwizard.metrics:metrics-jmx | 4.2.19 | Apache-2.0 | https://spdx.org/licenses/Apache-2.0.html io.dropwizard.metrics:metrics-logback | 4.2.19 | Apache-2.0 | https://spdx.org/licenses/Apache-2.0.html io.github.microutils:kotlin-logging | 1.4.1 | Apache-2.0 | https://spdx.org/licenses/Apache-2.0.html @@ -56,7 +56,7 @@ HiveMQ uses the following third party libraries: org.jetbrains.xodus:xodus-utils | 1.2.3 | Apache-2.0 | https://spdx.org/licenses/Apache-2.0.html org.rocksdb:rocksdbjni | 7.4.5 | Apache-2.0 | https://spdx.org/licenses/Apache-2.0.html org.slf4j:jul-to-slf4j | 2.0.7 | MIT | https://spdx.org/licenses/MIT.html - org.slf4j:slf4j-api | 2.0.7 | MIT | https://spdx.org/licenses/MIT.html + org.slf4j:slf4j-api | 2.0.9 | MIT | https://spdx.org/licenses/MIT.html -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The open source code of the libraries can be obtained by sending an email to legal@hivemq.com. diff --git a/src/distribution/third-party-licenses/licenses.html b/src/distribution/third-party-licenses/licenses.html index 24287f7f2..072f7d32a 100644 --- a/src/distribution/third-party-licenses/licenses.html +++ b/src/distribution/third-party-licenses/licenses.html @@ -172,7 +172,7 @@

Third Party Licenses

io.dropwizard.metrics:metrics-core - 4.2.19 + 4.2.22 Apache-2.0 https://spdx.org/licenses/Apache-2.0.html @@ -487,7 +487,7 @@

Third Party Licenses

org.slf4j:slf4j-api - 2.0.7 + 2.0.9 MIT https://spdx.org/licenses/MIT.html diff --git a/src/main/java/com/hivemq/bootstrap/LoggingBootstrap.java b/src/main/java/com/hivemq/bootstrap/LoggingBootstrap.java index 70d1a2f20..bb9a706d6 100644 --- a/src/main/java/com/hivemq/bootstrap/LoggingBootstrap.java +++ b/src/main/java/com/hivemq/bootstrap/LoggingBootstrap.java @@ -25,9 +25,10 @@ import ch.qos.logback.core.read.ListAppender; import ch.qos.logback.core.util.StatusPrinter; import com.hivemq.extension.sdk.api.annotations.NotNull; -import com.hivemq.logging.NettyLogLevelModifier; -import com.hivemq.logging.XodusEnvironmentImplLogLevelModificator; -import com.hivemq.logging.XodusFileDataWriterLogLevelModificator; +import com.hivemq.logging.LogLevelModifierTurboFilter; +import com.hivemq.logging.modifier.NettyLogLevelModifier; +import com.hivemq.logging.modifier.XodusEnvironmentImplLogLevelModifier; +import com.hivemq.logging.modifier.XodusFileDataWriterLogLevelModifier; import org.apache.commons.lang3.SystemUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,22 +43,15 @@ * This class is responsible for all logging bootstrapping. This is only * needed at the very beginning of HiveMQs lifecycle and before bootstrapping other * resources - * - * @author Dominik Obermaier */ public class LoggingBootstrap { - private static @NotNull ListAppender listAppender = new ListAppender<>(); - private static final Logger log = LoggerFactory.getLogger(LoggingBootstrap.class); - private static final XodusFileDataWriterLogLevelModificator xodusFileDataWriterLogLevelModificator = - new XodusFileDataWriterLogLevelModificator(); - private static final NettyLogLevelModifier nettyLogLevelModifier = new NettyLogLevelModifier(); - private static final XodusEnvironmentImplLogLevelModificator xodusEnvironmentImplLogLevelModificator = - new XodusEnvironmentImplLogLevelModificator(); - + private static @NotNull ListAppender listAppender = new ListAppender<>(); private static final List> defaultAppenders = new LinkedList<>(); + private static final @NotNull LogLevelModifierTurboFilter logLevelModifierTurboFilter = + new LogLevelModifierTurboFilter(); /** * Prepares the logging. This method must be called before any logging occurs @@ -90,9 +84,8 @@ public static void prepareLogging() { public static void initLogging(final @NotNull File configFolder) { final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); - final ch.qos.logback.classic.Logger logger = getRootLogger(); - context.addListener(new LogbackChangeListener(logger)); + context.addListener(new LogbackChangeListener()); final boolean overridden = overrideLogbackXml(configFolder); @@ -104,13 +97,15 @@ public static void initLogging(final @NotNull File configFolder) { reset(); + context.addTurboFilter(logLevelModifierTurboFilter); + // must be added here, as addLoglevelModifiers() is much to late if (SystemUtils.IS_OS_WINDOWS) { - context.addTurboFilter(xodusFileDataWriterLogLevelModificator); + logLevelModifierTurboFilter.registerLogLevelModifier(new XodusFileDataWriterLogLevelModifier()); log.trace("Added Xodus log level modifier for FileDataWriter.class"); } - context.addTurboFilter(nettyLogLevelModifier); + logLevelModifierTurboFilter.registerLogLevelModifier(new NettyLogLevelModifier()); log.trace("Added Netty log level modifier"); } @@ -194,9 +189,7 @@ private static boolean overrideLogbackXml(final @NotNull File configFolder) { } public static void addLoglevelModifiers() { - final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); - - context.addTurboFilter(xodusEnvironmentImplLogLevelModificator); + logLevelModifierTurboFilter.registerLogLevelModifier(new XodusEnvironmentImplLogLevelModifier()); log.trace("Added Xodus log level modifier for EnvironmentImpl.class"); } @@ -208,14 +201,7 @@ private static void reset() { listAppender.list.clear(); } - private static class LogbackChangeListener implements LoggerContextListener { - - private final @NotNull ch.qos.logback.classic.Logger logger; - - private LogbackChangeListener( - final @NotNull ch.qos.logback.classic.Logger logger) { - this.logger = logger; - } + private static final class LogbackChangeListener implements LoggerContextListener { @Override public boolean isResetResistant() { @@ -237,7 +223,7 @@ public void onStart(final @NotNull LoggerContext context) { @Override public void onReset(final @NotNull LoggerContext context) { log.trace("logback.xml was changed"); - addTurboFilters(context); + context.addTurboFilter(logLevelModifierTurboFilter); } @Override @@ -249,12 +235,5 @@ public void onStop(final @NotNull LoggerContext context) { public void onLevelChange(final @NotNull ch.qos.logback.classic.Logger logger, final @NotNull Level level) { //noop } - - private void addTurboFilters(final @NotNull LoggerContext context) { - - context.addTurboFilter(xodusFileDataWriterLogLevelModificator); - context.addTurboFilter(nettyLogLevelModifier); - context.addTurboFilter(xodusEnvironmentImplLogLevelModificator); - } } } diff --git a/src/main/java/com/hivemq/logging/LogLevelModifierTurboFilter.java b/src/main/java/com/hivemq/logging/LogLevelModifierTurboFilter.java new file mode 100644 index 000000000..97ef5e3ea --- /dev/null +++ b/src/main/java/com/hivemq/logging/LogLevelModifierTurboFilter.java @@ -0,0 +1,62 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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. + */ +package com.hivemq.logging; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.turbo.TurboFilter; +import ch.qos.logback.core.spi.FilterReply; +import com.hivemq.extension.sdk.api.annotations.NotNull; +import com.hivemq.extension.sdk.api.annotations.Nullable; +import com.hivemq.logging.modifier.LogLevelModifier; +import org.slf4j.Marker; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +public class LogLevelModifierTurboFilter extends TurboFilter { + + private final @NotNull List logLevelModifiers = new CopyOnWriteArrayList<>(); + + @Override + public @NotNull FilterReply decide( + final @Nullable Marker marker, + final @NotNull Logger logger, + final @NotNull Level level, + final @Nullable String format, + final @Nullable Object @Nullable [] params, + final @Nullable Throwable t) { + + FilterReply filterReply = FilterReply.NEUTRAL; + + if (format == null || level == Level.OFF) { + // format is the log message + return filterReply; + } + + for (final LogLevelModifier logLevelModifier : logLevelModifiers) { + filterReply = logLevelModifier.decide(marker, logger, level, format, params, t); + if (filterReply != FilterReply.NEUTRAL) { + return filterReply; + } + } + return filterReply; + } + + public void registerLogLevelModifier(final @NotNull LogLevelModifier logLevelModifier) { + logLevelModifiers.add(logLevelModifier); + } +} diff --git a/src/main/java/com/hivemq/logging/NettyLogLevelModifier.java b/src/main/java/com/hivemq/logging/NettyLogLevelModifier.java deleted file mode 100644 index 4c0108c82..000000000 --- a/src/main/java/com/hivemq/logging/NettyLogLevelModifier.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2019-present HiveMQ GmbH - * - * 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. - */ -package com.hivemq.logging; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.turbo.TurboFilter; -import ch.qos.logback.core.spi.FilterReply; -import com.hivemq.extension.sdk.api.annotations.NotNull; -import org.slf4j.Marker; - -/** - * @author Lukas Brandl - */ -public class NettyLogLevelModifier extends TurboFilter { - - @Override - public FilterReply decide( - final Marker marker, - final Logger logger, - final Level level, - final String format, - final Object[] params, - final Throwable t) { - - if (format == null || logger == null) { - return FilterReply.NEUTRAL; - } - - if (logger.getName() == null) { - return FilterReply.NEUTRAL; - } - - if (level == Level.DEBUG) { - - if (logger.getName().startsWith("io.netty.handler.traffic.")) { - return FilterReply.DENY; - } else if (logger.getName().contains("io.netty.util.internal.NativeLibraryLoader")) { - if (t instanceof UnsatisfiedLinkError) { - return FilterReply.DENY; - } - if (params == null) { - logger.trace(marker, format, params); - return FilterReply.DENY; - } - final Object[] paramList = params; - for (final Object param : paramList) { - if (param instanceof UnsatisfiedLinkError) { - return FilterReply.DENY; - } - } - logger.trace(marker, format, params); - return FilterReply.DENY; - } else if (logger.getName().startsWith("io.netty")) { - return traceAndSortOutUnsupportedOperationException(marker, logger, format, params, t); - } - - } else if (level == Level.TRACE) { - if (logger.getName().contains("io.netty.channel.nio.NioEventLoop")) { - return sortOutUnsupportedOperationException(params, t); - } - } - - return FilterReply.NEUTRAL; - } - - @NotNull - private FilterReply traceAndSortOutUnsupportedOperationException( - final Marker marker, final Logger logger, final String format, final Object[] params, final Throwable t) { - if (t instanceof UnsupportedOperationException) { - return FilterReply.DENY; - } - if (params == null) { - logger.trace(marker, format, params); - return FilterReply.DENY; - } - final Object[] paramList = params; - for (final Object param : paramList) { - if (param instanceof UnsupportedOperationException) { - return FilterReply.DENY; - } - } - logger.trace(marker, format, params); - return FilterReply.DENY; - } - - @NotNull - private FilterReply sortOutUnsupportedOperationException(final Object[] params, final Throwable t) { - if (t instanceof UnsupportedOperationException) { - return FilterReply.DENY; - } - if (params == null) { - return FilterReply.NEUTRAL; - } - final Object[] paramList = params; - for (final Object param : paramList) { - if (param instanceof UnsupportedOperationException) { - return FilterReply.DENY; - } - } - return FilterReply.NEUTRAL; - } - -} diff --git a/src/main/java/com/hivemq/logging/XodusEnvironmentImplLogLevelModificator.java b/src/main/java/com/hivemq/logging/XodusEnvironmentImplLogLevelModificator.java deleted file mode 100644 index 8b3ba8702..000000000 --- a/src/main/java/com/hivemq/logging/XodusEnvironmentImplLogLevelModificator.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2019-present HiveMQ GmbH - * - * 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. - */ -package com.hivemq.logging; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.turbo.TurboFilter; -import ch.qos.logback.core.spi.FilterReply; -import com.google.common.annotations.VisibleForTesting; -import jetbrains.exodus.ExodusException; -import jetbrains.exodus.env.EnvironmentImpl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.Marker; - -/** - * This Log Level Modificator is used to modify the log level of Xodus logs. - * - * @author Dominik Obermaier - */ -public class XodusEnvironmentImplLogLevelModificator extends TurboFilter { - - @VisibleForTesting - final static Logger environmentalLogger = LoggerFactory.getLogger(EnvironmentImpl.class); - - @Override - public FilterReply decide( - final Marker marker, - final ch.qos.logback.classic.Logger logger, - final Level level, - final String format, - final Object[] params, - final Throwable t) { - if (level.isGreaterOrEqual(Level.INFO)) { - - if (logger.getName().equals(environmentalLogger.getName())) { - - if (format != null) { - - if (format.contains("transaction(s) not finished")) { - logger.trace(marker, format, params); - return FilterReply.DENY; - } else if (format.contains("Transactions stack traces are not available")) { - logger.trace(marker, format, params); - return FilterReply.DENY; - } - } - } - } - - - if (level.isGreaterOrEqual(Level.ERROR) && - t != null && - t.getMessage() != null && - t instanceof ExodusException) { - if (t.getMessage().contains("cleanFile") || t.getMessage().contains("There is no file by address")) { - logger.trace(marker, "Xodus background job unable to cleanup stale data just now, trying again later"); - return FilterReply.DENY; - } - } - - // Let other filters decide - return FilterReply.NEUTRAL; - } -} - - diff --git a/src/main/java/com/hivemq/logging/XodusFileDataWriterLogLevelModificator.java b/src/main/java/com/hivemq/logging/XodusFileDataWriterLogLevelModificator.java deleted file mode 100644 index ab9a07802..000000000 --- a/src/main/java/com/hivemq/logging/XodusFileDataWriterLogLevelModificator.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2019-present HiveMQ GmbH - * - * 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. - */ -package com.hivemq.logging; - - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.turbo.TurboFilter; -import ch.qos.logback.core.spi.FilterReply; -import com.google.common.annotations.VisibleForTesting; -import jetbrains.exodus.io.FileDataWriter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.Marker; - -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * @author Georg Held - */ -public class XodusFileDataWriterLogLevelModificator extends TurboFilter { - - @VisibleForTesting - static final Logger fileDataWriterLogger = LoggerFactory.getLogger(FileDataWriter.class); - private static final Logger log = LoggerFactory.getLogger(XodusFileDataWriterLogLevelModificator.class); - - private final AtomicBoolean first = new AtomicBoolean(true); - - @Override - public FilterReply decide( - final Marker marker, - final ch.qos.logback.classic.Logger logger, - final Level level, - final String format, - final Object[] params, - final Throwable t) { - - if (level.isGreaterOrEqual(Level.WARN)) { - if (logger.getName().equals(fileDataWriterLogger.getName())) { - if (format != null) { - if (format.startsWith("Can't open directory channel. Log directory fsync won't be performed.")) { - if (first.getAndSet(false)) { - log.debug("Can't open directory channel. Log directory fsync won't be performed."); - } - return FilterReply.DENY; - } - } - } - - } - return FilterReply.NEUTRAL; - } -} diff --git a/src/main/java/com/hivemq/logging/modifier/LogLevelModifier.java b/src/main/java/com/hivemq/logging/modifier/LogLevelModifier.java new file mode 100644 index 000000000..6c48733c2 --- /dev/null +++ b/src/main/java/com/hivemq/logging/modifier/LogLevelModifier.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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. + */ +package com.hivemq.logging.modifier; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.core.spi.FilterReply; +import com.hivemq.extension.sdk.api.annotations.NotNull; +import com.hivemq.extension.sdk.api.annotations.Nullable; +import org.slf4j.Marker; + +public interface LogLevelModifier { + + @NotNull FilterReply decide( + @Nullable Marker marker, + @NotNull Logger logger, + @NotNull Level level, + @NotNull String format, + @Nullable Object @Nullable [] params, + @Nullable Throwable t); +} diff --git a/src/main/java/com/hivemq/logging/modifier/NettyLogLevelModifier.java b/src/main/java/com/hivemq/logging/modifier/NettyLogLevelModifier.java new file mode 100644 index 000000000..cf627323c --- /dev/null +++ b/src/main/java/com/hivemq/logging/modifier/NettyLogLevelModifier.java @@ -0,0 +1,96 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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. + */ +package com.hivemq.logging.modifier; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.core.spi.FilterReply; +import com.hivemq.extension.sdk.api.annotations.NotNull; +import com.hivemq.extension.sdk.api.annotations.Nullable; +import org.slf4j.Marker; + +public class NettyLogLevelModifier implements LogLevelModifier { + + @Override + public @NotNull FilterReply decide( + final @Nullable Marker marker, + final @NotNull Logger logger, + final @NotNull Level level, + final @NotNull String format, + final @Nullable Object @Nullable [] params, + final @Nullable Throwable t) { + + if (level == Level.DEBUG) { + if (logger.getName().startsWith("io.netty")) { + if (logger.getName().startsWith("io.netty.handler.traffic.")) { + return FilterReply.DENY; + } + if (logger.getName().startsWith("io.netty.util.internal.NativeLibraryLoader")) { + if (t instanceof UnsatisfiedLinkError) { + return FilterReply.DENY; + } + if (params == null) { + logger.trace(marker, format, params); + return FilterReply.DENY; + } + for (final Object param : params) { + if (param instanceof UnsatisfiedLinkError) { + return FilterReply.DENY; + } + } + logger.trace(marker, format, params); + return FilterReply.DENY; + } + traceAndSortOutUnsupportedOperationException(marker, logger, format, params, t); + return FilterReply.DENY; + } + } else if (level == Level.TRACE) { + if (logger.getName().startsWith("io.netty.channel.nio.NioEventLoop")) { + if (t instanceof UnsupportedOperationException) { + return FilterReply.DENY; + } + if (params != null) { + for (final Object param : params) { + if (param instanceof UnsupportedOperationException) { + return FilterReply.DENY; + } + } + } + } + } + return FilterReply.NEUTRAL; + } + + private static void traceAndSortOutUnsupportedOperationException( + final @Nullable Marker marker, + final @NotNull Logger logger, + final @NotNull String format, + final @Nullable Object @Nullable [] params, + final @Nullable Throwable t) { + + if (t instanceof UnsupportedOperationException) { + return; + } + if (params != null) { + for (final Object param : params) { + if (param instanceof UnsupportedOperationException) { + return; + } + } + } + logger.trace(marker, format, params); + } +} diff --git a/src/main/java/com/hivemq/logging/modifier/XodusEnvironmentImplLogLevelModifier.java b/src/main/java/com/hivemq/logging/modifier/XodusEnvironmentImplLogLevelModifier.java new file mode 100644 index 000000000..1a7895d7e --- /dev/null +++ b/src/main/java/com/hivemq/logging/modifier/XodusEnvironmentImplLogLevelModifier.java @@ -0,0 +1,67 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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. + */ +package com.hivemq.logging.modifier; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.core.spi.FilterReply; +import com.hivemq.extension.sdk.api.annotations.NotNull; +import com.hivemq.extension.sdk.api.annotations.Nullable; +import jetbrains.exodus.ExodusException; +import jetbrains.exodus.env.EnvironmentImpl; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; + +public class XodusEnvironmentImplLogLevelModifier implements LogLevelModifier { + + private final @NotNull Logger environmentalLogger; + + public XodusEnvironmentImplLogLevelModifier() { + final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + environmentalLogger = context.getLogger(EnvironmentImpl.class); + } + + @Override + public @NotNull FilterReply decide( + final @Nullable Marker marker, + final @NotNull Logger logger, + final @NotNull Level level, + final @NotNull String format, + final @Nullable Object @Nullable [] params, + final @Nullable Throwable t) { + + if (level.isGreaterOrEqual(Level.INFO)) { + if (logger.equals(environmentalLogger)) { + if (format.contains("transaction(s) not finished")) { + logger.trace(marker, format, params); + return FilterReply.DENY; + } + if (format.contains("Transactions stack traces are not available")) { + logger.trace(marker, format, params); + return FilterReply.DENY; + } + } + if (level == Level.ERROR && t instanceof ExodusException) { + if (t.getMessage().contains("cleanFile") || t.getMessage().contains("There is no file by address")) { + logger.trace(marker, "Xodus background job unable to cleanup stale data just now, trying again later"); + return FilterReply.DENY; + } + } + } + return FilterReply.NEUTRAL; + } +} diff --git a/src/main/java/com/hivemq/logging/modifier/XodusFileDataWriterLogLevelModifier.java b/src/main/java/com/hivemq/logging/modifier/XodusFileDataWriterLogLevelModifier.java new file mode 100644 index 000000000..51c3b53e1 --- /dev/null +++ b/src/main/java/com/hivemq/logging/modifier/XodusFileDataWriterLogLevelModifier.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019-present HiveMQ GmbH + * + * 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. + */ +package com.hivemq.logging.modifier; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.core.spi.FilterReply; +import com.hivemq.extension.sdk.api.annotations.NotNull; +import com.hivemq.extension.sdk.api.annotations.Nullable; +import jetbrains.exodus.io.FileDataWriter; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; + +import java.util.concurrent.atomic.AtomicBoolean; + +public class XodusFileDataWriterLogLevelModifier implements LogLevelModifier { + + private final @NotNull AtomicBoolean first = new AtomicBoolean(true); + private final @NotNull Logger fileDataWriterLogger; + + public XodusFileDataWriterLogLevelModifier() { + final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + fileDataWriterLogger = context.getLogger(FileDataWriter.class); + } + + @Override + public @NotNull FilterReply decide( + final @Nullable Marker marker, + final @NotNull ch.qos.logback.classic.Logger logger, + final @NotNull Level level, + final @NotNull String format, + final @Nullable Object @Nullable [] params, + final @Nullable Throwable t) { + + if (level.isGreaterOrEqual(Level.WARN)) { + if (logger.equals(fileDataWriterLogger)) { + if (format.startsWith("Can't open directory channel. Log directory fsync won't be performed.")) { + if (first.getAndSet(false)) { + logger.debug("Can't open directory channel. Log directory fsync won't be performed."); + } + return FilterReply.DENY; + } + } + } + return FilterReply.NEUTRAL; + } +} diff --git a/src/test/java/com/hivemq/logging/NettyLogLevelModifierTest.java b/src/test/java/com/hivemq/logging/modifier/NettyLogLevelModifierTest.java similarity index 83% rename from src/test/java/com/hivemq/logging/NettyLogLevelModifierTest.java rename to src/test/java/com/hivemq/logging/modifier/NettyLogLevelModifierTest.java index 87826fd06..fd541b272 100644 --- a/src/test/java/com/hivemq/logging/NettyLogLevelModifierTest.java +++ b/src/test/java/com/hivemq/logging/modifier/NettyLogLevelModifierTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hivemq.logging; +package com.hivemq.logging.modifier; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; @@ -24,9 +24,6 @@ import static org.junit.Assert.assertEquals; -/** - * @author Lukas Brandl - */ public class NettyLogLevelModifierTest { private NettyLogLevelModifier nettyLogLevelModifier; @@ -37,46 +34,37 @@ public class NettyLogLevelModifierTest { public void setUp() throws Exception { final LoggerContext context = (LoggerContext) org.slf4j.LoggerFactory.getILoggerFactory(); - rootLogger = context.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); nettyLogLevelModifier = new NettyLogLevelModifier(); } @Test - public void test_level_trace() throws Exception { - - final FilterReply decide = nettyLogLevelModifier.decide(null, null, Level.TRACE, "", null, null); - + public void test_level_trace() { + final FilterReply decide = nettyLogLevelModifier.decide(null, rootLogger, Level.TRACE, "", null, null); assertEquals(FilterReply.NEUTRAL, decide); } @Test - public void test_level_all() throws Exception { - - final FilterReply decide = nettyLogLevelModifier.decide(null, null, Level.ALL, "", null, null); - + public void test_level_all() { + final FilterReply decide = nettyLogLevelModifier.decide(null, rootLogger, Level.ALL, "", null, null); assertEquals(FilterReply.NEUTRAL, decide); } @Test - public void test_level_info_format_null() throws Exception { - - final FilterReply decide = nettyLogLevelModifier.decide(null, null, Level.INFO, null, null, null); - + public void test_level_info_format_null() { + final FilterReply decide = nettyLogLevelModifier.decide(null, rootLogger, Level.INFO, null, null, null); assertEquals(FilterReply.NEUTRAL, decide); } @Test - public void test_level_info_format_set() throws Exception { - + public void test_level_info_format_set() { final FilterReply decide = nettyLogLevelModifier.decide(null, rootLogger, Level.INFO, format, null, null); - assertEquals(FilterReply.NEUTRAL, decide); } @Test - public void test_level_info_format_denied_throwable() throws Exception { + public void test_level_info_format_denied_throwable() { final LoggerContext context = (LoggerContext) org.slf4j.LoggerFactory.getILoggerFactory(); rootLogger = context.getLogger("io.netty.util.internal.PlatformDependent0"); @@ -92,7 +80,7 @@ public void test_level_info_format_denied_throwable() throws Exception { } @Test - public void test_level_info_format_neutral_throwable() throws Exception { + public void test_level_info_format_neutral_throwable() { final LoggerContext context = (LoggerContext) org.slf4j.LoggerFactory.getILoggerFactory(); rootLogger = context.getLogger("io.netty.channel.nio.NioEventLoop"); @@ -104,7 +92,7 @@ public void test_level_info_format_neutral_throwable() throws Exception { } @Test - public void test_level_trace_format_denied_throwable() throws Exception { + public void test_level_trace_format_denied_throwable() { final LoggerContext context = (LoggerContext) org.slf4j.LoggerFactory.getILoggerFactory(); rootLogger = context.getLogger("io.netty.channel.nio.NioEventLoop"); @@ -120,7 +108,7 @@ public void test_level_trace_format_denied_throwable() throws Exception { } @Test - public void test_level_info_format_denied_parameter() throws Exception { + public void test_level_info_format_denied_parameter() { final LoggerContext context = (LoggerContext) org.slf4j.LoggerFactory.getILoggerFactory(); rootLogger = context.getLogger("io.netty.util.internal.PlatformDependent0"); @@ -136,7 +124,7 @@ public void test_level_info_format_denied_parameter() throws Exception { } @Test - public void test_level_debug_native_denied_parameter() throws Exception { + public void test_level_debug_native_denied_parameter() { final LoggerContext context = (LoggerContext) org.slf4j.LoggerFactory.getILoggerFactory(); rootLogger = context.getLogger("io.netty.util.internal.NativeLibraryLoader"); diff --git a/src/test/java/com/hivemq/logging/XodusEnvironmentImplLogLevelModificatorTest.java b/src/test/java/com/hivemq/logging/modifier/XodusEnvironmentImplLogLevelModifierTest.java similarity index 69% rename from src/test/java/com/hivemq/logging/XodusEnvironmentImplLogLevelModificatorTest.java rename to src/test/java/com/hivemq/logging/modifier/XodusEnvironmentImplLogLevelModifierTest.java index a871b5b8f..ab802bda1 100644 --- a/src/test/java/com/hivemq/logging/XodusEnvironmentImplLogLevelModificatorTest.java +++ b/src/test/java/com/hivemq/logging/modifier/XodusEnvironmentImplLogLevelModifierTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hivemq.logging; +package com.hivemq.logging.modifier; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.LoggerContext; @@ -21,8 +21,12 @@ import ch.qos.logback.core.Appender; import ch.qos.logback.core.filter.Filter; import ch.qos.logback.core.spi.FilterReply; +import com.hivemq.bootstrap.LoggingBootstrap; import com.hivemq.extension.sdk.api.annotations.NotNull; +import com.hivemq.logging.LogLevelModifierTurboFilter; +import jetbrains.exodus.env.EnvironmentImpl; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; @@ -32,32 +36,40 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; -/** - * @author Dominik Obermaier - */ -public class XodusEnvironmentImplLogLevelModificatorTest { +public class XodusEnvironmentImplLogLevelModifierTest { private ch.qos.logback.classic.Logger rootLogger; + private LoggerContext context; private Level level; @Before public void setUp() throws Exception { - final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + context = (LoggerContext) LoggerFactory.getILoggerFactory(); rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME); + final LogLevelModifierTurboFilter logLevelModifierTurboFilter = new LogLevelModifierTurboFilter(); + logLevelModifierTurboFilter.registerLogLevelModifier(new XodusEnvironmentImplLogLevelModifier()); level = rootLogger.getLevel(); rootLogger.setLevel(Level.TRACE); - context.addTurboFilter(new XodusEnvironmentImplLogLevelModificator()); + context.addTurboFilter(logLevelModifierTurboFilter); context.getLogger("jetbrains.exodus").setLevel(Level.TRACE); } @After public void tearDown() throws Exception { rootLogger.setLevel(level); + context.resetTurboFilterList(); + } + + @AfterClass + public static void afterClass() { + final LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); + loggerContext.reset(); + LoggingBootstrap.prepareLogging(); } @Test @@ -72,9 +84,9 @@ public void test_xodus_error_message_transactions_not_finished() throws Exceptio appenderIterator.next().addFilter(createFilter(countDownLatch, msg)); } - XodusEnvironmentImplLogLevelModificator.environmentalLogger.error(msg); + context.getLogger(EnvironmentImpl.class).error(msg); - assertEquals(true, countDownLatch.await(3, TimeUnit.SECONDS)); + assertTrue(countDownLatch.await(3, TimeUnit.SECONDS)); } @Test @@ -87,14 +99,15 @@ public void test_xodus_error_message_transaction_stack_traces_not_available() th appenderIterator.next().addFilter(createFilter(countDownLatch, msg)); } - XodusEnvironmentImplLogLevelModificator.environmentalLogger.error(msg); + context.getLogger(EnvironmentImpl.class).error(msg); - assertEquals(true, countDownLatch.await(3, TimeUnit.SECONDS)); + assertTrue(countDownLatch.await(3, TimeUnit.SECONDS)); } - @NotNull - private Filter createFilter(final CountDownLatch countDownLatch, final String text) { - return new Filter() { + private @NotNull Filter createFilter( + final @NotNull CountDownLatch countDownLatch, final @NotNull String text) { + + return new Filter<>() { @Override public FilterReply decide(final ILoggingEvent event) { if (event.getLevel().equals(Level.TRACE)) { diff --git a/src/test/java/com/hivemq/logging/XodusFileDataWriterLogLevelModificatorSingularityTest.java b/src/test/java/com/hivemq/logging/modifier/XodusFileDataWriterLogLevelModifierSingularityTest.java similarity index 61% rename from src/test/java/com/hivemq/logging/XodusFileDataWriterLogLevelModificatorSingularityTest.java rename to src/test/java/com/hivemq/logging/modifier/XodusFileDataWriterLogLevelModifierSingularityTest.java index cba89450d..e7c5d07fa 100644 --- a/src/test/java/com/hivemq/logging/XodusFileDataWriterLogLevelModificatorSingularityTest.java +++ b/src/test/java/com/hivemq/logging/modifier/XodusFileDataWriterLogLevelModifierSingularityTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hivemq.logging; +package com.hivemq.logging.modifier; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.LoggerContext; @@ -21,23 +21,23 @@ import ch.qos.logback.core.Appender; import ch.qos.logback.core.filter.Filter; import ch.qos.logback.core.spi.FilterReply; +import com.hivemq.bootstrap.LoggingBootstrap; import com.hivemq.extension.sdk.api.annotations.NotNull; +import com.hivemq.logging.LogLevelModifierTurboFilter; +import jetbrains.exodus.io.FileDataWriter; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Iterator; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import static org.junit.Assert.assertEquals; -/** - * @author Georg Held - */ -public class XodusFileDataWriterLogLevelModificatorSingularityTest { +public class XodusFileDataWriterLogLevelModifierSingularityTest { private ch.qos.logback.classic.Logger rootLogger; private Level level; @@ -50,9 +50,11 @@ public void setUp() throws Exception { rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME); + final LogLevelModifierTurboFilter logLevelModifierTurboFilter = new LogLevelModifierTurboFilter(); + logLevelModifierTurboFilter.registerLogLevelModifier(new XodusFileDataWriterLogLevelModifier()); level = rootLogger.getLevel(); rootLogger.setLevel(Level.DEBUG); - context.addTurboFilter(new XodusFileDataWriterLogLevelModificator()); + context.addTurboFilter(logLevelModifierTurboFilter); context.getLogger("jetbrains.exodus").setLevel(Level.DEBUG); } @@ -62,35 +64,42 @@ public void tearDown() throws Exception { context.resetTurboFilterList(); } + @AfterClass + public static void afterClass() { + final LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); + loggerContext.reset(); + LoggingBootstrap.prepareLogging(); + } - @Test(timeout = 5000) - public void test_get_only_logged_once() throws Exception { + @Test + public void test_get_only_logged_once() { final String msg = "Can't open directory channel. Log directory fsync won't be performed."; - final CountDownLatch countDownLatch = new CountDownLatch(2); + final AtomicInteger loggedCounter = new AtomicInteger(); final Iterator> appenderIterator = rootLogger.iteratorForAppenders(); final Appender next = appenderIterator.next(); - next.addFilter(createFilter(countDownLatch, msg)); + next.addFilter(createFilter(loggedCounter, msg)); - XodusFileDataWriterLogLevelModificator.fileDataWriterLogger.warn(msg); - XodusFileDataWriterLogLevelModificator.fileDataWriterLogger.warn(msg); - XodusFileDataWriterLogLevelModificator.fileDataWriterLogger.warn(msg); - XodusFileDataWriterLogLevelModificator.fileDataWriterLogger.warn(msg); - XodusFileDataWriterLogLevelModificator.fileDataWriterLogger.warn(msg); + final ch.qos.logback.classic.Logger logger = context.getLogger(FileDataWriter.class); + logger.warn(msg); + logger.warn(msg); + logger.warn(msg); + logger.warn(msg); + logger.warn(msg); - assertEquals(false, countDownLatch.await(3, TimeUnit.SECONDS)); + assertEquals(1, loggedCounter.get()); } + private @NotNull Filter createFilter( + final @NotNull AtomicInteger loggedCounter, final @NotNull String text) { - @NotNull - private Filter createFilter(final CountDownLatch countDownLatch, final String text) { - return new Filter() { + return new Filter<>() { @Override public FilterReply decide(final ILoggingEvent event) { if (event.getLevel().equals(Level.DEBUG)) { if (event.getFormattedMessage().equals(text)) { - countDownLatch.countDown(); + loggedCounter.getAndIncrement(); return FilterReply.NEUTRAL; } } diff --git a/src/test/java/com/hivemq/logging/XodusFileDataWriterLogLevelModificatorTest.java b/src/test/java/com/hivemq/logging/modifier/XodusFileDataWriterLogLevelModifierTest.java similarity index 63% rename from src/test/java/com/hivemq/logging/XodusFileDataWriterLogLevelModificatorTest.java rename to src/test/java/com/hivemq/logging/modifier/XodusFileDataWriterLogLevelModifierTest.java index b04830545..66da9c7aa 100644 --- a/src/test/java/com/hivemq/logging/XodusFileDataWriterLogLevelModificatorTest.java +++ b/src/test/java/com/hivemq/logging/modifier/XodusFileDataWriterLogLevelModifierTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hivemq.logging; +package com.hivemq.logging.modifier; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.LoggerContext; @@ -21,23 +21,24 @@ import ch.qos.logback.core.Appender; import ch.qos.logback.core.filter.Filter; import ch.qos.logback.core.spi.FilterReply; +import com.hivemq.bootstrap.LoggingBootstrap; import com.hivemq.extension.sdk.api.annotations.NotNull; +import com.hivemq.logging.LogLevelModifierTurboFilter; +import jetbrains.exodus.io.FileDataWriter; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Iterator; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import static org.junit.Assert.assertEquals; -/** - * @author Georg Held - */ -public class XodusFileDataWriterLogLevelModificatorTest { + +public class XodusFileDataWriterLogLevelModifierTest { private ch.qos.logback.classic.Logger rootLogger; private Level level; @@ -50,9 +51,11 @@ public void setUp() throws Exception { rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME); + final LogLevelModifierTurboFilter logLevelModifierTurboFilter = new LogLevelModifierTurboFilter(); + logLevelModifierTurboFilter.registerLogLevelModifier(new XodusFileDataWriterLogLevelModifier()); level = rootLogger.getLevel(); rootLogger.setLevel(Level.DEBUG); - context.addTurboFilter(new XodusFileDataWriterLogLevelModificator()); + context.addTurboFilter(logLevelModifierTurboFilter); context.getLogger("jetbrains.exodus").setLevel(Level.DEBUG); } @@ -62,30 +65,37 @@ public void tearDown() throws Exception { context.resetTurboFilterList(); } - @Test(timeout = 5000) - public void test_first_time_gets_modified_to_debug() throws Exception { + @AfterClass + public static void afterClass() { + final LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); + loggerContext.reset(); + LoggingBootstrap.prepareLogging(); + } + + @Test + public void test_first_time_gets_modified_to_debug() { final String msg = "Can't open directory channel. Log directory fsync won't be performed."; - final CountDownLatch countDownLatch = new CountDownLatch(1); + final AtomicInteger loggedCounter = new AtomicInteger(); final Iterator> appenderIterator = rootLogger.iteratorForAppenders(); while (appenderIterator.hasNext()) { - - appenderIterator.next().addFilter(createFilter(countDownLatch, msg)); + appenderIterator.next().addFilter(createFilter(loggedCounter, msg)); } - XodusFileDataWriterLogLevelModificator.fileDataWriterLogger.warn(msg); + context.getLogger(FileDataWriter.class).warn(msg); - assertEquals(true, countDownLatch.await(5, TimeUnit.SECONDS)); + assertEquals(1, loggedCounter.get()); } - @NotNull - private Filter createFilter(final CountDownLatch countDownLatch, final String text) { - return new Filter() { + private @NotNull Filter createFilter( + final @NotNull AtomicInteger loggedCounter, final @NotNull String text) { + + return new Filter<>() { @Override public FilterReply decide(final ILoggingEvent event) { if (event.getLevel().equals(Level.DEBUG)) { if (event.getFormattedMessage().equals(text)) { - countDownLatch.countDown(); + loggedCounter.getAndIncrement(); return FilterReply.NEUTRAL; } } @@ -93,4 +103,4 @@ public FilterReply decide(final ILoggingEvent event) { } }; } -} \ No newline at end of file +}