Skip to content

Commit 361604d

Browse files
committed
Logging > The current TurboFilterList implementation of logback-classic which calls the TurboFilters is a CopyOnWriteArrayList. This means every time any logger method is called the array of TurboFilters is copied. As we are using the logger extensively this small copy is visible in the flamegraph. A call to isXLevelEnabled check does not avoid this path.
1 parent 818415e commit 361604d

13 files changed

+422
-380
lines changed

src/main/java/com/hivemq/bootstrap/LoggingBootstrap.java

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@
2525
import ch.qos.logback.core.read.ListAppender;
2626
import ch.qos.logback.core.util.StatusPrinter;
2727
import com.hivemq.extension.sdk.api.annotations.NotNull;
28-
import com.hivemq.logging.NettyLogLevelModifier;
29-
import com.hivemq.logging.XodusEnvironmentImplLogLevelModificator;
30-
import com.hivemq.logging.XodusFileDataWriterLogLevelModificator;
28+
import com.hivemq.logging.LogLevelModifierTurboFilter;
29+
import com.hivemq.logging.modifier.NettyLogLevelModifier;
30+
import com.hivemq.logging.modifier.XodusEnvironmentImplLogLevelModifier;
31+
import com.hivemq.logging.modifier.XodusFileDataWriterLogLevelModifier;
3132
import org.apache.commons.lang3.SystemUtils;
3233
import org.slf4j.Logger;
3334
import org.slf4j.LoggerFactory;
@@ -42,22 +43,15 @@
4243
* This class is responsible for all logging bootstrapping. This is only
4344
* needed at the very beginning of HiveMQs lifecycle and before bootstrapping other
4445
* resources
45-
*
46-
* @author Dominik Obermaier
4746
*/
4847
public class LoggingBootstrap {
4948

50-
private static @NotNull ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
51-
5249
private static final Logger log = LoggerFactory.getLogger(LoggingBootstrap.class);
5350

54-
private static final XodusFileDataWriterLogLevelModificator xodusFileDataWriterLogLevelModificator =
55-
new XodusFileDataWriterLogLevelModificator();
56-
private static final NettyLogLevelModifier nettyLogLevelModifier = new NettyLogLevelModifier();
57-
private static final XodusEnvironmentImplLogLevelModificator xodusEnvironmentImplLogLevelModificator =
58-
new XodusEnvironmentImplLogLevelModificator();
59-
51+
private static @NotNull ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
6052
private static final List<Appender<ILoggingEvent>> defaultAppenders = new LinkedList<>();
53+
private static final @NotNull LogLevelModifierTurboFilter logLevelModifierTurboFilter =
54+
new LogLevelModifierTurboFilter();
6155

6256
/**
6357
* Prepares the logging. This method must be called before any logging occurs
@@ -90,9 +84,8 @@ public static void prepareLogging() {
9084
public static void initLogging(final @NotNull File configFolder) {
9185

9286
final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
93-
final ch.qos.logback.classic.Logger logger = getRootLogger();
9487

95-
context.addListener(new LogbackChangeListener(logger));
88+
context.addListener(new LogbackChangeListener());
9689

9790
final boolean overridden = overrideLogbackXml(configFolder);
9891

@@ -104,13 +97,15 @@ public static void initLogging(final @NotNull File configFolder) {
10497

10598
reset();
10699

100+
context.addTurboFilter(logLevelModifierTurboFilter);
101+
107102
// must be added here, as addLoglevelModifiers() is much to late
108103
if (SystemUtils.IS_OS_WINDOWS) {
109-
context.addTurboFilter(xodusFileDataWriterLogLevelModificator);
104+
logLevelModifierTurboFilter.registerLogLevelModifier(new XodusFileDataWriterLogLevelModifier());
110105
log.trace("Added Xodus log level modifier for FileDataWriter.class");
111106
}
112107

113-
context.addTurboFilter(nettyLogLevelModifier);
108+
logLevelModifierTurboFilter.registerLogLevelModifier(new NettyLogLevelModifier());
114109
log.trace("Added Netty log level modifier");
115110
}
116111

@@ -194,9 +189,7 @@ private static boolean overrideLogbackXml(final @NotNull File configFolder) {
194189
}
195190

196191
public static void addLoglevelModifiers() {
197-
final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
198-
199-
context.addTurboFilter(xodusEnvironmentImplLogLevelModificator);
192+
logLevelModifierTurboFilter.registerLogLevelModifier(new XodusEnvironmentImplLogLevelModifier());
200193
log.trace("Added Xodus log level modifier for EnvironmentImpl.class");
201194
}
202195

@@ -208,14 +201,7 @@ private static void reset() {
208201
listAppender.list.clear();
209202
}
210203

211-
private static class LogbackChangeListener implements LoggerContextListener {
212-
213-
private final @NotNull ch.qos.logback.classic.Logger logger;
214-
215-
private LogbackChangeListener(
216-
final @NotNull ch.qos.logback.classic.Logger logger) {
217-
this.logger = logger;
218-
}
204+
private static final class LogbackChangeListener implements LoggerContextListener {
219205

220206
@Override
221207
public boolean isResetResistant() {
@@ -237,7 +223,7 @@ public void onStart(final @NotNull LoggerContext context) {
237223
@Override
238224
public void onReset(final @NotNull LoggerContext context) {
239225
log.trace("logback.xml was changed");
240-
addTurboFilters(context);
226+
context.addTurboFilter(logLevelModifierTurboFilter);
241227
}
242228

243229
@Override
@@ -249,12 +235,5 @@ public void onStop(final @NotNull LoggerContext context) {
249235
public void onLevelChange(final @NotNull ch.qos.logback.classic.Logger logger, final @NotNull Level level) {
250236
//noop
251237
}
252-
253-
private void addTurboFilters(final @NotNull LoggerContext context) {
254-
255-
context.addTurboFilter(xodusFileDataWriterLogLevelModificator);
256-
context.addTurboFilter(nettyLogLevelModifier);
257-
context.addTurboFilter(xodusEnvironmentImplLogLevelModificator);
258-
}
259238
}
260239
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2019-present HiveMQ GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.hivemq.logging;
17+
18+
import ch.qos.logback.classic.Level;
19+
import ch.qos.logback.classic.Logger;
20+
import ch.qos.logback.classic.turbo.TurboFilter;
21+
import ch.qos.logback.core.spi.FilterReply;
22+
import com.hivemq.extension.sdk.api.annotations.NotNull;
23+
import com.hivemq.extension.sdk.api.annotations.Nullable;
24+
import com.hivemq.logging.modifier.LogLevelModifier;
25+
import org.slf4j.Marker;
26+
27+
import java.util.ArrayList;
28+
import java.util.List;
29+
30+
public class LogLevelModifierTurboFilter extends TurboFilter {
31+
32+
private @NotNull List<LogLevelModifier> logLevelModifiers = new ArrayList<>();
33+
34+
@Override
35+
public @NotNull FilterReply decide(
36+
final @Nullable Marker marker,
37+
final @NotNull Logger logger,
38+
final @NotNull Level level,
39+
final @Nullable String format,
40+
final @Nullable Object @Nullable [] params,
41+
final @Nullable Throwable t) {
42+
43+
FilterReply filterReply = FilterReply.NEUTRAL;
44+
45+
if (format == null || level == Level.OFF) {
46+
// format is the log message
47+
return filterReply;
48+
}
49+
50+
for (final LogLevelModifier logLevelModifier : logLevelModifiers) {
51+
filterReply = logLevelModifier.decide(marker, logger, level, format, params, t);
52+
if (filterReply != FilterReply.NEUTRAL) {
53+
return filterReply;
54+
}
55+
}
56+
return filterReply;
57+
}
58+
59+
public void registerLogLevelModifier(final @NotNull LogLevelModifier logLevelModifier) {
60+
final List<LogLevelModifier> tmp = new ArrayList<>(logLevelModifiers);
61+
tmp.add(logLevelModifier);
62+
logLevelModifiers = tmp;
63+
}
64+
}

src/main/java/com/hivemq/logging/NettyLogLevelModifier.java

Lines changed: 0 additions & 117 deletions
This file was deleted.

src/main/java/com/hivemq/logging/XodusEnvironmentImplLogLevelModificator.java

Lines changed: 0 additions & 79 deletions
This file was deleted.

0 commit comments

Comments
 (0)