You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2022/09/03 08:38:21 UTC
[logging-log4j2] 01/02: [LOG4J2-2975] Implements the SLF4J LoggingEventBuilder
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 1003c9a3605416256e47c089fd55ba645304a103
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Sun Aug 28 13:14:14 2022 +0200
[LOG4J2-2975] Implements the SLF4J LoggingEventBuilder
This PR implements the SLF4J 2.0 `LoggingEventBuilder`, taking care of
preserving the caller information.
---
.../java/org/apache/logging/log4j/BridgeAware.java | 34 +++++
.../logging/log4j/internal/DefaultLogBuilder.java | 11 +-
log4j-slf4j20-impl/pom.xml | 3 +-
.../apache/logging/slf4j/Log4jEventBuilder.java | 151 +++++++++++++++++++++
.../java/org/apache/logging/slf4j/Log4jLogger.java | 130 ++++++++++++------
.../apache/logging/slf4j/Log4jMarkerFactory.java | 18 ++-
.../logging/slf4j/CallerInformationTest.java | 12 +-
.../logging/slf4j/Log4jEventBuilderTest.java | 67 +++++++++
8 files changed, 379 insertions(+), 47 deletions(-)
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/BridgeAware.java b/log4j-api/src/main/java/org/apache/logging/log4j/BridgeAware.java
new file mode 100644
index 0000000000..fc3b8fd929
--- /dev/null
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/BridgeAware.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.log4j;
+
+/**
+ * Extended interface to allow bridges between logging systems to convey the
+ * correct location information.
+ *
+ */
+public interface BridgeAware {
+
+ /**
+ * Fully qualified class name of the entry point to the logging system. This
+ * class will not appear in the location information.
+ *
+ * @param fqcn
+ * @return this
+ */
+ public void setEntryPoint(final String fqcn);
+}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/internal/DefaultLogBuilder.java b/log4j-api/src/main/java/org/apache/logging/log4j/internal/DefaultLogBuilder.java
index 5f672612c3..75915c52ee 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/internal/DefaultLogBuilder.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/internal/DefaultLogBuilder.java
@@ -16,6 +16,7 @@
*/
package org.apache.logging.log4j.internal;
+import org.apache.logging.log4j.BridgeAware;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogBuilder;
import org.apache.logging.log4j.Logger;
@@ -32,7 +33,7 @@ import org.apache.logging.log4j.util.Supplier;
/**
* Collects data for a log event and then logs it. This class should be considered private.
*/
-public class DefaultLogBuilder implements LogBuilder {
+public class DefaultLogBuilder implements BridgeAware, LogBuilder {
private static final String FQCN = DefaultLogBuilder.class.getName();
private static final Logger LOGGER = StatusLogger.getLogger();
@@ -45,6 +46,7 @@ public class DefaultLogBuilder implements LogBuilder {
private StackTraceElement location;
private volatile boolean inUse;
private final long threadId;
+ private String fqcn = FQCN;
public DefaultLogBuilder(final Logger logger, final Level level) {
this.logger = logger;
@@ -59,6 +61,11 @@ public class DefaultLogBuilder implements LogBuilder {
this.threadId = Thread.currentThread().getId();
}
+ @Override
+ public void setEntryPoint(String fqcn) {
+ this.fqcn = fqcn;
+ }
+
/**
* This method should be considered internal. It is used to reset the LogBuilder for a new log message.
* @param level The logging level for this event.
@@ -228,7 +235,7 @@ public class DefaultLogBuilder implements LogBuilder {
private void logMessage(final Message message) {
try {
- logger.logMessage(level, marker, FQCN, location, message, throwable);
+ logger.logMessage(level, marker, fqcn, location, message, throwable);
} finally {
inUse = false;
}
diff --git a/log4j-slf4j20-impl/pom.xml b/log4j-slf4j20-impl/pom.xml
index d52ee1b592..7777a9c991 100644
--- a/log4j-slf4j20-impl/pom.xml
+++ b/log4j-slf4j20-impl/pom.xml
@@ -53,7 +53,7 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
- <scope>runtime</scope>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
@@ -131,6 +131,7 @@
<includes>
<include>**/OverflowTest.java</include>
</includes>
+ <includeJUnit5Engines>junit-vintage</includeJUnit5Engines>
</configuration>
</execution>
<execution>
diff --git a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jEventBuilder.java b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jEventBuilder.java
new file mode 100644
index 0000000000..2d50d10747
--- /dev/null
+++ b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jEventBuilder.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.slf4j;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.logging.log4j.BridgeAware;
+import org.apache.logging.log4j.CloseableThreadContext;
+import org.apache.logging.log4j.CloseableThreadContext.Instance;
+import org.apache.logging.log4j.LogBuilder;
+import org.slf4j.Marker;
+import org.slf4j.spi.LoggingEventBuilder;
+
+public class Log4jEventBuilder implements LoggingEventBuilder {
+
+ private static final String FQCN = Log4jEventBuilder.class.getName();
+
+ private final Log4jMarkerFactory markerFactory;
+ private final LogBuilder logBuilder;
+ private final List<Object> arguments = new ArrayList<>();
+ private String message = null;
+ private Map<String, String> keyValuePairs = null;
+
+ public Log4jEventBuilder(final Log4jMarkerFactory markerFactory, final LogBuilder logBuilder) {
+ this.markerFactory = markerFactory;
+ this.logBuilder = logBuilder;
+ if (logBuilder instanceof BridgeAware) {
+ ((BridgeAware) logBuilder).setEntryPoint(FQCN);
+ }
+ }
+
+ @Override
+ public LoggingEventBuilder setCause(Throwable cause) {
+ logBuilder.withThrowable(cause);
+ return this;
+ }
+
+ @Override
+ public LoggingEventBuilder addMarker(Marker marker) {
+ logBuilder.withMarker(markerFactory.getLog4jMarker(marker));
+ return this;
+ }
+
+ @Override
+ public LoggingEventBuilder addArgument(Object p) {
+ arguments.add(p);
+ return this;
+ }
+
+ @Override
+ public LoggingEventBuilder addArgument(Supplier<?> objectSupplier) {
+ arguments.add(objectSupplier.get());
+ return this;
+ }
+
+ @Override
+ public LoggingEventBuilder addKeyValue(String key, Object value) {
+ if (keyValuePairs == null) {
+ keyValuePairs = new HashMap<>();
+ }
+ keyValuePairs.put(key, String.valueOf(value));
+ return this;
+ }
+
+ @Override
+ public LoggingEventBuilder addKeyValue(String key, Supplier<Object> valueSupplier) {
+ if (keyValuePairs == null) {
+ keyValuePairs = new HashMap<>();
+ }
+ keyValuePairs.put(key, String.valueOf(valueSupplier.get()));
+ return this;
+ }
+
+ @Override
+ public LoggingEventBuilder setMessage(String message) {
+ this.message = message;
+ return this;
+ }
+
+ @Override
+ public LoggingEventBuilder setMessage(Supplier<String> messageSupplier) {
+ this.message = messageSupplier.get();
+ return this;
+ }
+
+ @Override
+ public void log() {
+ if (keyValuePairs == null || keyValuePairs.isEmpty()) {
+ logBuilder.log(message, arguments.toArray());
+ } else {
+ try (Instance c = CloseableThreadContext.putAll(keyValuePairs)) {
+ logBuilder.log(message, arguments.toArray());
+ }
+ }
+ }
+
+ @Override
+ public void log(String message) {
+ setMessage(message);
+ log();
+ }
+
+ @Override
+ public void log(String message, Object arg) {
+ setMessage(message);
+ addArgument(arg);
+ log();
+ }
+
+ @Override
+ public void log(String message, Object arg0, Object arg1) {
+ setMessage(message);
+ addArgument(arg0);
+ addArgument(arg1);
+ log();
+ }
+
+ @Override
+ public void log(String message, Object... args) {
+ setMessage(message);
+ for (final Object arg : args) {
+ addArgument(arg);
+ }
+ log();
+ }
+
+ @Override
+ public void log(Supplier<String> messageSupplier) {
+ setMessage(messageSupplier);
+ log();
+ }
+
+}
diff --git a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jLogger.java b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jLogger.java
index fd42f361fc..2b601be0ee 100644
--- a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jLogger.java
+++ b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jLogger.java
@@ -29,6 +29,8 @@ import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.spi.ExtendedLogger;
import org.slf4j.Marker;
import org.slf4j.spi.LocationAwareLogger;
+import org.slf4j.spi.LoggingEventBuilder;
+import org.slf4j.spi.NOPLoggingEventBuilder;
/**
* SLF4J logger implementation that uses Log4j.
@@ -80,32 +82,32 @@ public class Log4jLogger implements LocationAwareLogger, Serializable {
@Override
public boolean isTraceEnabled(final Marker marker) {
- return logger.isEnabled(Level.TRACE, getMarker(marker), null);
+ return logger.isEnabled(Level.TRACE, markerFactory.getLog4jMarker(marker), null);
}
@Override
public void trace(final Marker marker, final String s) {
- logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s);
+ logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s);
}
@Override
public void trace(final Marker marker, final String s, final Object o) {
- logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o);
+ logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s, o);
}
@Override
public void trace(final Marker marker, final String s, final Object o, final Object o1) {
- logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o, o1);
+ logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s, o, o1);
}
@Override
public void trace(final Marker marker, final String s, final Object... objects) {
- logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, objects);
+ logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s, objects);
}
@Override
public void trace(final Marker marker, final String s, final Throwable throwable) {
- logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, throwable);
+ logger.logIfEnabled(FQCN, Level.TRACE, markerFactory.getLog4jMarker(marker), s, throwable);
}
@Override
@@ -140,32 +142,32 @@ public class Log4jLogger implements LocationAwareLogger, Serializable {
@Override
public boolean isDebugEnabled(final Marker marker) {
- return logger.isEnabled(Level.DEBUG, getMarker(marker), null);
+ return logger.isEnabled(Level.DEBUG, markerFactory.getLog4jMarker(marker), null);
}
@Override
public void debug(final Marker marker, final String s) {
- logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s);
+ logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s);
}
@Override
public void debug(final Marker marker, final String s, final Object o) {
- logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o);
+ logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s, o);
}
@Override
public void debug(final Marker marker, final String s, final Object o, final Object o1) {
- logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o, o1);
+ logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s, o, o1);
}
@Override
public void debug(final Marker marker, final String s, final Object... objects) {
- logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, objects);
+ logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s, objects);
}
@Override
public void debug(final Marker marker, final String s, final Throwable throwable) {
- logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, throwable);
+ logger.logIfEnabled(FQCN, Level.DEBUG, markerFactory.getLog4jMarker(marker), s, throwable);
}
@Override
@@ -200,32 +202,32 @@ public class Log4jLogger implements LocationAwareLogger, Serializable {
@Override
public boolean isInfoEnabled(final Marker marker) {
- return logger.isEnabled(Level.INFO, getMarker(marker), null);
+ return logger.isEnabled(Level.INFO, markerFactory.getLog4jMarker(marker), null);
}
@Override
public void info(final Marker marker, final String s) {
- logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s);
+ logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s);
}
@Override
public void info(final Marker marker, final String s, final Object o) {
- logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o);
+ logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s, o);
}
@Override
public void info(final Marker marker, final String s, final Object o, final Object o1) {
- logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o, o1);
+ logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s, o, o1);
}
@Override
public void info(final Marker marker, final String s, final Object... objects) {
- logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, objects);
+ logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s, objects);
}
@Override
public void info(final Marker marker, final String s, final Throwable throwable) {
- logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, throwable);
+ logger.logIfEnabled(FQCN, Level.INFO, markerFactory.getLog4jMarker(marker), s, throwable);
}
@Override
@@ -260,32 +262,32 @@ public class Log4jLogger implements LocationAwareLogger, Serializable {
@Override
public boolean isWarnEnabled(final Marker marker) {
- return logger.isEnabled(Level.WARN, getMarker(marker), null);
+ return logger.isEnabled(Level.WARN, markerFactory.getLog4jMarker(marker), null);
}
@Override
public void warn(final Marker marker, final String s) {
- logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s);
+ logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s);
}
@Override
public void warn(final Marker marker, final String s, final Object o) {
- logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o);
+ logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s, o);
}
@Override
public void warn(final Marker marker, final String s, final Object o, final Object o1) {
- logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o, o1);
+ logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s, o, o1);
}
@Override
public void warn(final Marker marker, final String s, final Object... objects) {
- logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, objects);
+ logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s, objects);
}
@Override
public void warn(final Marker marker, final String s, final Throwable throwable) {
- logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, throwable);
+ logger.logIfEnabled(FQCN, Level.WARN, markerFactory.getLog4jMarker(marker), s, throwable);
}
@Override
@@ -320,38 +322,38 @@ public class Log4jLogger implements LocationAwareLogger, Serializable {
@Override
public boolean isErrorEnabled(final Marker marker) {
- return logger.isEnabled(Level.ERROR, getMarker(marker), null);
+ return logger.isEnabled(Level.ERROR, markerFactory.getLog4jMarker(marker), null);
}
@Override
public void error(final Marker marker, final String s) {
- logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s);
+ logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s);
}
@Override
public void error(final Marker marker, final String s, final Object o) {
- logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o);
+ logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s, o);
}
@Override
public void error(final Marker marker, final String s, final Object o, final Object o1) {
- logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o, o1);
+ logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s, o, o1);
}
@Override
public void error(final Marker marker, final String s, final Object... objects) {
- logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, objects);
+ logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s, objects);
}
@Override
public void error(final Marker marker, final String s, final Throwable throwable) {
- logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, throwable);
+ logger.logIfEnabled(FQCN, Level.ERROR, markerFactory.getLog4jMarker(marker), s, throwable);
}
@Override
public void log(final Marker marker, final String fqcn, final int level, final String message, final Object[] params, final Throwable throwable) {
final Level log4jLevel = getLevel(level);
- final org.apache.logging.log4j.Marker log4jMarker = getMarker(marker);
+ final org.apache.logging.log4j.Marker log4jMarker = markerFactory.getLog4jMarker(marker);
if (!logger.isEnabled(log4jLevel, log4jMarker, message, params)) {
return;
@@ -368,16 +370,6 @@ public class Log4jLogger implements LocationAwareLogger, Serializable {
logger.logMessage(fqcn, log4jLevel, log4jMarker, msg, actualThrowable);
}
- private org.apache.logging.log4j.Marker getMarker(final Marker marker) {
- if (marker == null) {
- return null;
- } else if (marker instanceof Log4jMarker) {
- return ((Log4jMarker) marker).getLog4jMarker();
- } else {
- return ((Log4jMarker) markerFactory.getMarker(marker)).getLog4jMarker();
- }
- }
-
@Override
public String getName() {
return name;
@@ -417,4 +409,60 @@ public class Log4jLogger implements LocationAwareLogger, Serializable {
}
return Level.ERROR;
}
+
+ @Override
+ public LoggingEventBuilder makeLoggingEventBuilder(org.slf4j.event.Level level) {
+ final Level log4jLevel = getLevel(level.toInt());
+ if (logger.isEnabled(log4jLevel)) {
+ return new Log4jEventBuilder(markerFactory, logger.atLevel(log4jLevel));
+ }
+ return NOPLoggingEventBuilder.singleton();
+ }
+
+ @Override
+ public LoggingEventBuilder atTrace() {
+ if (logger.isTraceEnabled()) {
+ return new Log4jEventBuilder(markerFactory, logger.atTrace());
+ }
+ return NOPLoggingEventBuilder.singleton();
+ }
+
+ @Override
+ public LoggingEventBuilder atDebug() {
+ if (logger.isDebugEnabled()) {
+ return new Log4jEventBuilder(markerFactory, logger.atDebug());
+ }
+ return NOPLoggingEventBuilder.singleton();
+ }
+
+ @Override
+ public LoggingEventBuilder atInfo() {
+ if (logger.isInfoEnabled()) {
+ return new Log4jEventBuilder(markerFactory, logger.atInfo());
+ }
+ return NOPLoggingEventBuilder.singleton();
+ }
+
+ @Override
+ public LoggingEventBuilder atWarn() {
+ if (logger.isWarnEnabled()) {
+ return new Log4jEventBuilder(markerFactory, logger.atWarn());
+ }
+ return NOPLoggingEventBuilder.singleton();
+ }
+
+ @Override
+ public LoggingEventBuilder atError() {
+ if (logger.isErrorEnabled()) {
+ return new Log4jEventBuilder(markerFactory, logger.atError());
+ }
+ return NOPLoggingEventBuilder.singleton();
+ }
+
+ @Override
+ public boolean isEnabledForLevel(org.slf4j.event.Level level) {
+ return logger.isEnabled(getLevel(level.toInt()));
+ }
+
+
}
diff --git a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMarkerFactory.java b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMarkerFactory.java
index 69ea94b33c..9073fa9242 100644
--- a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMarkerFactory.java
+++ b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMarkerFactory.java
@@ -78,7 +78,23 @@ public class Log4jMarkerFactory implements IMarkerFactory {
return addMarkerIfAbsent(marker.getName(), convertMarker(marker));
}
- private static org.apache.logging.log4j.Marker convertMarker(final Marker original) {
+ /**
+ * Gets the Log4j2 marker associated to this SLF4J marker or creates a new one.
+ *
+ * @param marker a SLF4J marker
+ * @return a Log4j2 marker
+ */
+ org.apache.logging.log4j.Marker getLog4jMarker(final Marker marker) {
+ if (marker == null) {
+ return null;
+ } else if (marker instanceof Log4jMarker) {
+ return ((Log4jMarker) marker).getLog4jMarker();
+ } else {
+ return ((Log4jMarker) getMarker(marker)).getLog4jMarker();
+ }
+ }
+
+ static org.apache.logging.log4j.Marker convertMarker(final Marker original) {
if (original == null) {
throw new IllegalArgumentException("Marker must not be null");
}
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
index 7efc0e5090..ea399b2b1a 100644
--- a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
@@ -42,8 +42,11 @@ public class CallerInformationTest {
logger.info("Ignored message contents.");
logger.warn("Verifying the caller class is still correct.");
logger.error("Hopefully nobody breaks me!");
+ logger.atInfo().log("Ignored message contents.");
+ logger.atWarn().log("Verifying the caller class is still correct.");
+ logger.atError().log("Hopefully nobody breaks me!");
final List<String> messages = app.getMessages();
- assertEquals("Incorrect number of messages.", 3, messages.size());
+ assertEquals("Incorrect number of messages.", 6, messages.size());
for (final String message : messages) {
assertEquals("Incorrect caller class name.", this.getClass().getName(), message);
}
@@ -58,8 +61,13 @@ public class CallerInformationTest {
logger.error("ZOMBIES!!!");
logger.warn("brains~~~");
logger.info("Itchy. Tasty.");
+ logger.atInfo().log("More messages.");
+ logger.atWarn().log("CATASTROPHE INCOMING!");
+ logger.atError().log("ZOMBIES!!!");
+ logger.atWarn().log("brains~~~");
+ logger.atInfo().log("Itchy. Tasty.");
final List<String> messages = app.getMessages();
- assertEquals("Incorrect number of messages.", 5, messages.size());
+ assertEquals("Incorrect number of messages.", 10, messages.size());
for (final String message : messages) {
assertEquals("Incorrect caller method name.", "testMethodLogger", message);
}
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/Log4jEventBuilderTest.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/Log4jEventBuilderTest.java
new file mode 100644
index 0000000000..64a9696155
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/Log4jEventBuilderTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.logging.slf4j;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
+
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.test.appender.ListAppender;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+// Config from `log4j-core` test jar.
+@LoggerContextSource("log4j2-config.xml")
+public class Log4jEventBuilderTest {
+
+ private final Logger logger;
+ private final ListAppender appender;
+
+ public Log4jEventBuilderTest(@Named("List") Appender appender) {
+ logger = LoggerFactory.getLogger("org.apache.test.Log4jEventBuilderTest");
+ this.appender = (ListAppender) appender;
+ }
+
+ @BeforeEach
+ public void setUp() {
+ appender.clear();
+ }
+
+ @Test
+ public void testKeyValuePairs() {
+ logger.atDebug().addKeyValue("testKeyValuePairs", "ok").log();
+ final List<LogEvent> events = appender.getEvents();
+ assertThat(events).hasSize(1);
+ assertThat(events.get(0).getContextMap()).containsEntry("testKeyValuePairs", "ok");
+ }
+
+ @Test
+ public void testArguments() {
+ logger.atDebug().setMessage("{}-{}").addArgument("a").addArgument("b").log();
+ logger.atDebug().log("{}-{}", "a", "b");
+ logger.atDebug().addArgument("a").log("{}-{}", "b");
+ logger.atDebug().log("{}-{}", new Object[] {"a", "b"});
+ assertThat(appender.getEvents()).hasSize(4)
+ .allMatch(event -> "a-b".equals(event.getMessage().getFormattedMessage()));
+ }
+}