You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2019/06/29 04:39:04 UTC
[logging-log4j2] 01/04: LOG4J2-2639 - Allow logging calls to be
constructed using a builder pattern
This is an automated email from the ASF dual-hosted git repository.
rgoers pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 3bd605d2c4eb24657396d4fe4cee78edc3d2c1b6
Author: Ralph Goers <rg...@apache.org>
AuthorDate: Sat Jun 22 08:35:23 2019 -0700
LOG4J2-2639 - Allow logging calls to be constructed using a builder pattern
---
.../main/java/org/apache/logging/log4j/Logger.java | 86 +++++++++-
.../logging/log4j/internal/DefaultLogBuilder.java | 133 +++++++++++++++
.../apache/logging/log4j/internal/LogBuilder.java | 51 ++++--
.../log4j/message/AbstractMessageFactory.java | 124 +-------------
.../log4j/message/FormattedMessageFactory.java | 9 +-
.../log4j/message/LocalizedMessageFactory.java | 8 +-
.../logging/log4j/message/MessageFactory.java | 186 ++++++++++++++++++++-
.../logging/log4j/message/MessageFactory2.java | 156 +----------------
.../log4j/message/MessageFormatMessageFactory.java | 9 +-
.../log4j/message/ParameterizedMessageFactory.java | 9 +-
.../ParameterizedNoReferenceMessageFactory.java | 9 +-
.../log4j/message/ReusableMessageFactory.java | 2 +-
.../log4j/message/SimpleMessageFactory.java | 9 +-
.../message/StringFormatterMessageFactory.java | 9 +-
.../apache/logging/log4j/spi/AbstractLogger.java | 144 ++++++++++++++--
.../logging/log4j/spi/MessageFactory2Adapter.java | 118 -------------
.../apache/logging/log4j/AbstractLoggerTest.java | 5 +-
.../java/org/apache/logging/log4j/LoggerTest.java | 20 ++-
.../java/org/apache/logging/log4j/TestLogger.java | 15 +-
.../java/org/apache/logging/log4j/core/Logger.java | 7 +
.../config/AwaitCompletionReliabilityStrategy.java | 19 +++
.../AwaitUnconditionallyReliabilityStrategy.java | 14 ++
.../core/config/DefaultReliabilityStrategy.java | 14 ++
.../core/config/LockingReliabilityStrategy.java | 19 +++
.../logging/log4j/core/config/LoggerConfig.java | 46 +++++
.../log4j/core/config/ReliabilityStrategy.java | 16 ++
.../log4j/core/impl/DefaultLogEventFactory.java | 19 +++
.../logging/log4j/core/impl/Log4jLogEvent.java | 24 +++
.../logging/log4j/core/impl/LogEventFactory.java | 5 +
.../org/apache/logging/log4j/core/LoggerTest.java | 41 +++--
.../logging/log4j/taglib/SetLoggerTagTest.java | 16 +-
.../java/org/apache/logging/slf4j/LoggerTest.java | 14 +-
32 files changed, 853 insertions(+), 503 deletions(-)
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/Logger.java b/log4j-api/src/main/java/org/apache/logging/log4j/Logger.java
index 9bedc23..6927c42 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/Logger.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/Logger.java
@@ -16,13 +16,16 @@
*/
package org.apache.logging.log4j;
+import org.apache.logging.log4j.internal.DefaultLogBuilder;
+import org.apache.logging.log4j.internal.LogBuilder;
import org.apache.logging.log4j.message.EntryMessage;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.message.MessageFactory2;
import org.apache.logging.log4j.util.MessageSupplier;
import org.apache.logging.log4j.util.Supplier;
+import java.util.List;
+
/**
* This is the central interface in the log4j package. Most logging operations, except configuration, are done through
* this interface.
@@ -1682,13 +1685,7 @@ public interface Logger {
/**
* Gets the message factory used to convert message Objects and Strings/CharSequences into actual log Messages.
*
- * Since version 2.6, Log4j internally uses message factories that implement the {@link MessageFactory2} interface.
- * From version 2.6.2, the return type of this method was changed from {@link MessageFactory} to
- * {@code <MF extends MessageFactory> MF}. The returned factory will always implement {@link MessageFactory2},
- * but the return type of this method could not be changed to {@link MessageFactory2} without breaking binary
- * compatibility.
- *
- * @return the message factory, as an instance of {@link MessageFactory2}
+ * @return the message factory, as an instance of {@link MessageFactory}
*/
<MF extends MessageFactory> MF getMessageFactory();
@@ -4199,4 +4196,77 @@ public interface Logger {
void warn(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7,
Object p8, Object p9);
+ /**
+ * Logs a Message.
+ * @param level The logging Level to check.
+ * @param marker A Marker or null.
+ * @param fqcn The fully qualified class name of the logger entry point, used to determine the caller class and
+ * method when location information needs to be logged.
+ * @param location The location of the caller.
+ * @param message The message format.
+ * @param throwable the exception to log, including its stack trace.
+ * @since 3.0
+ */
+ default void logMessage(Level level, Marker marker, String fqcn, StackTraceElement location, Message message,
+ Throwable throwable) {
+
+ }
+
+ /**
+ * Constuct a trace log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ default LogBuilder atTrace() {
+ return LogBuilder.INSTANCE;
+ }
+ /**
+ * Constuct a trace log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ default LogBuilder atDebug() {
+ return LogBuilder.INSTANCE;
+ }
+ /**
+ * Constuct a trace log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ default LogBuilder atInfo() {
+ return LogBuilder.INSTANCE;
+ }
+ /**
+ * Constuct a trace log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ default LogBuilder atWarn() {
+ return LogBuilder.INSTANCE;
+ }
+ /**
+ * Constuct a trace log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ default LogBuilder atError() {
+ return LogBuilder.INSTANCE;
+ }
+ /**
+ * Constuct a trace log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ default LogBuilder atFatal() {
+ return LogBuilder.INSTANCE;
+ }
+ /**
+ * Constuct a log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ default LogBuilder atLevel(Level level) {
+ return LogBuilder.INSTANCE;
+ }
+
}
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
new file mode 100644
index 0000000..cd80b84
--- /dev/null
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/internal/DefaultLogBuilder.java
@@ -0,0 +1,133 @@
+/*
+ * 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.internal;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.apache.logging.log4j.util.StackLocatorUtil;
+import org.apache.logging.log4j.util.Supplier;
+
+
+/**
+ * Collects data for a log event and then logs it.
+ */
+public class DefaultLogBuilder implements LogBuilder {
+ private static Message EMPTY_MESSAGE = new SimpleMessage("");
+ private static final String FQCN = DefaultLogBuilder.class.getName();
+
+ private final Logger logger;
+ private Level level;
+ private Marker marker;
+ private Throwable throwable;
+ private StackTraceElement location;
+ private Object object;
+ private Message msg;
+ private String textMessage;
+ private Supplier<Message> supplier;
+ private Object[] parameters;
+
+ public DefaultLogBuilder(Logger logger) {
+ this.logger = logger;
+ }
+
+ public LogBuilder setLevel(Level level) {
+ this.level = level;
+ this.marker = null;
+ this.throwable = null;
+ this.location = null;
+ this.object = null;
+ this.msg = null;
+ this.textMessage = null;
+ this.supplier = null;
+ this.parameters = null;
+ return this;
+ }
+
+ public LogBuilder withMarker(Marker marker) {
+ this.marker = marker;
+ return this;
+ }
+
+ public LogBuilder withThrowable(Throwable throwable) {
+ this.throwable = throwable;
+ return this;
+ }
+
+ public LogBuilder withLocation() {
+ location = StackLocatorUtil.getStackTraceElement(2);
+ return this;
+ }
+
+ public LogBuilder withLocation(StackTraceElement location) {
+ this.location = location;
+ return this;
+ }
+
+ public LogBuilder withMessage(String msg) {
+ this.textMessage = msg;
+ return this;
+ }
+
+ public LogBuilder withMessage(Object msg) {
+ this.object = msg;
+ return this;
+ }
+
+ public LogBuilder withMessage(Message msg) {
+ this.msg = msg;
+ return this;
+ }
+
+ public LogBuilder withMessage(Supplier<Message> supplier) {
+ this.supplier = supplier;
+ return this;
+ }
+
+ public LogBuilder withParameters(Object... params) {
+ if (params != null && params.length > 0) {
+ if (parameters == null) {
+ parameters = params;
+ } else {
+ Object[] prev = parameters;
+ int count = parameters.length + params.length;
+ parameters = new Object[count];
+ System.arraycopy(prev, 0, parameters, 0, prev.length);
+ System.arraycopy(params, 0, parameters, prev.length, params.length);
+ }
+ }
+ return this;
+ }
+
+ public void log() {
+ Message message;
+ if (msg != null) {
+ message = msg;
+ } else if (supplier != null) {
+ message = supplier.get();
+ } else if (object != null) {
+ message = logger.getMessageFactory().newMessage(object);
+ } else if (textMessage != null) {
+ message = logger.getMessageFactory().newMessage(textMessage, parameters);
+ } else {
+ message = EMPTY_MESSAGE;
+ }
+ logger.logMessage(level, marker, FQCN, location, message, throwable);
+ }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/LogEventFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/internal/LogBuilder.java
similarity index 51%
copy from log4j-core/src/main/java/org/apache/logging/log4j/core/impl/LogEventFactory.java
copy to log4j-api/src/main/java/org/apache/logging/log4j/internal/LogBuilder.java
index ad9128c..8075412 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/LogEventFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/internal/LogBuilder.java
@@ -14,22 +14,51 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
+package org.apache.logging.log4j.internal;
-package org.apache.logging.log4j.core.impl;
-
-import java.util.List;
-
-import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.message.Message;
/**
- *
+ * Class Description goes here.
*/
-public interface LogEventFactory {
+public interface LogBuilder {
+
+ public static final LogBuilder INSTANCE = new LogBuilder() {};
+
+ default LogBuilder withMarker(Marker marker) {
+ return this;
+ }
+
+ default LogBuilder withThrowable(Throwable throwable) {
+ return this;
+ }
+
+ default LogBuilder withLocation() {
+ return this;
+ }
+
+ default LogBuilder withLocation(StackTraceElement location) {
+ return this;
+ }
+
+ default LogBuilder withMessage(Message msg) {
+ return this;
+ }
+
+ default LogBuilder withMessage(String msg) {
+ return this;
+ }
+
+ default LogBuilder withMessage(Object msg) {
+ return this;
+ }
+
+
+ default LogBuilder withParameters(Object... params) {
+ return this;
+ }
- LogEvent createEvent(String loggerName, Marker marker, String fqcn, Level level, Message data,
- List<Property> properties, Throwable t);
+ default void log() {
+ }
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/AbstractMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/AbstractMessageFactory.java
index 6429ed7..cc4f328 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/AbstractMessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/AbstractMessageFactory.java
@@ -19,128 +19,12 @@ package org.apache.logging.log4j.message;
import java.io.Serializable;
/**
- * Provides an abstract superclass for {@link MessageFactory2} implementations with default implementations (and for
- * {@link MessageFactory} by extension).
- * <p>
- * This class is immutable.
- * </p>
- * <h4>Note to implementors</h4>
- * <p>
- * Subclasses can implement the {@link MessageFactory2} methods when they can most effectively build {@link Message}
- * instances. If a subclass does not implement {@link MessageFactory2} methods, these calls are routed through
- * {@link #newMessage(String, Object...)} in this class.
+ * Provides an abstract superclass for {@link MessageFactory}. This class is now unnecessary as all default
+ * methods are provided by the (@link MessageFactory) interface.
* </p>
+ * @deprecated MessageFactory has default methods that implement all the methods that were here.
*/
-public abstract class AbstractMessageFactory implements MessageFactory2, Serializable {
+public abstract class AbstractMessageFactory implements MessageFactory, Serializable {
private static final long serialVersionUID = -1307891137684031187L;
- @Override
- public Message newMessage(final CharSequence message) {
- return new SimpleMessage(message);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.logging.log4j.message.MessageFactory#newMessage(java.lang.Object)
- */
- @Override
- public Message newMessage(final Object message) {
- return new ObjectMessage(message);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.logging.log4j.message.MessageFactory#newMessage(java.lang.String)
- */
- @Override
- public Message newMessage(final String message) {
- return new SimpleMessage(message);
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0) {
- return newMessage(message, new Object[] { p0 });
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1) {
- return newMessage(message, new Object[] { p0, p1 });
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2) {
- return newMessage(message, new Object[] { p0, p1, p2 });
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3) {
- return newMessage(message, new Object[] { p0, p1, p2, p3 });
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4) {
- return newMessage(message, new Object[] { p0, p1, p2, p3, p4 });
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5) {
- return newMessage(message, new Object[] { p0, p1, p2, p3, p4, p5 });
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5,
- final Object p6) {
- return newMessage(message, new Object[] { p0, p1, p2, p3, p4, p5, p6 });
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5,
- final Object p6, final Object p7) {
- return newMessage(message, new Object[] { p0, p1, p2, p3, p4, p5, p6, p7 });
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5,
- final Object p6, final Object p7, final Object p8) {
- return newMessage(message, new Object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8 });
- }
-
- /**
- * @since 2.6.1
- */
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5,
- final Object p6, final Object p7, final Object p8, final Object p9) {
- return newMessage(message, new Object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9 });
- }
-
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/FormattedMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/FormattedMessageFactory.java
index 805e24b..cf6ed3a 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/FormattedMessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/FormattedMessageFactory.java
@@ -16,16 +16,17 @@
*/
package org.apache.logging.log4j.message;
+import java.io.Serializable;
+
/**
- * Creates {@link FormattedMessage} instances for {@link MessageFactory2} methods (and {@link MessageFactory} by
- * extension.)
+ * Creates {@link FormattedMessage} instances for {@link MessageFactory} methods.
*
* <h4>Note to implementors</h4>
* <p>
- * This class implements all {@link MessageFactory2} methods.
+ * This class implements all {@link MessageFactory} methods.
* </p>
*/
-public class FormattedMessageFactory extends AbstractMessageFactory {
+public class FormattedMessageFactory implements MessageFactory, Serializable {
private static final long serialVersionUID = 1L;
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/LocalizedMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/LocalizedMessageFactory.java
index b7e9803..d92878d 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/LocalizedMessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/LocalizedMessageFactory.java
@@ -16,19 +16,19 @@
*/
package org.apache.logging.log4j.message;
+import java.io.Serializable;
import java.util.ResourceBundle;
/**
- * Creates {@link FormattedMessage} instances for {@link MessageFactory2} methods (and {@link MessageFactory} by
- * extension.)
+ * Creates {@link FormattedMessage} instances for {@link MessageFactory} methods.
*
* <h4>Note to implementors</h4>
* <p>
- * This class does <em>not</em> implement any {@link MessageFactory2} methods and lets the superclass funnel those calls
+ * This class does <em>not</em> implement any {@link MessageFactory} methods and lets the superclass funnel those calls
* through {@link #newMessage(String, Object...)}.
* </p>
*/
-public class LocalizedMessageFactory extends AbstractMessageFactory {
+public class LocalizedMessageFactory implements MessageFactory, Serializable {
private static final long serialVersionUID = -1996295808703146741L;
// FIXME: cannot use ResourceBundle name for serialization until Java 8
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory.java
index 009d5a6..fa7c672 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory.java
@@ -31,7 +31,9 @@ public interface MessageFactory {
* a message object
* @return a new message
*/
- Message newMessage(Object message);
+ default Message newMessage(Object message) {
+ return new ObjectMessage(message);
+ }
/**
* Creates a new message based on a String.
@@ -40,7 +42,9 @@ public interface MessageFactory {
* a message String
* @return a new message
*/
- Message newMessage(String message);
+ default Message newMessage(String message) {
+ return new SimpleMessage(message);
+ }
/**
* Creates a new parameterized message.
@@ -54,4 +58,182 @@ public interface MessageFactory {
* @see StringFormatterMessageFactory
*/
Message newMessage(String message, Object... params);
+
+ /**
+ * Creates a new message for the specified CharSequence.
+ * @param charSequence the (potentially mutable) CharSequence
+ * @return a new message for the specified CharSequence
+ */
+ default Message newMessage(CharSequence charSequence) {
+ return new SimpleMessage(charSequence);
+ }
+
+ /**
+ * Creates a new parameterized message.
+ *
+ * @param message a message template, the kind of message template depends on the implementation.
+ * @param p0 a message parameter
+ * @return a new message
+ * @see ParameterizedMessageFactory
+ */
+ default Message newMessage(String message, Object p0) {
+ return newMessage(message, new Object[] { p0 });
+ }
+
+ /**
+ * Creates a new parameterized message.
+ *
+ * @param message a message template, the kind of message template depends on the implementation.
+ * @param p0 a message parameter
+ * @param p1 a message parameter
+ * @return a new message
+ * @see ParameterizedMessageFactory
+ */
+ default Message newMessage(String message, Object p0, Object p1) {
+ return newMessage(message, new Object[] { p0, p1 });
+ }
+
+ /**
+ * Creates a new parameterized message.
+ *
+ * @param message a message template, the kind of message template depends on the implementation.
+ * @param p0 a message parameter
+ * @param p1 a message parameter
+ * @param p2 a message parameter
+ * @return a new message
+ * @see ParameterizedMessageFactory
+ */
+ default Message newMessage(String message, Object p0, Object p1, Object p2) {
+ return newMessage(message, new Object[] { p0, p1, p2 });
+ }
+
+ /**
+ * Creates a new parameterized message.
+ *
+ * @param message a message template, the kind of message template depends on the implementation.
+ * @param p0 a message parameter
+ * @param p1 a message parameter
+ * @param p2 a message parameter
+ * @param p3 a message parameter
+ * @return a new message
+ * @see ParameterizedMessageFactory
+ */
+ default Message newMessage(String message, Object p0, Object p1, Object p2, Object p3) {
+ return newMessage(message, new Object[] { p0, p1, p2, p3 });
+ }
+
+ /**
+ * Creates a new parameterized message.
+ *
+ * @param message a message template, the kind of message template depends on the implementation.
+ * @param p0 a message parameter
+ * @param p1 a message parameter
+ * @param p2 a message parameter
+ * @param p3 a message parameter
+ * @param p4 a message parameter
+ * @return a new message
+ * @see ParameterizedMessageFactory
+ */
+ default Message newMessage(String message, Object p0, Object p1, Object p2, Object p3, Object p4) {
+ return newMessage(message, new Object[] { p0, p1, p2, p3, p4 });
+ }
+
+ /**
+ * Creates a new parameterized message.
+ *
+ * @param message a message template, the kind of message template depends on the implementation.
+ * @param p0 a message parameter
+ * @param p1 a message parameter
+ * @param p2 a message parameter
+ * @param p3 a message parameter
+ * @param p4 a message parameter
+ * @param p5 a message parameter
+ * @return a new message
+ * @see ParameterizedMessageFactory
+ */
+ default Message newMessage(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) {
+ return newMessage(message, new Object[] { p0, p1, p2, p3, p4, p5 });
+ }
+
+ /**
+ * Creates a new parameterized message.
+ *
+ * @param message a message template, the kind of message template depends on the implementation.
+ * @param p0 a message parameter
+ * @param p1 a message parameter
+ * @param p2 a message parameter
+ * @param p3 a message parameter
+ * @param p4 a message parameter
+ * @param p5 a message parameter
+ * @param p6 a message parameter
+ * @return a new message
+ * @see ParameterizedMessageFactory
+ */
+ default Message newMessage(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5,
+ Object p6) {
+ return newMessage(message, new Object[] { p0, p1, p2, p3, p4, p5, p6 });
+ }
+
+ /**
+ * Creates a new parameterized message.
+ *
+ * @param message a message template, the kind of message template depends on the implementation.
+ * @param p0 a message parameter
+ * @param p1 a message parameter
+ * @param p2 a message parameter
+ * @param p3 a message parameter
+ * @param p4 a message parameter
+ * @param p5 a message parameter
+ * @param p6 a message parameter
+ * @param p7 a message parameter
+ * @return a new message
+ * @see ParameterizedMessageFactory
+ */
+ default Message newMessage(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5,
+ Object p6, Object p7) {
+ return newMessage(message, new Object[] { p0, p1, p2, p3, p4, p5, p6, p7 });
+ }
+
+ /**
+ * Creates a new parameterized message.
+ *
+ * @param message a message template, the kind of message template depends on the implementation.
+ * @param p0 a message parameter
+ * @param p1 a message parameter
+ * @param p2 a message parameter
+ * @param p3 a message parameter
+ * @param p4 a message parameter
+ * @param p5 a message parameter
+ * @param p6 a message parameter
+ * @param p7 a message parameter
+ * @param p8 a message parameter
+ * @return a new message
+ * @see ParameterizedMessageFactory
+ */
+ default Message newMessage(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5,
+ Object p6, Object p7, Object p8) {
+ return newMessage(message, new Object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8 });
+ }
+
+ /**
+ * Creates a new parameterized message.
+ *
+ * @param message a message template, the kind of message template depends on the implementation.
+ * @param p0 a message parameter
+ * @param p1 a message parameter
+ * @param p2 a message parameter
+ * @param p3 a message parameter
+ * @param p4 a message parameter
+ * @param p5 a message parameter
+ * @param p6 a message parameter
+ * @param p7 a message parameter
+ * @param p8 a message parameter
+ * @param p9 a message parameter
+ * @return a new message
+ * @see ParameterizedMessageFactory
+ */
+ default Message newMessage(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5,
+ Object p6, Object p7, Object p8, Object p9) {
+ return newMessage(message, new Object[] { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9 });
+ }
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory2.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory2.java
index 33004dd..2e2ad70 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory2.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFactory2.java
@@ -20,162 +20,8 @@ package org.apache.logging.log4j.message;
* Creates messages. Implementations can provide different message format syntaxes.
*
* @see ParameterizedMessageFactory
+ * @deprecated MessageFactory now contains all interface methods.
* @since 2.6
*/
public interface MessageFactory2 extends MessageFactory {
-
- /**
- * Creates a new message for the specified CharSequence.
- * @param charSequence the (potentially mutable) CharSequence
- * @return a new message for the specified CharSequence
- */
- Message newMessage(CharSequence charSequence);
-
- /**
- * Creates a new parameterized message.
- *
- * @param message a message template, the kind of message template depends on the implementation.
- * @param p0 a message parameter
- * @return a new message
- * @see ParameterizedMessageFactory
- */
- Message newMessage(String message, Object p0);
-
- /**
- * Creates a new parameterized message.
- *
- * @param message a message template, the kind of message template depends on the implementation.
- * @param p0 a message parameter
- * @param p1 a message parameter
- * @return a new message
- * @see ParameterizedMessageFactory
- */
- Message newMessage(String message, Object p0, Object p1);
-
- /**
- * Creates a new parameterized message.
- *
- * @param message a message template, the kind of message template depends on the implementation.
- * @param p0 a message parameter
- * @param p1 a message parameter
- * @param p2 a message parameter
- * @return a new message
- * @see ParameterizedMessageFactory
- */
- Message newMessage(String message, Object p0, Object p1, Object p2);
-
- /**
- * Creates a new parameterized message.
- *
- * @param message a message template, the kind of message template depends on the implementation.
- * @param p0 a message parameter
- * @param p1 a message parameter
- * @param p2 a message parameter
- * @param p3 a message parameter
- * @return a new message
- * @see ParameterizedMessageFactory
- */
- Message newMessage(String message, Object p0, Object p1, Object p2, Object p3);
-
- /**
- * Creates a new parameterized message.
- *
- * @param message a message template, the kind of message template depends on the implementation.
- * @param p0 a message parameter
- * @param p1 a message parameter
- * @param p2 a message parameter
- * @param p3 a message parameter
- * @param p4 a message parameter
- * @return a new message
- * @see ParameterizedMessageFactory
- */
- Message newMessage(String message, Object p0, Object p1, Object p2, Object p3, Object p4);
-
- /**
- * Creates a new parameterized message.
- *
- * @param message a message template, the kind of message template depends on the implementation.
- * @param p0 a message parameter
- * @param p1 a message parameter
- * @param p2 a message parameter
- * @param p3 a message parameter
- * @param p4 a message parameter
- * @param p5 a message parameter
- * @return a new message
- * @see ParameterizedMessageFactory
- */
- Message newMessage(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5);
-
- /**
- * Creates a new parameterized message.
- *
- * @param message a message template, the kind of message template depends on the implementation.
- * @param p0 a message parameter
- * @param p1 a message parameter
- * @param p2 a message parameter
- * @param p3 a message parameter
- * @param p4 a message parameter
- * @param p5 a message parameter
- * @param p6 a message parameter
- * @return a new message
- * @see ParameterizedMessageFactory
- */
- Message newMessage(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6);
-
- /**
- * Creates a new parameterized message.
- *
- * @param message a message template, the kind of message template depends on the implementation.
- * @param p0 a message parameter
- * @param p1 a message parameter
- * @param p2 a message parameter
- * @param p3 a message parameter
- * @param p4 a message parameter
- * @param p5 a message parameter
- * @param p6 a message parameter
- * @param p7 a message parameter
- * @return a new message
- * @see ParameterizedMessageFactory
- */
- Message newMessage(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6,
- Object p7);
-
- /**
- * Creates a new parameterized message.
- *
- * @param message a message template, the kind of message template depends on the implementation.
- * @param p0 a message parameter
- * @param p1 a message parameter
- * @param p2 a message parameter
- * @param p3 a message parameter
- * @param p4 a message parameter
- * @param p5 a message parameter
- * @param p6 a message parameter
- * @param p7 a message parameter
- * @param p8 a message parameter
- * @return a new message
- * @see ParameterizedMessageFactory
- */
- Message newMessage(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6,
- Object p7, Object p8);
-
- /**
- * Creates a new parameterized message.
- *
- * @param message a message template, the kind of message template depends on the implementation.
- * @param p0 a message parameter
- * @param p1 a message parameter
- * @param p2 a message parameter
- * @param p3 a message parameter
- * @param p4 a message parameter
- * @param p5 a message parameter
- * @param p6 a message parameter
- * @param p7 a message parameter
- * @param p8 a message parameter
- * @param p9 a message parameter
- * @return a new message
- * @see ParameterizedMessageFactory
- */
- Message newMessage(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6,
- Object p7, Object p8, Object p9);
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFormatMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFormatMessageFactory.java
index f75e68b..bab3c89 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFormatMessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/MessageFormatMessageFactory.java
@@ -16,16 +16,17 @@
*/
package org.apache.logging.log4j.message;
+import java.io.Serializable;
+
/**
- * Creates {@link FormattedMessage} instances for {@link MessageFactory2} methods (and {@link MessageFactory} by
- * extension.)
+ * Creates {@link FormattedMessage} instances for {@link MessageFactory} methods.
*
* <h4>Note to implementors</h4>
* <p>
- * This class implements all {@link MessageFactory2} methods.
+ * This class implements all {@link MessageFactory} methods.
* </p>
*/
-public class MessageFormatMessageFactory extends AbstractMessageFactory {
+public class MessageFormatMessageFactory implements MessageFactory, Serializable {
private static final long serialVersionUID = 3584821740584192453L;
/**
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedMessageFactory.java
index 5878cac..8716f18 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedMessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedMessageFactory.java
@@ -16,9 +16,10 @@
*/
package org.apache.logging.log4j.message;
+import java.io.Serializable;
+
/**
- * Creates {@link FormattedMessage} instances for {@link MessageFactory2} methods (and {@link MessageFactory} by
- * extension.)
+ * Creates {@link FormattedMessage} instances for {@link MessageFactory}.
* <p>
* Enables the use of <code>{}</code> parameter markers in message strings.
* </p>
@@ -31,10 +32,10 @@ package org.apache.logging.log4j.message;
*
* <h4>Note to implementors</h4>
* <p>
- * This class implements all {@link MessageFactory2} methods.
+ * This class implements all {@link MessageFactory} methods.
* </p>
*/
-public final class ParameterizedMessageFactory extends AbstractMessageFactory {
+public final class ParameterizedMessageFactory implements MessageFactory, Serializable {
/**
* Instance of ParameterizedMessageFactory.
*/
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedNoReferenceMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedNoReferenceMessageFactory.java
index fdf397b..3ad9e85 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedNoReferenceMessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedNoReferenceMessageFactory.java
@@ -18,9 +18,10 @@ package org.apache.logging.log4j.message;
import org.apache.logging.log4j.status.StatusLogger;
+import java.io.Serializable;
+
/**
- * Creates {@link FormattedMessage} instances for {@link MessageFactory2} methods (and {@link MessageFactory} by
- * extension.)
+ * Creates {@link FormattedMessage} instances for {@link MessageFactory} methods.
* <p>
* Creates {@link SimpleMessage} objects that do not retain a reference to the parameter object.
* </p>
@@ -33,11 +34,11 @@ import org.apache.logging.log4j.status.StatusLogger;
* </p>
* <h4>Note to implementors</h4>
* <p>
- * This class does <em>not</em> implement any {@link MessageFactory2} methods and lets the superclass funnel those calls
+ * This class does <em>not</em> implement any {@link MessageFactory} methods and lets the superclass funnel those calls
* through {@link #newMessage(String, Object...)}.
* </p>
*/
-public final class ParameterizedNoReferenceMessageFactory extends AbstractMessageFactory {
+public final class ParameterizedNoReferenceMessageFactory implements MessageFactory, Serializable {
private static final long serialVersionUID = 5027639245636870500L;
/**
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableMessageFactory.java
index bf30cfa..88a153b 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableMessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableMessageFactory.java
@@ -30,7 +30,7 @@ import org.apache.logging.log4j.util.PerformanceSensitive;
* @since 2.6
*/
@PerformanceSensitive("allocation")
-public final class ReusableMessageFactory implements MessageFactory2, Serializable {
+public final class ReusableMessageFactory implements MessageFactory, Serializable {
/**
* Instance of ReusableMessageFactory..
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/SimpleMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/SimpleMessageFactory.java
index e85b8c0..43a7259 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/SimpleMessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/SimpleMessageFactory.java
@@ -16,9 +16,10 @@
*/
package org.apache.logging.log4j.message;
+import java.io.Serializable;
+
/**
- * Creates {@link FormattedMessage} instances for {@link MessageFactory2} methods (and {@link MessageFactory} by
- * extension.)
+ * Creates {@link FormattedMessage} instances for {@link MessageFactory} methods.
* <p>
* This uses is the simplest possible implementation of {@link Message}, the where you give the message to the
* constructor argument as a String.
@@ -32,12 +33,12 @@ package org.apache.logging.log4j.message;
*
* <h4>Note to implementors</h4>
* <p>
- * This class implements all {@link MessageFactory2} methods.
+ * This class implements all {@link MessageFactory} methods.
* </p>
*
* @since 2.5
*/
-public final class SimpleMessageFactory extends AbstractMessageFactory {
+public final class SimpleMessageFactory implements MessageFactory, Serializable {
/**
* Instance of StringFormatterMessageFactory.
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/StringFormatterMessageFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/StringFormatterMessageFactory.java
index b6554d5..a2b0e96 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/StringFormatterMessageFactory.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/StringFormatterMessageFactory.java
@@ -16,9 +16,10 @@
*/
package org.apache.logging.log4j.message;
+import java.io.Serializable;
+
/**
- * Creates {@link FormattedMessage} instances for {@link MessageFactory2} methods (and {@link MessageFactory} by
- * extension.)
+ * Creates {@link FormattedMessage} instances for {@link MessageFactory} methods.
* <p>
* Enables the use of {@link java.util.Formatter} strings in message strings.
* </p>
@@ -30,10 +31,10 @@ package org.apache.logging.log4j.message;
* </p>
* <h4>Note to implementors</h4>
* <p>
- * This class implements all {@link MessageFactory2} methods.
+ * This class implements all {@link MessageFactory} methods.
* </p>
*/
-public final class StringFormatterMessageFactory extends AbstractMessageFactory {
+public final class StringFormatterMessageFactory implements MessageFactory, Serializable {
/**
* Instance of StringFormatterMessageFactory.
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
index 9b1b060..9a9115a 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
@@ -22,12 +22,13 @@ import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LoggingException;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.internal.DefaultLogBuilder;
+import org.apache.logging.log4j.internal.LogBuilder;
import org.apache.logging.log4j.message.DefaultFlowMessageFactory;
import org.apache.logging.log4j.message.EntryMessage;
import org.apache.logging.log4j.message.FlowMessageFactory;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.message.MessageFactory2;
import org.apache.logging.log4j.message.ParameterizedMessage;
import org.apache.logging.log4j.message.ParameterizedMessageFactory;
import org.apache.logging.log4j.message.ReusableMessageFactory;
@@ -102,9 +103,11 @@ public abstract class AbstractLogger implements ExtendedLogger, Serializable {
private static final String CATCHING = "Catching";
protected final String name;
- private final MessageFactory2 messageFactory;
+ private final MessageFactory messageFactory;
private final FlowMessageFactory flowMessageFactory;
private static ThreadLocal<int[]> recursionDepthHolder = new ThreadLocal<>(); // LOG4J2-1518, LOG4J2-2031
+ private final ThreadLocal<DefaultLogBuilder> logBuilder;
+
/**
* Creates a new logger named after this class (or subclass).
@@ -113,6 +116,7 @@ public abstract class AbstractLogger implements ExtendedLogger, Serializable {
this.name = getClass().getName();
this.messageFactory = createDefaultMessageFactory();
this.flowMessageFactory = createDefaultFlowMessageFactory();
+ this.logBuilder = new LocalLogBuilder(this);
}
/**
@@ -132,8 +136,9 @@ public abstract class AbstractLogger implements ExtendedLogger, Serializable {
*/
public AbstractLogger(final String name, final MessageFactory messageFactory) {
this.name = name;
- this.messageFactory = messageFactory == null ? createDefaultMessageFactory() : narrow(messageFactory);
+ this.messageFactory = messageFactory == null ? createDefaultMessageFactory() : messageFactory;
this.flowMessageFactory = createDefaultFlowMessageFactory();
+ this.logBuilder = new LocalLogBuilder(this);
}
/**
@@ -214,22 +219,14 @@ public abstract class AbstractLogger implements ExtendedLogger, Serializable {
}
}
- private static MessageFactory2 createDefaultMessageFactory() {
+ private static MessageFactory createDefaultMessageFactory() {
try {
- final MessageFactory result = DEFAULT_MESSAGE_FACTORY_CLASS.newInstance();
- return narrow(result);
+ return DEFAULT_MESSAGE_FACTORY_CLASS.newInstance();
} catch (final InstantiationException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
- private static MessageFactory2 narrow(final MessageFactory result) {
- if (result instanceof MessageFactory2) {
- return (MessageFactory2) result;
- }
- return new MessageFactory2Adapter(result);
- }
-
private static FlowMessageFactory createDefaultFlowMessageFactory() {
try {
return DEFAULT_FLOW_MESSAGE_FACTORY_CLASS.newInstance();
@@ -2028,6 +2025,23 @@ public abstract class AbstractLogger implements ExtendedLogger, Serializable {
logMessageSafely(fqcn, level, marker, msg, msg.getThrowable());
}
+ public void logMessage(final Level level, final Marker marker, final String fqcn, final StackTraceElement location,
+ final Message message, final Throwable throwable) {
+ try {
+ incrementRecursionDepth();
+ log(level, marker, fqcn, location, message, throwable);
+ } catch (Exception ex) {
+ handleLogMessageException(ex, fqcn, message);
+ } finally {
+ decrementRecursionDepth();
+ ReusableMessageFactory.release(message);
+ }
+ }
+
+ protected void log(final Level level, final Marker marker, final String fqcn, final StackTraceElement location,
+ final Message message, final Throwable throwable) {
+ }
+
@Override
public void printf(final Level level, final Marker marker, final String format, final Object... params) {
if (isEnabled(level, marker, format, params)) {
@@ -2734,4 +2748,108 @@ public abstract class AbstractLogger implements ExtendedLogger, Serializable {
final Object p7, final Object p8, final Object p9) {
logIfEnabled(FQCN, Level.WARN, null, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
}
+
+ /**
+ * Constuct a trace log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ @Override
+ public LogBuilder atTrace() {
+ if (isTraceEnabled()) {
+ return logBuilder.get().setLevel(Level.TRACE);
+ } else {
+ return LogBuilder.INSTANCE;
+ }
+ }
+ /**
+ * Constuct a trace log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ @Override
+ public LogBuilder atDebug() {
+ if (isDebugEnabled()) {
+ return logBuilder.get().setLevel(Level.DEBUG);
+ } else {
+ return LogBuilder.INSTANCE;
+ }
+ }
+ /**
+ * Constuct a trace log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ @Override
+ public LogBuilder atInfo() {
+ if (isInfoEnabled()) {
+ return logBuilder.get().setLevel(Level.INFO);
+ } else {
+ return LogBuilder.INSTANCE;
+ }
+ }
+ /**
+ * Constuct a trace log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ @Override
+ public LogBuilder atWarn() {
+ if (isWarnEnabled()) {
+ return logBuilder.get().setLevel(Level.WARN);
+ } else {
+ return LogBuilder.INSTANCE;
+ }
+ }
+ /**
+ * Constuct a trace log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ @Override
+ public LogBuilder atError() {
+ if (isErrorEnabled()) {
+ return logBuilder.get().setLevel(Level.ERROR);
+ } else {
+ return LogBuilder.INSTANCE;
+ }
+ }
+ /**
+ * Constuct a trace log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ @Override
+ public LogBuilder atFatal() {
+ if (isFatalEnabled()) {
+ return logBuilder.get().setLevel(Level.FATAL);
+ } else {
+ return LogBuilder.INSTANCE;
+ }
+ }
+ /**
+ * Constuct a log event.
+ * @return a LogBuilder.
+ * @since 3.0
+ */
+ @Override
+ public LogBuilder atLevel(Level level) {
+ if (isEnabled(level)) {
+ return logBuilder.get().setLevel(level);
+ } else {
+ return LogBuilder.INSTANCE;
+ }
+ }
+
+ private class LocalLogBuilder extends ThreadLocal<DefaultLogBuilder> {
+ private AbstractLogger logger;
+ LocalLogBuilder(AbstractLogger logger) {
+ this.logger = logger;
+ }
+
+ @Override
+ protected DefaultLogBuilder initialValue() {
+ return new DefaultLogBuilder(logger);
+ }
+ }
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/MessageFactory2Adapter.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/MessageFactory2Adapter.java
deleted file mode 100644
index ff31515..0000000
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/MessageFactory2Adapter.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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.spi;
-
-import java.util.Objects;
-
-import org.apache.logging.log4j.message.Message;
-import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.message.MessageFactory2;
-import org.apache.logging.log4j.message.SimpleMessage;
-
-/**
- * Adapts a legacy MessageFactory to the new MessageFactory2 interface.
- *
- * @since 2.6
- */
-public class MessageFactory2Adapter implements MessageFactory2 {
- private final MessageFactory wrapped;
-
- public MessageFactory2Adapter(final MessageFactory wrapped) {
- this.wrapped = Objects.requireNonNull(wrapped);
- }
-
- public MessageFactory getOriginal() {
- return wrapped;
- }
-
- @Override
- public Message newMessage(final CharSequence charSequence) {
- return new SimpleMessage(charSequence);
- }
-
- @Override
- public Message newMessage(final String message, final Object p0) {
- return wrapped.newMessage(message, p0);
- }
-
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1) {
- return wrapped.newMessage(message, p0, p1);
- }
-
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2) {
- return wrapped.newMessage(message, p0, p1, p2);
- }
-
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2,
- final Object p3) {
- return wrapped.newMessage(message, p0, p1, p2, p3);
- }
-
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3,
- final Object p4) {
- return wrapped.newMessage(message, p0, p1, p2, p3, p4);
- }
-
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3,
- final Object p4, final Object p5) {
- return wrapped.newMessage(message, p0, p1, p2, p3, p4, p5);
- }
-
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3,
- final Object p4, final Object p5, final Object p6) {
- return wrapped.newMessage(message, p0, p1, p2, p3, p4, p5, p6);
- }
-
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3,
- final Object p4, final Object p5, final Object p6, final Object p7) {
- return wrapped.newMessage(message, p0, p1, p2, p3, p4, p5, p6, p7);
- }
-
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3,
- final Object p4, final Object p5, final Object p6, final Object p7, final Object p8) {
- return wrapped.newMessage(message, p0, p1, p2, p3, p4, p5, p6, p7, p8);
- }
-
- @Override
- public Message newMessage(final String message, final Object p0, final Object p1, final Object p2, final Object p3,
- final Object p4, final Object p5, final Object p6, final Object p7, final Object p8, final Object p9) {
- return wrapped.newMessage(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
- }
-
- @Override
- public Message newMessage(final Object message) {
- return wrapped.newMessage(message);
- }
-
- @Override
- public Message newMessage(final String message) {
- return wrapped.newMessage(message);
- }
-
- @Override
- public Message newMessage(final String message, final Object... params) {
- return wrapped.newMessage(message, params);
- }
-}
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java
index a152aad..4a703cd 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java
@@ -31,7 +31,6 @@ import org.apache.logging.log4j.message.ParameterizedMessage;
import org.apache.logging.log4j.message.ParameterizedMessageFactory;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.spi.AbstractLogger;
-import org.apache.logging.log4j.spi.MessageFactory2Adapter;
import org.apache.logging.log4j.status.StatusData;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.MessageSupplier;
@@ -989,7 +988,7 @@ public class AbstractLoggerTest {
private int objectCount;
CountingLogger() {
- super("CountingLogger", new MessageFactory2Adapter(ParameterizedMessageFactory.INSTANCE));
+ super("CountingLogger", ParameterizedMessageFactory.INSTANCE);
}
void setCurrentLevel(final Level currentLevel) {
@@ -1216,7 +1215,7 @@ public class AbstractLoggerTest {
private final boolean expectingThrowables;
ThrowableExpectingLogger(final boolean expectingThrowables) {
- super("ThrowableExpectingLogger", new MessageFactory2Adapter(ParameterizedMessageFactory.INSTANCE));
+ super("ThrowableExpectingLogger", ParameterizedMessageFactory.INSTANCE);
this.expectingThrowables = expectingThrowables;
}
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java
index 351b36f..1026d56 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java
@@ -26,10 +26,10 @@ import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.message.ObjectMessage;
import org.apache.logging.log4j.message.ParameterizedMessageFactory;
+import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.message.SimpleMessageFactory;
import org.apache.logging.log4j.message.StringFormatterMessageFactory;
import org.apache.logging.log4j.message.StructuredDataMessage;
-import org.apache.logging.log4j.spi.MessageFactory2Adapter;
import org.apache.logging.log4j.util.Strings;
import org.apache.logging.log4j.util.Supplier;
import org.junit.Before;
@@ -58,6 +58,18 @@ public class LoggerTest {
private final List<String> results = logger.getEntries();
@Test
+ public void builder() {
+ logger.atDebug().withLocation().withMessage("Hello").log();
+ logger.atError().withMarker(marker).withMessage("Hello {}").withParameters("John").log();
+ logger.atWarn().withMessage(new SimpleMessage("Log4j rocks!")).withThrowable(new Throwable("This is a test")).log();
+ assertEquals(3, results.size());
+ assertThat("Incorrect message 1", results.get(0), equalTo(" DEBUG org.apache.logging.log4j.LoggerTest.builder(LoggerTest.java:62) Hello"));
+ assertThat("Incorrect message 2", results.get(1), equalTo("test ERROR Hello John"));
+ assertThat("Incorrect message 3", results.get(2), startsWith(" WARN Log4j rocks! java.lang.Throwable: This is a test\n" +
+ "\tat org.apache.logging.log4j.LoggerTest.builder(LoggerTest.java:64)"));
+ }
+
+ @Test
public void basicFlow() {
logger.traceEntry();
logger.traceExit();
@@ -253,9 +265,6 @@ public class LoggerTest {
}
private static void assertMessageFactoryInstanceOf(MessageFactory factory, final Class<?> cls) {
- if (factory instanceof MessageFactory2Adapter) {
- factory = ((MessageFactory2Adapter) factory).getOriginal();
- }
assertTrue(factory.getClass().isAssignableFrom(cls));
}
@@ -327,9 +336,6 @@ public class LoggerTest {
private void assertEqualMessageFactory(final MessageFactory messageFactory, final TestLogger testLogger) {
MessageFactory actual = testLogger.getMessageFactory();
- if (actual instanceof MessageFactory2Adapter) {
- actual = ((MessageFactory2Adapter) actual).getOriginal();
- }
assertEquals(messageFactory, actual);
}
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/TestLogger.java b/log4j-api/src/test/java/org/apache/logging/log4j/TestLogger.java
index 5f7abb7..b7a820c 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/TestLogger.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/TestLogger.java
@@ -53,6 +53,12 @@ public class TestLogger extends AbstractLogger {
@Override
public void logMessage(final String fqcn, final Level level, final Marker marker, final Message msg, final Throwable throwable) {
+ log(level, marker, fqcn, null, msg, throwable);
+ }
+
+ @Override
+ protected void log(final Level level, final Marker marker, final String fqcn, final StackTraceElement location,
+ final Message message, final Throwable throwable) {
final StringBuilder sb = new StringBuilder();
if (marker != null) {
sb.append(marker);
@@ -60,14 +66,18 @@ public class TestLogger extends AbstractLogger {
sb.append(' ');
sb.append(level.toString());
sb.append(' ');
- sb.append(msg.getFormattedMessage());
+ if (location != null) {
+ sb.append(location.toString());
+ sb.append(' ');
+ }
+ sb.append(message.getFormattedMessage());
final Map<String, String> mdc = ThreadContext.getImmutableContext();
if (mdc.size() > 0) {
sb.append(' ');
sb.append(mdc.toString());
sb.append(' ');
}
- final Object[] params = msg.getParameters();
+ final Object[] params = message.getParameters();
Throwable t;
if (throwable == null && params != null && params.length > 0 && params[params.length - 1] instanceof Throwable) {
t = (Throwable) params[params.length - 1];
@@ -81,7 +91,6 @@ public class TestLogger extends AbstractLogger {
sb.append(baos.toString());
}
list.add(sb.toString());
- //System.out.println(sb.toString());
}
@Override
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java
index ef90b40..856ca31 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java
@@ -147,6 +147,13 @@ public class Logger extends AbstractLogger implements Supplier<LoggerConfig> {
}
@Override
+ protected void log(final Level level, final Marker marker, final String fqcn, final StackTraceElement location,
+ final Message message, final Throwable throwable) {
+ final ReliabilityStrategy strategy = privateConfig.loggerConfig.getReliabilityStrategy();
+ strategy.log(this, getName(), fqcn, location, marker, level, message, throwable);
+ }
+
+ @Override
public boolean isEnabled(final Level level, final Marker marker, final String message, final Throwable t) {
return privateConfig.filter(level, marker, message, t);
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AwaitCompletionReliabilityStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AwaitCompletionReliabilityStrategy.java
index 3314706..e9031e8 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AwaitCompletionReliabilityStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AwaitCompletionReliabilityStrategy.java
@@ -70,6 +70,25 @@ public class AwaitCompletionReliabilityStrategy implements ReliabilityStrategy {
* (non-Javadoc)
*
* @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
+ * java.lang.String, java.lang.String, java.lang.StackTraceElement, org.apache.logging.log4j.Marker,
+ * org.apache.logging.log4j.Level, org.apache.logging.log4j.message.Message, java.lang.Throwable)
+ */
+ @Override
+ public void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn,
+ final StackTraceElement location, final Marker marker, final Level level, final Message data,
+ final Throwable t) {
+ final LoggerConfig config = getActiveLoggerConfig(reconfigured);
+ try {
+ config.log(loggerName, fqcn, location, marker, level, data, t);
+ } finally {
+ config.getReliabilityStrategy().afterLogEvent();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
* org.apache.logging.log4j.core.LogEvent)
*/
@Override
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AwaitUnconditionallyReliabilityStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AwaitUnconditionallyReliabilityStrategy.java
index 357f18b..ce88285 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AwaitUnconditionallyReliabilityStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AwaitUnconditionallyReliabilityStrategy.java
@@ -60,6 +60,20 @@ public class AwaitUnconditionallyReliabilityStrategy implements ReliabilityStrat
/*
* (non-Javadoc)
+ *
+ * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
+ * java.lang.String, java.lang.String, java.lang.StackTraceElement, org.apache.logging.log4j.Marker,
+ * org.apache.logging.log4j.Level, org.apache.logging.log4j.message.Message, java.lang.Throwable)
+ */
+ @Override
+ public void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn,
+ final StackTraceElement location, final Marker marker, final Level level, final Message data,
+ final Throwable t) {
+ loggerConfig.log(loggerName, fqcn, location, marker, level, data, t);
+ }
+
+ /*
+ * (non-Javadoc)
*
* @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
* org.apache.logging.log4j.core.LogEvent)
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/DefaultReliabilityStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/DefaultReliabilityStrategy.java
index 18fcae4..4777f2f 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/DefaultReliabilityStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/DefaultReliabilityStrategy.java
@@ -51,6 +51,20 @@ public class DefaultReliabilityStrategy implements ReliabilityStrategy {
/*
* (non-Javadoc)
+ *
+ * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
+ * java.lang.String, java.lang.String, java.lang.StackTraceElement, org.apache.logging.log4j.Marker,
+ * org.apache.logging.log4j.Level, org.apache.logging.log4j.message.Message, java.lang.Throwable)
+ */
+ @Override
+ public void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn,
+ final StackTraceElement location, final Marker marker, final Level level, final Message data,
+ final Throwable t) {
+ loggerConfig.log(loggerName, fqcn, location, marker, level, data, t);
+ }
+
+ /*
+ * (non-Javadoc)
*
* @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
* org.apache.logging.log4j.core.LogEvent)
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LockingReliabilityStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LockingReliabilityStrategy.java
index 35215c1..391f2ec 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LockingReliabilityStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LockingReliabilityStrategy.java
@@ -62,6 +62,25 @@ public class LockingReliabilityStrategy implements ReliabilityStrategy {
* (non-Javadoc)
*
* @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
+ * java.lang.String, java.lang.String, java.lang.StackTraceElement, org.apache.logging.log4j.Marker,
+ * org.apache.logging.log4j.Level, org.apache.logging.log4j.message.Message, java.lang.Throwable)
+ */
+ @Override
+ public void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn,
+ final StackTraceElement location, final Marker marker, final Level level, final Message data,
+ final Throwable t) {
+ final LoggerConfig config = getActiveLoggerConfig(reconfigured);
+ try {
+ config.log(loggerName, fqcn, location, marker, level, data, t);
+ } finally {
+ config.getReliabilityStrategy().afterLogEvent();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
* org.apache.logging.log4j.core.LogEvent)
*/
@Override
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
index 7bfcdc1..2c7c186 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
@@ -385,6 +385,52 @@ public class LoggerConfig extends AbstractFilterable {
/**
* Logs an event.
*
+ * @param loggerName The name of the Logger.
+ * @param fqcn The fully qualified class name of the caller.
+ * @param location the location of the caller.
+ * @param marker A Marker or null if none is present.
+ * @param level The event Level.
+ * @param data The Message.
+ * @param t A Throwable or null.
+ */
+ @PerformanceSensitive("allocation")
+ public void log(final String loggerName, final String fqcn, final StackTraceElement location, final Marker marker,
+ final Level level, final Message data, final Throwable t) {
+ List<Property> props = null;
+ if (!propertiesRequireLookup) {
+ props = properties;
+ } else {
+ if (properties != null) {
+ props = new ArrayList<>(properties.size());
+ final LogEvent event = Log4jLogEvent.newBuilder()
+ .setMessage(data)
+ .setMarker(marker)
+ .setLevel(level)
+ .setLoggerName(loggerName)
+ .setLoggerFqcn(fqcn)
+ .setThrown(t)
+ .build();
+ for (int i = 0; i < properties.size(); i++) {
+ final Property prop = properties.get(i);
+ final String value = prop.isValueNeedsLookup() // since LOG4J2-1575
+ ? config.getStrSubstitutor().replace(event, prop.getValue()) //
+ : prop.getValue();
+ props.add(Property.createProperty(prop.getName(), value));
+ }
+ }
+ }
+ final LogEvent logEvent = logEventFactory.createEvent(loggerName, marker, fqcn, location, level, data, props, t);
+ try {
+ log(logEvent, LoggerConfigPredicate.ALL);
+ } finally {
+ // LOG4J2-1583 prevent scrambled logs when logging calls are nested (logging in toString())
+ ReusableLogEventFactory.release(logEvent);
+ }
+ }
+
+ /**
+ * Logs an event.
+ *
* @param event The log event.
*/
public void log(final LogEvent event) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ReliabilityStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ReliabilityStrategy.java
index f21a92d..6400435 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ReliabilityStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ReliabilityStrategy.java
@@ -42,6 +42,22 @@ public interface ReliabilityStrategy {
*/
void log(Supplier<LoggerConfig> reconfigured, String loggerName, String fqcn, Marker marker, Level level,
Message data, Throwable t);
+ /**
+ * Logs an event.
+ *
+ * @param reconfigured supplies the next LoggerConfig if the strategy's LoggerConfig is no longer active
+ * @param loggerName The name of the Logger.
+ * @param fqcn The fully qualified class name of the caller.
+ * @param location The location of the caller or null.
+ * @param marker A Marker or null if none is present.
+ * @param level The event Level.
+ * @param data The Message.
+ * @param t A Throwable or null.
+ * @since 3.0
+ */
+ default void log(Supplier<LoggerConfig> reconfigured, String loggerName, String fqcn, StackTraceElement location,
+ Marker marker, Level level, Message data, Throwable t) {
+ }
/**
* Logs an event.
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/DefaultLogEventFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/DefaultLogEventFactory.java
index 127b02a..343d965 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/DefaultLogEventFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/DefaultLogEventFactory.java
@@ -53,4 +53,23 @@ public class DefaultLogEventFactory implements LogEventFactory {
final List<Property> properties, final Throwable t) {
return new Log4jLogEvent(loggerName, marker, fqcn, level, data, properties, t);
}
+
+ /**
+ * Creates a log event.
+ *
+ * @param loggerName The name of the Logger.
+ * @param marker An optional Marker.
+ * @param location The location of the caller
+ * @param level The event Level.
+ * @param data The Message.
+ * @param properties Properties to be added to the log event.
+ * @param t An optional Throwable.
+ * @return The LogEvent.
+ */
+ @Override
+ public LogEvent createEvent(final String loggerName, final Marker marker, final String fqcn,
+ final StackTraceElement location, final Level level, final Message data,
+ final List<Property> properties, final Throwable t) {
+ return new Log4jLogEvent(loggerName, marker, fqcn, location, level, data, properties, t);
+ }
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
index 1090399..efa732c 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
@@ -301,6 +301,30 @@ public class Log4jLogEvent implements LogEvent {
nanoClock.nanoTime());
}
+ /**
+ * Constructor.
+ * @param loggerName The name of the Logger.
+ * @param marker The Marker or null.
+ * @param source The location of the caller.
+ * @param level The logging Level.
+ * @param message The Message.
+ * @param properties the properties to be merged with ThreadContext key-value pairs into the event's ReadOnlyStringMap.
+ * @param t A Throwable or null.
+ */
+ // This constructor is called from LogEventFactories.
+ public Log4jLogEvent(final String loggerName, final Marker marker, final String fqcn, final StackTraceElement source,
+ final Level level, final Message message, final List<Property> properties, final Throwable t) {
+ this(loggerName, marker,fqcn, level, message, t,
+ null, createContextData(properties),
+ ThreadContext.getDepth() == 0 ? null : ThreadContext.cloneStack(), // mutable copy
+ 0, // thread id
+ null, // thread name
+ 0, // thread priority
+ source, // StackTraceElement source
+ CLOCK, //
+ nanoClock.nanoTime());
+ }
+
/**
* Constructor.
* @param loggerName The name of the Logger.
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/LogEventFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/LogEventFactory.java
index ad9128c..b2af73a 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/LogEventFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/LogEventFactory.java
@@ -32,4 +32,9 @@ public interface LogEventFactory {
LogEvent createEvent(String loggerName, Marker marker, String fqcn, Level level, Message data,
List<Property> properties, Throwable t);
+
+ default LogEvent createEvent(String loggerName, Marker marker, String fqcn, StackTraceElement location, Level level,
+ Message data, List<Property> properties, Throwable t) {
+ return createEvent(loggerName, marker, fqcn, level, data, properties, t);
+ }
}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
index 81f2d9d..59a4465 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
@@ -16,12 +16,6 @@
*/
package org.apache.logging.log4j.core;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertTrue;
-
import java.io.File;
import java.util.Date;
import java.util.HashMap;
@@ -32,6 +26,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.config.Configuration;
@@ -41,16 +36,21 @@ import org.apache.logging.log4j.junit.LoggerContextRule;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.message.ParameterizedMessageFactory;
+import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.message.StringFormatterMessageFactory;
import org.apache.logging.log4j.message.StructuredDataMessage;
import org.apache.logging.log4j.spi.AbstractLogger;
-import org.apache.logging.log4j.spi.MessageFactory2Adapter;
import org.apache.logging.log4j.test.appender.ListAppender;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.junit.Assert.*;
+import static org.junit.Assert.assertThat;
+
public class LoggerTest {
private static final String CONFIG = "log4j-test2.xml";
@@ -84,6 +84,20 @@ public class LoggerTest {
org.apache.logging.log4j.Logger loggerGrandchild;
@Test
+ public void builder() {
+ logger.atDebug().withLocation().withMessage("Hello").log();
+ Marker marker = MarkerManager.getMarker("test");
+ logger.atError().withMarker(marker).withMessage("Hello {}").withParameters("John").log();
+ logger.atWarn().withMessage(new SimpleMessage("Log4j rocks!")).withThrowable(new Throwable("This is a test")).log();
+ final List<LogEvent> events = app.getEvents();
+ assertEventCount(events, 3);
+ assertEquals("Incorrect location", "org.apache.logging.log4j.core.LoggerTest.builder(LoggerTest.java:88)", events.get(0).getSource().toString());
+ assertEquals("Incorrect Level", Level.DEBUG, events.get(0).getLevel());
+ assertThat("Incorrect message", events.get(1).getMessage().getFormattedMessage(), equalTo("Hello John"));
+ assertNotNull("Missing Throwable", events.get(2).getThrown());
+ }
+
+ @Test
public void basicFlow() {
logger.traceEntry();
logger.traceExit();
@@ -275,15 +289,12 @@ public class LoggerTest {
return testLogger1;
}
- private static void checkMessageFactory(final MessageFactory messageFactory1, final Logger testLogger1) {
- if (messageFactory1 == null) {
- assertEquals(AbstractLogger.DEFAULT_MESSAGE_FACTORY_CLASS, testLogger1.getMessageFactory().getClass());
+ private static void checkMessageFactory(final MessageFactory messageFactory, final Logger testLogger) {
+ if (messageFactory == null) {
+ assertEquals(AbstractLogger.DEFAULT_MESSAGE_FACTORY_CLASS, testLogger.getMessageFactory().getClass());
} else {
- MessageFactory actual = testLogger1.getMessageFactory();
- if (actual instanceof MessageFactory2Adapter) {
- actual = ((MessageFactory2Adapter) actual).getOriginal();
- }
- assertEquals(messageFactory1, actual);
+ MessageFactory actual = testLogger.getMessageFactory();
+ assertEquals(messageFactory, actual);
}
}
diff --git a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/SetLoggerTagTest.java b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/SetLoggerTagTest.java
index 022ea58..bc6450d 100644
--- a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/SetLoggerTagTest.java
+++ b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/SetLoggerTagTest.java
@@ -24,7 +24,6 @@ import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.message.StringFormatterMessageFactory;
import org.apache.logging.log4j.spi.AbstractLogger;
-import org.apache.logging.log4j.spi.MessageFactory2Adapter;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockPageContext;
@@ -165,17 +164,14 @@ public class SetLoggerTagTest {
checkMessageFactory("The message factory is not correct.", factory, logger);
}
- private static void checkMessageFactory(final String msg, final MessageFactory messageFactory1,
- final Logger testLogger1) {
- if (messageFactory1 == null) {
+ private static void checkMessageFactory(final String msg, final MessageFactory messageFactory,
+ final Logger testLogger) {
+ if (messageFactory == null) {
assertEquals(msg, AbstractLogger.DEFAULT_MESSAGE_FACTORY_CLASS,
- testLogger1.getMessageFactory().getClass());
+ testLogger.getMessageFactory().getClass());
} else {
- MessageFactory actual = testLogger1.getMessageFactory();
- if (actual instanceof MessageFactory2Adapter) {
- actual = ((MessageFactory2Adapter) actual).getOriginal();
- }
- assertEquals(msg, messageFactory1, actual);
+ MessageFactory actual = testLogger.getMessageFactory();
+ assertEquals(msg, messageFactory, actual);
}
}
diff --git a/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/LoggerTest.java b/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/LoggerTest.java
index a115392..e994d19 100644
--- a/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/LoggerTest.java
+++ b/log4j-to-slf4j/src/test/java/org/apache/logging/slf4j/LoggerTest.java
@@ -29,7 +29,6 @@ import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.message.ParameterizedMessageFactory;
import org.apache.logging.log4j.message.StringFormatterMessageFactory;
import org.apache.logging.log4j.spi.AbstractLogger;
-import org.apache.logging.log4j.spi.MessageFactory2Adapter;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
@@ -126,15 +125,12 @@ public class LoggerTest {
return testLogger;
}
- private static void checkMessageFactory(final MessageFactory messageFactory1, final Logger testLogger1) {
- if (messageFactory1 == null) {
- assertEquals(AbstractLogger.DEFAULT_MESSAGE_FACTORY_CLASS, testLogger1.getMessageFactory().getClass());
+ private static void checkMessageFactory(final MessageFactory messageFactory, final Logger testLogger) {
+ if (messageFactory == null) {
+ assertEquals(AbstractLogger.DEFAULT_MESSAGE_FACTORY_CLASS, testLogger.getMessageFactory().getClass());
} else {
- MessageFactory actual = testLogger1.getMessageFactory();
- if (actual instanceof MessageFactory2Adapter) {
- actual = ((MessageFactory2Adapter) actual).getOriginal();
- }
- assertEquals(messageFactory1, actual);
+ MessageFactory actual = testLogger.getMessageFactory();
+ assertEquals(messageFactory, actual);
}
}