You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ck...@apache.org on 2019/06/20 15:48:43 UTC
[logging-log4j2] branch master updated: LOG4J2-2634: Break up large
AsyncLogger methods for inlining
This is an automated email from the ASF dual-hosted git repository.
ckozak pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/master by this push:
new 547eab8 LOG4J2-2634: Break up large AsyncLogger methods for inlining
new ef7121e Merge pull request #282 from carterkozak/ckozak/async_logger_35byte_methods
547eab8 is described below
commit 547eab8535e52e7333cb597ecc83ef2b3ec69972
Author: Carter Kozak <ck...@apache.org>
AuthorDate: Wed May 29 15:42:55 2019 -0400
LOG4J2-2634: Break up large AsyncLogger methods for inlining
---
.../logging/log4j/core/async/AsyncLogger.java | 72 +++++++++++++++-------
.../core/async/RingBufferLogEventHandler.java | 5 +-
src/changes/changes.xml | 3 +
3 files changed, 58 insertions(+), 22 deletions(-)
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
index 1afead0..7d7a1e7 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
@@ -26,6 +26,7 @@ import org.apache.logging.log4j.core.ContextDataInjector;
import org.apache.logging.log4j.core.Logger;
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.core.config.Property;
import org.apache.logging.log4j.core.config.ReliabilityStrategy;
import org.apache.logging.log4j.core.impl.ContextDataFactory;
@@ -126,13 +127,32 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
@Override
public void logMessage(final String fqcn, final Level level, final Marker marker, final Message message,
final Throwable thrown) {
+ getTranslatorType().log(fqcn, level, marker, message, thrown);
+ }
+
+ abstract class TranslatorType {
+
+ abstract void log(final String fqcn, final Level level, final Marker marker,
+ final Message message, final Throwable thrown);
+ }
- if (loggerDisruptor.isUseThreadLocals()) {
+ private final TranslatorType threadLocalTranslatorType = new TranslatorType() {
+ @Override
+ void log(String fqcn, Level level, Marker marker, Message message, Throwable thrown) {
logWithThreadLocalTranslator(fqcn, level, marker, message, thrown);
- } else {
+ }
+ };
+
+ private final TranslatorType varargTranslatorType = new TranslatorType() {
+ @Override
+ void log(String fqcn, Level level, Marker marker, Message message, Throwable thrown) {
// LOG4J2-1172: avoid storing non-JDK classes in ThreadLocals to avoid memory leaks in web apps
logWithVarargTranslator(fqcn, level, marker, message, thrown);
}
+ };
+
+ private TranslatorType getTranslatorType() {
+ return loggerDisruptor.isUseThreadLocals() ? threadLocalTranslatorType : varargTranslatorType;
}
private boolean isReused(final Message message) {
@@ -355,29 +375,39 @@ public class AsyncLogger extends Logger implements EventTranslatorVararg<RingBuf
* @param event the event to log
*/
public void actualAsyncLog(final RingBufferLogEvent event) {
- final List<Property> properties = privateConfig.loggerConfig.getPropertyList();
+ final LoggerConfig privateConfigLoggerConfig = privateConfig.loggerConfig;
+ final List<Property> properties = privateConfigLoggerConfig.getPropertyList();
if (properties != null) {
- StringMap contextData = (StringMap) event.getContextData();
- if (contextData.isFrozen()) {
- final StringMap temp = ContextDataFactory.createContextData();
- temp.putAll(contextData);
- contextData = temp;
- }
- for (int i = 0; i < properties.size(); i++) {
- final Property prop = properties.get(i);
- if (contextData.getValue(prop.getName()) != null) {
- continue; // contextMap overrides config properties
- }
- final String value = prop.isValueNeedsLookup() //
- ? privateConfig.config.getStrSubstitutor().replace(event, prop.getValue()) //
- : prop.getValue();
- contextData.putValue(prop.getName(), value);
+ onPropertiesPresent(event, properties);
+ }
+
+ privateConfigLoggerConfig.getReliabilityStrategy().log(this, event);
+ }
+
+ @SuppressWarnings("ForLoopReplaceableByForEach") // Avoid iterator allocation
+ private void onPropertiesPresent(final RingBufferLogEvent event, final List<Property> properties) {
+ StringMap contextData = getContextData(event);
+ for (int i = 0, size = properties.size(); i < size; i++) {
+ final Property prop = properties.get(i);
+ if (contextData.getValue(prop.getName()) != null) {
+ continue; // contextMap overrides config properties
}
- event.setContextData(contextData);
+ final String value = prop.isValueNeedsLookup() //
+ ? privateConfig.config.getStrSubstitutor().replace(event, prop.getValue()) //
+ : prop.getValue();
+ contextData.putValue(prop.getName(), value);
}
+ event.setContextData(contextData);
+ }
- final ReliabilityStrategy strategy = privateConfig.loggerConfig.getReliabilityStrategy();
- strategy.log(this, event);
+ private static StringMap getContextData(final RingBufferLogEvent event) {
+ StringMap contextData = (StringMap) event.getContextData();
+ if (contextData.isFrozen()) {
+ final StringMap temp = ContextDataFactory.createContextData();
+ temp.putAll(contextData);
+ return temp;
+ }
+ return contextData;
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventHandler.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventHandler.java
index e4a496c..f0cab8d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventHandler.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventHandler.java
@@ -44,10 +44,13 @@ public class RingBufferLogEventHandler implements
final boolean endOfBatch) throws Exception {
event.execute(endOfBatch);
event.clear();
-
// notify the BatchEventProcessor that the sequence has progressed.
// Without this callback the sequence would not be progressed
// until the batch has completely finished.
+ notifyCallback(sequence);
+ }
+
+ private void notifyCallback(long sequence) {
if (++counter > NOTIFY_PROGRESS_THRESHOLD) {
sequenceCallback.set(sequence);
counter = 0;
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index d385b4f..039c9cc 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -224,6 +224,9 @@
<action issue="LOG4J2-2606" dev="ckozak" type="fix">
Asynchronous logging when the queue is full no longer results in heavy CPU utilization and low throughput.
</action>
+ <action issue="LOG4J2-2634" dev="ckozak" type="update">
+ Refactor several AsyncLogger methods below the 35 byte threshold for inlining.
+ </action>
</release>
<release version="2.11.2" date="2018-MM-DD" description="GA Release 2.11.2">
<action issue="LOG4J2-2500" dev="rgoers" type="fix">