diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterFormatterTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterFormatterTest.java
index ee4735191d5..af7a3acc777 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterFormatterTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterFormatterTest.java
@@ -16,156 +16,106 @@
*/
package org.apache.logging.log4j.message;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import org.apache.logging.log4j.message.ParameterFormatter.MessagePatternAnalysis;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.MethodSource;
/**
* Tests {@link ParameterFormatter}.
*/
public class ParameterFormatterTest {
- @Test
- public void testCountArgumentPlaceholders() {
- assertEquals(0, ParameterFormatter.countArgumentPlaceholders(""));
- assertEquals(0, ParameterFormatter.countArgumentPlaceholders("aaa"));
- assertEquals(0, ParameterFormatter.countArgumentPlaceholders("\\{}"));
- assertEquals(1, ParameterFormatter.countArgumentPlaceholders("{}"));
- assertEquals(1, ParameterFormatter.countArgumentPlaceholders("{}\\{}"));
- assertEquals(2, ParameterFormatter.countArgumentPlaceholders("{}{}"));
- assertEquals(3, ParameterFormatter.countArgumentPlaceholders("{}{}{}"));
- assertEquals(4, ParameterFormatter.countArgumentPlaceholders("{}{}{}aa{}"));
- assertEquals(4, ParameterFormatter.countArgumentPlaceholders("{}{}{}a{]b{}"));
- assertEquals(5, ParameterFormatter.countArgumentPlaceholders("{}{}{}a{}b{}"));
- }
-
- @Test
- public void testFormat3StringArgs() {
- final String testMsg = "Test message {}{} {}";
- final String[] args = {"a", "b", "c"};
- final String result = ParameterFormatter.format(testMsg, args);
- assertEquals("Test message ab c", result);
- }
-
- @Test
- public void testFormatNullArgs() {
- final String testMsg = "Test message {} {} {} {} {} {}";
- final String[] args = {"a", null, "c", null, null, null};
- final String result = ParameterFormatter.format(testMsg, args);
- assertEquals("Test message a null c null null null", result);
- }
-
- @Test
- public void testFormatStringArgsIgnoresSuperfluousArgs() {
- final String testMsg = "Test message {}{} {}";
- final String[] args = {"a", "b", "c", "unnecessary", "superfluous"};
- final String result = ParameterFormatter.format(testMsg, args);
- assertEquals("Test message ab c", result);
- }
-
- @Test
- public void testFormatStringArgsWithEscape() {
- final String testMsg = "Test message \\{}{} {}";
- final String[] args = {"a", "b", "c"};
- final String result = ParameterFormatter.format(testMsg, args);
- assertEquals("Test message {}a b", result);
- }
-
- @Test
- public void testFormatStringArgsWithTrailingEscape() {
- final String testMsg = "Test message {}{} {}\\";
- final String[] args = {"a", "b", "c"};
- final String result = ParameterFormatter.format(testMsg, args);
- assertEquals("Test message ab c\\", result);
- }
-
- @Test
- public void testFormatStringArgsWithTrailingEscapedEscape() {
- final String testMsg = "Test message {}{} {}\\\\";
- final String[] args = {"a", "b", "c"};
- final String result = ParameterFormatter.format(testMsg, args);
- assertEquals("Test message ab c\\\\", result);
- }
-
- @Test
- public void testFormatStringArgsWithEscapedEscape() {
- final String testMsg = "Test message \\\\{}{} {}";
- final String[] args = {"a", "b", "c"};
- final String result = ParameterFormatter.format(testMsg, args);
- assertEquals("Test message \\ab c", result);
- }
-
- @Test
- public void testFormatMessage3StringArgs() {
- final String testMsg = "Test message {}{} {}";
- final String[] args = {"a", "b", "c"};
- final StringBuilder sb = new StringBuilder();
- ParameterFormatter.formatMessage(sb, testMsg, args, 3);
- final String result = sb.toString();
- assertEquals("Test message ab c", result);
- }
-
- @Test
- public void testFormatMessageNullArgs() {
- final String testMsg = "Test message {} {} {} {} {} {}";
- final String[] args = {"a", null, "c", null, null, null};
- final StringBuilder sb = new StringBuilder();
- ParameterFormatter.formatMessage(sb, testMsg, args, 6);
- final String result = sb.toString();
- assertEquals("Test message a null c null null null", result);
- }
-
- @Test
- public void testFormatMessageStringArgsIgnoresSuperfluousArgs() {
- final String testMsg = "Test message {}{} {}";
- final String[] args = {"a", "b", "c", "unnecessary", "superfluous"};
- final StringBuilder sb = new StringBuilder();
- ParameterFormatter.formatMessage(sb, testMsg, args, 5);
- final String result = sb.toString();
- assertEquals("Test message ab c", result);
- }
-
- @Test
- public void testFormatMessageStringArgsWithEscape() {
- final String testMsg = "Test message \\{}{} {}";
- final String[] args = {"a", "b", "c"};
- final StringBuilder sb = new StringBuilder();
- ParameterFormatter.formatMessage(sb, testMsg, args, 3);
- final String result = sb.toString();
- assertEquals("Test message {}a b", result);
- }
-
- @Test
- public void testFormatMessageStringArgsWithTrailingEscape() {
- final String testMsg = "Test message {}{} {}\\";
- final String[] args = {"a", "b", "c"};
- final StringBuilder sb = new StringBuilder();
- ParameterFormatter.formatMessage(sb, testMsg, args, 3);
- final String result = sb.toString();
- assertEquals("Test message ab c\\", result);
- }
-
- @Test
- public void testFormatMessageStringArgsWithTrailingEscapedEscape() {
- final String testMsg = "Test message {}{} {}\\\\";
- final String[] args = {"a", "b", "c"};
- final StringBuilder sb = new StringBuilder();
- ParameterFormatter.formatMessage(sb, testMsg, args, 3);
- final String result = sb.toString();
- assertEquals("Test message ab c\\\\", result);
- }
-
- @Test
- public void testFormatMessageStringArgsWithEscapedEscape() {
- final String testMsg = "Test message \\\\{}{} {}";
- final String[] args = {"a", "b", "c"};
- final StringBuilder sb = new StringBuilder();
- ParameterFormatter.formatMessage(sb, testMsg, args, 3);
- final String result = sb.toString();
- assertEquals("Test message \\ab c", result);
+ @ParameterizedTest
+ @CsvSource({
+ "0,,false,",
+ "0,,false,aaa",
+ "0,,true,\\{}",
+ "1,0,false,{}",
+ "1,0,true,{}\\{}",
+ "1,2,true,\\\\{}",
+ "2,8:10,true,foo \\{} {}{}",
+ "2,8:10,true,foo {\\} {}{}",
+ "2,0:2,false,{}{}",
+ "3,0:2:4,false,{}{}{}",
+ "4,0:2:4:8,false,{}{}{}aa{}",
+ "4,0:2:4:10,false,{}{}{}a{]b{}",
+ "5,0:2:4:7:10,false,{}{}{}a{}b{}"
+ })
+ public void test_pattern_analysis(
+ final int placeholderCount,
+ final String placeholderCharIndicesString,
+ final boolean escapedPlaceholderFound,
+ final String pattern) {
+ MessagePatternAnalysis analysis = ParameterFormatter.analyzePattern(pattern, placeholderCount);
+ assertThat(analysis.placeholderCount).isEqualTo(placeholderCount);
+ if (placeholderCount > 0) {
+ final int[] placeholderCharIndices = Arrays.stream(placeholderCharIndicesString.split(":"))
+ .mapToInt(Integer::parseInt)
+ .toArray();
+ assertThat(analysis.placeholderCharIndices).startsWith(placeholderCharIndices);
+ assertThat(analysis.escapedCharFound).isEqualTo(escapedPlaceholderFound);
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("messageFormattingTestCases")
+ void assertMessageFormatting(
+ final String pattern, final Object[] args, final int argCount, final String expectedFormattedMessage) {
+ MessagePatternAnalysis analysis = ParameterFormatter.analyzePattern(pattern, -1);
+ final StringBuilder buffer = new StringBuilder();
+ ParameterFormatter.formatMessage(buffer, pattern, args, argCount, analysis);
+ String actualFormattedMessage = buffer.toString();
+ assertThat(actualFormattedMessage).isEqualTo(expectedFormattedMessage);
+ }
+
+ static Object[][] messageFormattingTestCases() {
+ return new Object[][] {
+ new Object[] {"Test message {}{} {}", new Object[] {"a", "b", "c"}, 3, "Test message ab c"},
+ new Object[] {
+ "Test message {} {} {} {} {} {}",
+ new Object[] {"a", null, "c", null, null, null},
+ 6,
+ "Test message a null c null null null"
+ },
+ new Object[] {
+ "Test message {}{} {}",
+ new Object[] {"a", "b", "c", "unnecessary", "superfluous"},
+ 5,
+ "Test message ab c"
+ },
+ new Object[] {"Test message \\{}{} {}", new Object[] {"a", "b", "c"}, 3, "Test message {}a b"},
+ new Object[] {"Test message {}{} {}\\", new Object[] {"a", "b", "c"}, 3, "Test message ab c\\"},
+ new Object[] {"Test message {}{} {}\\\\", new Object[] {"a", "b", "c"}, 3, "Test message ab c\\"},
+ new Object[] {"Test message \\\\{}{} {}", new Object[] {"a", "b", "c"}, 3, "Test message \\ab c"},
+ new Object[] {"Test message {}{} {}", new Object[] {"a", "b", "c"}, 3, "Test message ab c"},
+ new Object[] {
+ "Test message {} {} {} {} {} {}",
+ new Object[] {"a", null, "c", null, null, null},
+ 6,
+ "Test message a null c null null null"
+ },
+ new Object[] {
+ "Test message {}{} {}",
+ new Object[] {"a", "b", "c", "unnecessary", "superfluous"},
+ 5,
+ "Test message ab c"
+ },
+ new Object[] {"Test message \\{}{} {}", new Object[] {"a", "b", "c"}, 3, "Test message {}a b"},
+ new Object[] {"Test message {}{} {}\\", new Object[] {"a", "b", "c"}, 3, "Test message ab c\\"},
+ new Object[] {"Test message {}{} {}\\\\", new Object[] {"a", "b", "c"}, 3, "Test message ab c\\"},
+ new Object[] {"Test message \\\\{}{} {}", new Object[] {"a", "b", "c"}, 3, "Test message \\ab c"},
+ new Object[] {"foo \\\\\\{} {}", new Object[] {"bar"}, 1, "foo \\{} bar"},
+ new Object[] {"missing arg {} {}", new Object[] {1, 2}, 1, "missing arg 1 {}"},
+ new Object[] {"foo {\\} {}", new Object[] {"bar"}, 1, "foo {\\} bar"}
+ };
}
@Test
@@ -177,7 +127,7 @@ public void testDeepToString() {
list.add(2);
final String actual = ParameterFormatter.deepToString(list);
final String expected = "[1, [..." + ParameterFormatter.identityToString(list) + "...], 2]";
- assertEquals(expected, actual);
+ assertThat(actual).isEqualTo(expected);
}
@Test
@@ -191,7 +141,7 @@ public void testDeepToStringUsingNonRecursiveButConsequentObjects() {
list.add(3);
final String actual = ParameterFormatter.deepToString(list);
final String expected = "[1, [0], 2, [0], 3]";
- assertEquals(expected, actual);
+ assertThat(actual).isEqualTo(expected);
}
@Test
@@ -203,6 +153,6 @@ public void testIdentityToString() {
list.add(2);
final String actual = ParameterFormatter.identityToString(list);
final String expected = list.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(list));
- assertEquals(expected, actual);
+ assertThat(actual).isEqualTo(expected);
}
}
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterizedMessageTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterizedMessageTest.java
index 686edf52556..d17f5723d2d 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterizedMessageTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterizedMessageTest.java
@@ -115,7 +115,7 @@ public void testFormatStringArgsWithTrailingEscapedEscape() {
final String testMsg = "Test message {}{} {}\\\\";
final String[] args = {"a", "b", "c"};
final String result = ParameterizedMessage.format(testMsg, args);
- assertEquals("Test message ab c\\\\", result);
+ assertEquals("Test message ab c\\", result);
}
@Test
diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ReusableParameterizedMessageTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ReusableParameterizedMessageTest.java
index 10adcf6f8a7..1a03523c7b3 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ReusableParameterizedMessageTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ReusableParameterizedMessageTest.java
@@ -112,7 +112,7 @@ public void testFormatStringArgsWithTrailingEscapedEscape() {
final String[] args = {"a", "b", "c"};
final String result =
new ReusableParameterizedMessage().set(testMsg, (Object[]) args).getFormattedMessage();
- assertEquals("Test message ab c\\\\", result);
+ assertEquals("Test message ab c\\", result);
}
@Test
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/BasicThreadInformation.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/BasicThreadInformation.java
index 26dfbed3023..fae8236793f 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/BasicThreadInformation.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/BasicThreadInformation.java
@@ -16,7 +16,9 @@
*/
package org.apache.logging.log4j.message;
-import org.apache.logging.log4j.util.Chars;
+import static org.apache.logging.log4j.util.Chars.LF;
+import static org.apache.logging.log4j.util.Chars.SPACE;
+
import org.apache.logging.log4j.util.StringBuilders;
/**
@@ -78,7 +80,7 @@ public int hashCode() {
*/
@Override
public void printThreadInfo(final StringBuilder sb) {
- StringBuilders.appendDqValue(sb, name).append(Chars.SPACE);
+ StringBuilders.appendDqValue(sb, name).append(SPACE);
if (isDaemon) {
sb.append("daemon ");
}
@@ -86,8 +88,8 @@ public void printThreadInfo(final StringBuilder sb) {
if (threadGroupName != null) {
StringBuilders.appendKeyDqValue(sb, "group", threadGroupName);
}
- sb.append('\n');
- sb.append("\tThread state: ").append(state.name()).append('\n');
+ sb.append(LF);
+ sb.append("\tThread state: ").append(state.name()).append(LF);
}
/**
@@ -98,7 +100,7 @@ public void printThreadInfo(final StringBuilder sb) {
@Override
public void printStack(final StringBuilder sb, final StackTraceElement[] trace) {
for (final StackTraceElement element : trace) {
- sb.append("\tat ").append(element).append('\n');
+ sb.append("\tat ").append(element).append(LF);
}
}
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/FormattedMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/FormattedMessage.java
index b936c3a5a58..2b15e355822 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/FormattedMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/FormattedMessage.java
@@ -21,7 +21,6 @@
import java.util.Arrays;
import java.util.Locale;
import java.util.Objects;
-import java.util.regex.Pattern;
/**
* Handles messages that contain a format String. This converts each message into a {@link MessageFormatMessage},
@@ -30,9 +29,6 @@
*/
public class FormattedMessage implements Message {
- private static final String FORMAT_SPECIFIER = "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])";
- private static final Pattern MSG_PATTERN = Pattern.compile(FORMAT_SPECIFIER);
-
private final String messagePattern;
private final Object[] argArray;
private String formattedMessage;
@@ -168,7 +164,27 @@ public String getFormattedMessage() {
return formattedMessage;
}
+ /**
+ * Gets the message implementation to which formatting is delegated.
+ *
+ *
+ * - if {@code msgPattern} contains {@link MessageFormat} format specifiers a {@link MessageFormatMessage}
+ * is returned,
+ * - if {@code msgPattern} contains {@code {}} placeholders a {@link ParameterizedMessage} is returned,
+ * - if {@code msgPattern} contains {@link Format} specifiers a {@link StringFormattedMessage} is returned
+ * .
+ *
+ *
+ * Mixing specifiers from multiple types is not supported.
+ *
+ *
+ * @param msgPattern The message pattern.
+ * @param args The parameters.
+ * @param aThrowable The throwable
+ * @return The message that performs formatting.
+ */
protected Message getMessage(final String msgPattern, final Object[] args, final Throwable aThrowable) {
+ // Check for valid `{ ArgumentIndex [, FormatType [, FormatStyle]] }` format specifiers
try {
final MessageFormat format = new MessageFormat(msgPattern);
final Format[] formats = format.getFormats();
@@ -178,14 +194,13 @@ protected Message getMessage(final String msgPattern, final Object[] args, final
} catch (final Exception ignored) {
// Obviously, the message is not a proper pattern for MessageFormat.
}
- try {
- if (MSG_PATTERN.matcher(msgPattern).find()) {
- return new StringFormattedMessage(locale, msgPattern, args);
- }
- } catch (final Exception ignored) {
- // Also not properly formatted.
+ // Check for non-escaped `{}` format specifiers
+ // This case also includes patterns without any `java.util.Formatter` specifiers
+ if (ParameterFormatter.analyzePattern(msgPattern, 1).placeholderCount > 0 || msgPattern.indexOf('%') == -1) {
+ return new ParameterizedMessage(msgPattern, args, aThrowable);
}
- return new ParameterizedMessage(msgPattern, args, aThrowable);
+ // Interpret as `java.util.Formatter` format
+ return new StringFormattedMessage(locale, msgPattern, args);
}
/**
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 b7b35263cb7..7a63dc5be8d 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
@@ -31,9 +31,7 @@ public class FormattedMessageFactory implements MessageFactory {
/**
* Constructs a message factory with default flow strings.
*/
- public FormattedMessageFactory() {
- super();
- }
+ public FormattedMessageFactory() {}
/**
* Creates {@link StringFormattedMessage} instances.
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/LocalizedMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/LocalizedMessage.java
index 51239cbb497..56622ddbf64 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/LocalizedMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/LocalizedMessage.java
@@ -38,7 +38,7 @@ public class LocalizedMessage implements Message, LoggerNameAwareMessage {
private final Locale locale;
- private final StatusLogger logger = StatusLogger.getLogger();
+ private static final StatusLogger logger = StatusLogger.getLogger();
private String loggerName;
private final String key;
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 aea9c1333c2..bb67efd04e3 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
@@ -68,7 +68,7 @@ public ResourceBundle getResourceBundle() {
@Override
public Message newMessage(final String key) {
if (resourceBundle == null) {
- return new LocalizedMessage(baseName, key, null);
+ return new LocalizedMessage(baseName, key);
}
return new LocalizedMessage(resourceBundle, key);
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/Message.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/Message.java
index c0b247c732e..4841983c24b 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/Message.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/Message.java
@@ -73,6 +73,11 @@ public interface Message {
*
* @return The message format. Some implementations, such as ParameterizedMessage, will use this as
* the message "pattern". Other Messages may simply return an empty String.
+ * TODO Do all messages have a format? What syntax? Using a Formatter object could be cleaner.
+ * (RG) In SimpleMessage the format is identical to the formatted message. In ParameterizedMessage and
+ * StructuredDataMessage it is not. It is up to the Message implementer to determine what this
+ * method will return. A Formatter is inappropriate as this is very specific to the Message
+ * implementation so it isn't clear to me how having a Formatter separate from the Message would be cleaner.
*/
String getFormat();
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ObjectArrayMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ObjectArrayMessage.java
index fbba8f91a04..bf6a8426763 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ObjectArrayMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ObjectArrayMessage.java
@@ -17,6 +17,7 @@
package org.apache.logging.log4j.message;
import java.util.Arrays;
+import org.apache.logging.log4j.util.Constants;
/**
* Handles messages that contain an Object[].
@@ -31,10 +32,8 @@
*/
public final class ObjectArrayMessage implements Message {
- private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
-
- private final transient Object[] array;
- private transient String arrayString;
+ private final Object[] array;
+ private String arrayString;
/**
* Creates the ObjectMessage.
@@ -43,7 +42,7 @@ public final class ObjectArrayMessage implements Message {
* The Object to format.
*/
public ObjectArrayMessage(final Object... obj) {
- this.array = obj == null ? EMPTY_OBJECT_ARRAY : obj;
+ this.array = obj == null ? Constants.EMPTY_OBJECT_ARRAY : obj;
}
private boolean equalObjectsOrStrings(final Object[] left, final Object[] right) {
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ObjectMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ObjectMessage.java
index f6b53158015..ae952cd7896 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ObjectMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ObjectMessage.java
@@ -99,7 +99,7 @@ public boolean equals(final Object o) {
}
final ObjectMessage that = (ObjectMessage) o;
- return equalObjectsOrStrings(obj, that.obj);
+ return obj == null ? that.obj == null : equalObjectsOrStrings(obj, that.obj);
}
private boolean equalObjectsOrStrings(final Object left, final Object right) {
@@ -108,7 +108,7 @@ private boolean equalObjectsOrStrings(final Object left, final Object right) {
@Override
public int hashCode() {
- return obj.hashCode();
+ return obj != null ? obj.hashCode() : 0;
}
@Override
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterFormatter.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterFormatter.java
index db88b240b92..66f8ca08643 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterFormatter.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterFormatter.java
@@ -60,325 +60,263 @@ final class ParameterFormatter {
private static final char DELIM_START = '{';
private static final char DELIM_STOP = '}';
private static final char ESCAPE_CHAR = '\\';
- private static final DateTimeFormatter FORMATTER =
+
+ private static final DateTimeFormatter DATE_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ").withZone(ZoneId.systemDefault());
private ParameterFormatter() {}
/**
- * Counts the number of unescaped placeholders in the given messagePattern.
+ * Analyzes – finds argument placeholder (i.e., {@literal "{}"}) occurrences, etc. – the given message pattern.
+ *
+ * Only {@literal "{}"} strings are treated as argument placeholders.
+ * Escaped or incomplete argument placeholders will be ignored.
+ * Some invalid argument placeholder examples:
+ *
+ *
+ * { }
+ * foo\{}
+ * {bar
+ * {buzz}
+ *
*
- * @param messagePattern the message pattern to be analyzed.
- * @return the number of unescaped placeholders.
+ * @param pattern a message pattern to be analyzed
+ * @param argCount
+ * The number of arguments to be formatted.
+ * For instance, for a parametrized message containing 7 placeholders in the pattern and 4 arguments for formatting, analysis will only need to store the index of the first 4 placeholder characters.
+ * A negative value indicates no limit.
+ * @return the analysis result
*/
- static int countArgumentPlaceholders(final String messagePattern) {
- if (messagePattern == null) {
- return 0;
- }
- final int length = messagePattern.length();
- int result = 0;
- boolean isEscaped = false;
- for (int i = 0; i < length - 1; i++) {
- final char curChar = messagePattern.charAt(i);
- if (curChar == ESCAPE_CHAR) {
- isEscaped = !isEscaped;
- } else if (curChar == DELIM_START) {
- if (!isEscaped && messagePattern.charAt(i + 1) == DELIM_STOP) {
- result++;
- i++;
- }
- isEscaped = false;
- } else {
- isEscaped = false;
- }
- }
- return result;
+ static MessagePatternAnalysis analyzePattern(final String pattern, final int argCount) {
+ MessagePatternAnalysis analysis = new MessagePatternAnalysis();
+ analyzePattern(pattern, argCount, analysis);
+ return analysis;
}
/**
- * Counts the number of unescaped placeholders in the given messagePattern.
+ * Analyzes – finds argument placeholder (i.e., {@literal "{}"}) occurrences, etc. – the given message pattern.
+ *
+ * Only {@literal "{}"} strings are treated as argument placeholders.
+ * Escaped or incomplete argument placeholders will be ignored.
+ * Some invalid argument placeholder examples:
+ *
+ *
+ * { }
+ * foo\{}
+ * {bar
+ * {buzz}
+ *
*
- * @param messagePattern the message pattern to be analyzed.
- * @return the number of unescaped placeholders.
+ * @param pattern a message pattern to be analyzed
+ * @param argCount
+ * The number of arguments to be formatted.
+ * For instance, for a parametrized message containing 7 placeholders in the pattern and 4 arguments for formatting, analysis will only need to store the index of the first 4 placeholder characters.
+ * A negative value indicates no limit.
+ * @param analysis an object to store the results
*/
- static int countArgumentPlaceholders2(final String messagePattern, final int[] indices) {
- if (messagePattern == null) {
- return 0;
+ static void analyzePattern(final String pattern, final int argCount, final MessagePatternAnalysis analysis) {
+
+ // Short-circuit if there is nothing interesting
+ final int l;
+ if (pattern == null || (l = pattern.length()) < 2) {
+ analysis.placeholderCount = 0;
+ return;
}
- final int length = messagePattern.length();
- int result = 0;
- boolean isEscaped = false;
- for (int i = 0; i < length - 1; i++) {
- final char curChar = messagePattern.charAt(i);
- if (curChar == ESCAPE_CHAR) {
- isEscaped = !isEscaped;
- indices[0] = -1; // escaping means fast path is not available...
- result++;
- } else if (curChar == DELIM_START) {
- if (!isEscaped && messagePattern.charAt(i + 1) == DELIM_STOP) {
- indices[result] = i;
- result++;
- i++;
- }
- isEscaped = false;
+
+ // Count `{}` occurrences that is not escaped, i.e., not `\`-prefixed
+ boolean escaped = false;
+ analysis.placeholderCount = 0;
+ analysis.escapedCharFound = false;
+ for (int i = 0; i < (l - 1); i++) {
+ final char c = pattern.charAt(i);
+ if (c == ESCAPE_CHAR) {
+ analysis.escapedCharFound = true;
+ escaped = !escaped;
} else {
- isEscaped = false;
+ if (escaped) {
+ escaped = false;
+ } else if (c == DELIM_START && pattern.charAt(i + 1) == DELIM_STOP) {
+ if (argCount < 0 || analysis.placeholderCount < argCount) {
+ analysis.ensurePlaceholderCharIndicesCapacity(argCount);
+ analysis.placeholderCharIndices[analysis.placeholderCount++] = i++;
+ }
+ // `argCount` is exceeded, skip storing the index
+ else {
+ analysis.placeholderCount++;
+ i++;
+ }
+ }
}
}
- return result;
}
/**
- * Counts the number of unescaped placeholders in the given messagePattern.
- *
- * @param messagePattern the message pattern to be analyzed.
- * @return the number of unescaped placeholders.
+ * @see #analyzePattern(String, int, MessagePatternAnalysis)
*/
- static int countArgumentPlaceholders3(final char[] messagePattern, final int length, final int[] indices) {
- int result = 0;
- boolean isEscaped = false;
- for (int i = 0; i < length - 1; i++) {
- final char curChar = messagePattern[i];
- if (curChar == ESCAPE_CHAR) {
- isEscaped = !isEscaped;
- } else if (curChar == DELIM_START) {
- if (!isEscaped && messagePattern[i + 1] == DELIM_STOP) {
- indices[result] = i;
- result++;
- i++;
- }
- isEscaped = false;
- } else {
- isEscaped = false;
+ static final class MessagePatternAnalysis {
+
+ /**
+ * The size of the {@link #placeholderCharIndices} buffer to be allocated if it is found to be null.
+ */
+ private static final int PLACEHOLDER_CHAR_INDEX_BUFFER_INITIAL_SIZE = 8;
+
+ /**
+ * The size {@link #placeholderCharIndices} buffer will be extended with if it has found to be insufficient.
+ */
+ private static final int PLACEHOLDER_CHAR_INDEX_BUFFER_SIZE_INCREMENT = 8;
+
+ /**
+ * The total number of argument placeholder occurrences.
+ */
+ int placeholderCount;
+
+ /**
+ * The array of indices pointing to the first character of the found argument placeholder occurrences.
+ */
+ int[] placeholderCharIndices;
+
+ /**
+ * Flag indicating if an escaped (i.e., `\`-prefixed) character is found.
+ */
+ boolean escapedCharFound;
+
+ private void ensurePlaceholderCharIndicesCapacity(final int argCount) {
+
+ // Initialize the index buffer, if necessary
+ if (placeholderCharIndices == null) {
+ final int length = Math.max(argCount, PLACEHOLDER_CHAR_INDEX_BUFFER_INITIAL_SIZE);
+ placeholderCharIndices = new int[length];
+ }
+
+ // Extend the index buffer, if necessary
+ else if (placeholderCount >= placeholderCharIndices.length) {
+ final int newLength = argCount > 0
+ ? argCount
+ : Math.addExact(placeholderCharIndices.length, PLACEHOLDER_CHAR_INDEX_BUFFER_SIZE_INCREMENT);
+ final int[] newPlaceholderCharIndices = new int[newLength];
+ System.arraycopy(placeholderCharIndices, 0, newPlaceholderCharIndices, 0, placeholderCount);
+ placeholderCharIndices = newPlaceholderCharIndices;
}
}
- return result;
}
/**
- * Replace placeholders in the given messagePattern with arguments.
+ * Format the following pattern using provided arguments.
*
- * @param messagePattern the message pattern containing placeholders.
- * @param arguments the arguments to be used to replace placeholders.
- * @return the formatted message.
+ * @param pattern a formatting pattern
+ * @param args arguments to be formatted
+ * @return the formatted message
*/
- static String format(final String messagePattern, final Object[] arguments) {
+ static String format(final String pattern, final Object[] args, int argCount) {
final StringBuilder result = new StringBuilder();
- final int argCount = arguments == null ? 0 : arguments.length;
- formatMessage(result, messagePattern, arguments, argCount);
+ final MessagePatternAnalysis analysis = analyzePattern(pattern, argCount);
+ formatMessage(result, pattern, args, argCount, analysis);
return result.toString();
}
- /**
- * Replace placeholders in the given messagePattern with arguments.
- *
- * @param buffer the buffer to write the formatted message into
- * @param messagePattern the message pattern containing placeholders.
- * @param arguments the arguments to be used to replace placeholders.
- */
- static void formatMessage2(
+ static void formatMessage(
final StringBuilder buffer,
- final String messagePattern,
- final Object[] arguments,
+ final String pattern,
+ final Object[] args,
final int argCount,
- final int[] indices) {
- if (messagePattern == null || arguments == null || argCount == 0) {
- buffer.append(messagePattern);
- return;
- }
- int previous = 0;
- for (int i = 0; i < argCount; i++) {
- buffer.append(messagePattern, previous, indices[i]);
- previous = indices[i] + 2;
- recursiveDeepToString(arguments[i], buffer);
- }
- buffer.append(messagePattern, previous, messagePattern.length());
- }
+ final MessagePatternAnalysis analysis) {
- /**
- * Replace placeholders in the given messagePattern with arguments.
- *
- * @param buffer the buffer to write the formatted message into
- * @param messagePattern the message pattern containing placeholders.
- * @param arguments the arguments to be used to replace placeholders.
- */
- static void formatMessage3(
- final StringBuilder buffer,
- final char[] messagePattern,
- final int patternLength,
- final Object[] arguments,
- final int argCount,
- final int[] indices) {
- if (messagePattern == null) {
- return;
- }
- if (arguments == null || argCount == 0) {
- buffer.append(messagePattern);
+ // Short-circuit if there is nothing interesting
+ if (pattern == null || args == null || analysis.placeholderCount == 0) {
+ buffer.append(pattern);
return;
}
- int previous = 0;
- for (int i = 0; i < argCount; i++) {
- buffer.append(messagePattern, previous, indices[i]);
- previous = indices[i] + 2;
- recursiveDeepToString(arguments[i], buffer);
- }
- buffer.append(messagePattern, previous, patternLength);
- }
- /**
- * Replace placeholders in the given messagePattern with arguments.
- *
- * @param buffer the buffer to write the formatted message into
- * @param messagePattern the message pattern containing placeholders.
- * @param arguments the arguments to be used to replace placeholders.
- */
- static void formatMessage(
- final StringBuilder buffer, final String messagePattern, final Object[] arguments, final int argCount) {
- if (messagePattern == null || arguments == null || argCount == 0) {
- buffer.append(messagePattern);
- return;
+ // Fail if there are insufficient arguments
+ if (analysis.placeholderCount > args.length) {
+ final String message = String.format(
+ "found %d argument placeholders, but provided %d for pattern `%s`",
+ analysis.placeholderCount, args.length, pattern);
+ throw new IllegalArgumentException(message);
}
- int escapeCounter = 0;
- int currentArgument = 0;
- int i = 0;
- final int len = messagePattern.length();
- for (; i < len - 1; i++) { // last char is excluded from the loop
- final char curChar = messagePattern.charAt(i);
- if (curChar == ESCAPE_CHAR) {
- escapeCounter++;
- } else {
- if (isDelimPair(curChar, messagePattern, i)) { // looks ahead one char
- i++;
- // write escaped escape chars
- writeEscapedEscapeChars(escapeCounter, buffer);
-
- if (isOdd(escapeCounter)) {
- // i.e. escaped: write escaped escape chars
- writeDelimPair(buffer);
- } else {
- // unescaped
- writeArgOrDelimPair(arguments, argCount, currentArgument, buffer);
- currentArgument++;
- }
- } else {
- handleLiteralChar(buffer, escapeCounter, curChar);
- }
- escapeCounter = 0;
- }
+ // Fast-path for patterns containing no escapes
+ if (analysis.escapedCharFound) {
+ formatMessageContainingEscapes(buffer, pattern, args, argCount, analysis);
}
- handleRemainingCharIfAny(messagePattern, len, buffer, escapeCounter, i);
- }
- /**
- * Returns {@code true} if the specified char and the char at {@code curCharIndex + 1} in the specified message
- * pattern together form a "{}" delimiter pair, returns {@code false} otherwise.
- */
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 22 bytes (allows immediate JVM inlining: < 35 bytes) LOG4J2-1096
- private static boolean isDelimPair(final char curChar, final String messagePattern, final int curCharIndex) {
- return curChar == DELIM_START && messagePattern.charAt(curCharIndex + 1) == DELIM_STOP;
+ // Slow-path for patterns containing escapes
+ else {
+ formatMessageContainingNoEscapes(buffer, pattern, args, argCount, analysis);
+ }
}
- /**
- * Detects whether the message pattern has been fully processed or if an unprocessed character remains and processes
- * it if necessary, returning the resulting position in the result char array.
- */
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 28 bytes (allows immediate JVM inlining: < 35 bytes) LOG4J2-1096
- private static void handleRemainingCharIfAny(
- final String messagePattern,
- final int len,
+ static void formatMessageContainingNoEscapes(
final StringBuilder buffer,
- final int escapeCounter,
- final int i) {
- if (i == len - 1) {
- final char curChar = messagePattern.charAt(i);
- handleLastChar(buffer, escapeCounter, curChar);
- }
- }
+ final String pattern,
+ final Object[] args,
+ final int argCount,
+ final MessagePatternAnalysis analysis) {
- /**
- * Processes the last unprocessed character and returns the resulting position in the result char array.
- */
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 28 bytes (allows immediate JVM inlining: < 35 bytes) LOG4J2-1096
- private static void handleLastChar(final StringBuilder buffer, final int escapeCounter, final char curChar) {
- if (curChar == ESCAPE_CHAR) {
- writeUnescapedEscapeChars(escapeCounter + 1, buffer);
- } else {
- handleLiteralChar(buffer, escapeCounter, curChar);
+ // Format each argument and the text preceding it
+ int precedingTextStartIndex = 0;
+ final int argLimit = Math.min(analysis.placeholderCount, argCount);
+ for (int argIndex = 0; argIndex < argLimit; argIndex++) {
+ final int placeholderCharIndex = analysis.placeholderCharIndices[argIndex];
+ buffer.append(pattern, precedingTextStartIndex, placeholderCharIndex);
+ recursiveDeepToString(args[argIndex], buffer);
+ precedingTextStartIndex = placeholderCharIndex + 2;
}
- }
-
- /**
- * Processes a literal char (neither an '\' escape char nor a "{}" delimiter pair) and returns the resulting
- * position.
- */
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 16 bytes (allows immediate JVM inlining: < 35 bytes) LOG4J2-1096
- private static void handleLiteralChar(final StringBuilder buffer, final int escapeCounter, final char curChar) {
- // any other char beside ESCAPE or DELIM_START/STOP-combo
- // write unescaped escape chars
- writeUnescapedEscapeChars(escapeCounter, buffer);
- buffer.append(curChar);
- }
-
- /**
- * Writes "{}" to the specified result array at the specified position and returns the resulting position.
- */
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 18 bytes (allows immediate JVM inlining: < 35 bytes) LOG4J2-1096
- private static void writeDelimPair(final StringBuilder buffer) {
- buffer.append(DELIM_START);
- buffer.append(DELIM_STOP);
- }
- /**
- * Returns {@code true} if the specified parameter is odd.
- */
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 11 bytes (allows immediate JVM inlining: < 35 bytes) LOG4J2-1096
- private static boolean isOdd(final int number) {
- return (number & 1) == 1;
- }
-
- /**
- * Writes a '\' char to the specified result array (starting at the specified position) for each pair of
- * '\' escape chars encountered in the message format and returns the resulting position.
- */
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 11 bytes (allows immediate JVM inlining: < 35 bytes) LOG4J2-1096
- private static void writeEscapedEscapeChars(final int escapeCounter, final StringBuilder buffer) {
- final int escapedEscapes = escapeCounter >> 1; // divide by two
- writeUnescapedEscapeChars(escapedEscapes, buffer);
+ // Format the last trailing text
+ buffer.append(pattern, precedingTextStartIndex, pattern.length());
}
- /**
- * Writes the specified number of '\' chars to the specified result array (starting at the specified position) and
- * returns the resulting position.
- */
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 20 bytes (allows immediate JVM inlining: < 35 bytes) LOG4J2-1096
- private static void writeUnescapedEscapeChars(int escapeCounter, final StringBuilder buffer) {
- while (escapeCounter > 0) {
- buffer.append(ESCAPE_CHAR);
- escapeCounter--;
- }
- }
-
- /**
- * Appends the argument at the specified argument index (or, if no such argument exists, the "{}" delimiter pair) to
- * the specified result char array at the specified position and returns the resulting position.
- */
- // Profiling showed this method is important to log4j performance. Modify with care!
- // 25 bytes (allows immediate JVM inlining: < 35 bytes) LOG4J2-1096
- private static void writeArgOrDelimPair(
- final Object[] arguments, final int argCount, final int currentArgument, final StringBuilder buffer) {
- if (currentArgument < argCount) {
- recursiveDeepToString(arguments[currentArgument], buffer);
- } else {
- writeDelimPair(buffer);
+ static void formatMessageContainingEscapes(
+ final StringBuilder buffer,
+ final String pattern,
+ final Object[] args,
+ final int argCount,
+ final MessagePatternAnalysis analysis) {
+
+ // Format each argument and the text preceding it
+ int precedingTextStartIndex = 0;
+ final int argLimit = Math.min(analysis.placeholderCount, argCount);
+ for (int argIndex = 0; argIndex < argLimit; argIndex++) {
+ final int placeholderCharIndex = analysis.placeholderCharIndices[argIndex];
+ copyMessagePatternContainingEscapes(buffer, pattern, precedingTextStartIndex, placeholderCharIndex);
+ recursiveDeepToString(args[argIndex], buffer);
+ precedingTextStartIndex = placeholderCharIndex + 2;
+ }
+
+ // Format the last trailing text
+ copyMessagePatternContainingEscapes(buffer, pattern, precedingTextStartIndex, pattern.length());
+ }
+
+ private static void copyMessagePatternContainingEscapes(
+ final StringBuilder buffer, final String pattern, final int startIndex, final int endIndex) {
+ boolean escaped = false;
+ int i = startIndex;
+ for (; i < endIndex; i++) {
+ final char c = pattern.charAt(i);
+ if (c == ESCAPE_CHAR) {
+ if (escaped) {
+ // Found an escaped `\`, skip appending it
+ escaped = false;
+ } else {
+ escaped = true;
+ buffer.append(c);
+ }
+ } else {
+ if (escaped) {
+ if (c == DELIM_START && pattern.charAt(i + 1) == DELIM_STOP) {
+ // Found an escaped placeholder, override the earlier appended `\`
+ buffer.setLength(buffer.length() - 1);
+ buffer.append("{}");
+ i++;
+ } else {
+ buffer.append(c);
+ }
+ escaped = false;
+ } else {
+ buffer.append(c);
+ }
+ }
}
}
@@ -499,7 +437,7 @@ private static boolean appendDate(final Object o, final StringBuilder str) {
if (!(o instanceof Date)) {
return false;
}
- str.append(FORMATTER.format(((Date) o).toInstant()));
+ str.append(DATE_FORMATTER.format(((Date) o).toInstant()));
return true;
}
@@ -579,15 +517,14 @@ private static void appendMap(final Object o, final StringBuilder str, final Set
final Map, ?> oMap = (Map, ?>) o;
str.append('{');
boolean isFirst = true;
- for (final Object o1 : oMap.entrySet()) {
- final Map.Entry, ?> current = (Map.Entry, ?>) o1;
+ for (final Map.Entry, ?> entry : oMap.entrySet()) {
if (isFirst) {
isFirst = false;
} else {
str.append(", ");
}
- final Object key = current.getKey();
- final Object value = current.getValue();
+ final Object key = entry.getKey();
+ final Object value = entry.getValue();
recursiveDeepToString(key, str, cloneDejaVu(effectiveDejaVu));
str.append('=');
recursiveDeepToString(value, str, cloneDejaVu(effectiveDejaVu));
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedMessage.java
index aae12e6f374..69bce67c14a 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterizedMessage.java
@@ -16,19 +16,32 @@
*/
package org.apache.logging.log4j.message;
+import static org.apache.logging.log4j.message.ParameterFormatter.analyzePattern;
+
import java.util.Arrays;
import java.util.Objects;
+import org.apache.logging.log4j.message.ParameterFormatter.MessagePatternAnalysis;
import org.apache.logging.log4j.spi.LoggingSystem;
import org.apache.logging.log4j.spi.recycler.Recycler;
import org.apache.logging.log4j.util.StringBuilderFormattable;
import org.apache.logging.log4j.util.StringBuilders;
/**
- * Handles messages that consist of a format string containing '{}' to represent each replaceable token, and
- * the parameters.
+ * A {@link Message} accepting argument placeholders in the formatting pattern.
+ *
+ * Only {@literal "{}"} strings are treated as argument placeholders.
+ * Escaped (i.e., {@code "\"}-prefixed) or incomplete argument placeholders will be ignored.
+ * Examples of argument placeholders that will be discarded and rendered intact:
+ *
+ *
+ * { }
+ * foo\{}
+ * {bar
+ * {buzz}
+ *
*
- * This class was originally written for Lilith by Joern Huxhorn where it is
- * licensed under the LGPL. It has been relicensed here with his permission providing that this attribution remain.
+ * This class was originally written for Lilith by Jörn Huxhorn and licensed under the LGPL.
+ * It has been relicensed here with his permission providing that this attribution remain.
*
*/
public class ParameterizedMessage implements Message, StringBuilderFormattable {
@@ -36,141 +49,127 @@ public class ParameterizedMessage implements Message, StringBuilderFormattable {
// Should this be configurable?
private static final int DEFAULT_STRING_BUILDER_SIZE = 255;
- /**
- * Prefix for recursion.
- */
- public static final String RECURSION_PREFIX = ParameterFormatter.RECURSION_PREFIX;
- /**
- * Suffix for recursion.
- */
- public static final String RECURSION_SUFFIX = ParameterFormatter.RECURSION_SUFFIX;
-
- /**
- * Prefix for errors.
- */
- public static final String ERROR_PREFIX = ParameterFormatter.ERROR_PREFIX;
-
- /**
- * Separator for errors.
- */
- public static final String ERROR_SEPARATOR = ParameterFormatter.ERROR_SEPARATOR;
-
- /**
- * Separator for error messages.
- */
- public static final String ERROR_MSG_SEPARATOR = ParameterFormatter.ERROR_MSG_SEPARATOR;
-
- /**
- * Suffix for errors.
- */
- public static final String ERROR_SUFFIX = ParameterFormatter.ERROR_SUFFIX;
-
private static final Recycler STRING_BUILDER_RECYCLER = LoggingSystem.getRecyclerFactory()
.create(() -> new StringBuilder(DEFAULT_STRING_BUILDER_SIZE), stringBuilder -> {
StringBuilders.trimToMaxSize(stringBuilder, DEFAULT_STRING_BUILDER_SIZE);
stringBuilder.setLength(0);
});
- private String messagePattern;
- private final Object[] argArray;
+ private final String pattern;
+
+ private final transient Object[] args;
+
+ private final transient Throwable throwable;
+
+ private final MessagePatternAnalysis patternAnalysis;
private String formattedMessage;
- private Throwable throwable;
- private int[] indices;
- private int usedCount;
/**
- * Creates a parameterized message.
- * @param messagePattern The message "format" string. This will be a String containing "{}" placeholders
- * where parameters should be substituted.
- * @param arguments The arguments for substitution.
- * @param throwable A Throwable.
+ * Constructs an instance.
+ *
+ * The {@link Throwable} associated with the message (and returned in {@link #getThrowable()}) will be determined as follows:
+ *
+ *
+ * - If a {@code throwable} argument is provided
+ * - If the last argument is a {@link Throwable} and is not referred to by any placeholder in the pattern
+ *
+ *
+ * @param pattern a formatting pattern
+ * @param args arguments to be formatted
+ * @param throwable a {@link Throwable}
*/
- public ParameterizedMessage(final String messagePattern, final Object[] arguments, final Throwable throwable) {
- this.argArray = arguments;
- this.throwable = throwable;
- init(messagePattern);
+ public ParameterizedMessage(final String pattern, final Object[] args, final Throwable throwable) {
+ this.args = args;
+ this.pattern = pattern;
+ this.patternAnalysis = analyzePattern(pattern, args != null ? args.length : 0);
+ this.throwable = determineThrowable(throwable, this.args, patternAnalysis);
+ }
+
+ private static Throwable determineThrowable(
+ final Throwable throwable, final Object[] args, final MessagePatternAnalysis analysis) {
+
+ // Short-circuit if an explicit `Throwable` is provided
+ if (throwable != null) {
+ return throwable;
+ }
+
+ // If the last `Throwable` argument is not consumed in the pattern, use that
+ if (args != null && args.length > analysis.placeholderCount) {
+ Object lastArg = args[args.length - 1];
+ if (lastArg instanceof Throwable) {
+ return (Throwable) lastArg;
+ }
+ }
+
+ // No `Throwable`s available
+ return null;
}
/**
- * Constructs a ParameterizedMessage which contains the arguments converted to String as well as an optional
- * Throwable.
- *
- * If the last argument is a Throwable and is NOT used up by a placeholder in the message pattern it is returned
- * in {@link #getThrowable()} and won't be contained in the created String[].
- * If it is used up {@link #getThrowable()} will return null even if the last argument was a Throwable!
+ * Constructor with a pattern and multiple arguments.
+ *
+ * If the last argument is a {@link Throwable} and is not referred to by any placeholder in the pattern, it is returned in {@link #getThrowable()}.
+ *
*
- * @param messagePattern the message pattern that to be checked for placeholders.
- * @param arguments the argument array to be converted.
+ * @param pattern a formatting pattern
+ * @param args arguments to be formatted
*/
- public ParameterizedMessage(final String messagePattern, final Object... arguments) {
- this.argArray = arguments;
- init(messagePattern);
+ public ParameterizedMessage(final String pattern, final Object... args) {
+ this(pattern, args, null);
}
/**
- * Constructor with a pattern and a single parameter.
- * @param messagePattern The message pattern.
- * @param arg The parameter.
+ * Constructor with a pattern and a single argument.
+ *
+ * If the argument is a {@link Throwable} and is not referred to by any placeholder in the pattern, it is returned in {@link #getThrowable()}.
+ *
+ *
+ * @param pattern a formatting pattern
+ * @param arg an argument
*/
- public ParameterizedMessage(final String messagePattern, final Object arg) {
- this(messagePattern, new Object[] {arg});
+ public ParameterizedMessage(final String pattern, final Object arg) {
+ this(pattern, new Object[] {arg});
}
/**
- * Constructor with a pattern and two parameters.
- * @param messagePattern The message pattern.
- * @param arg0 The first parameter.
- * @param arg1 The second parameter.
+ * Constructor with a pattern and two arguments.
+ *
+ * If the last argument is a {@link Throwable} and is not referred to by any placeholder in the pattern, it is returned in {@link #getThrowable()} and won't be contained in the formatted message.
+ *
+ *
+ * @param pattern a formatting pattern
+ * @param arg0 the first argument
+ * @param arg1 the second argument
*/
- public ParameterizedMessage(final String messagePattern, final Object arg0, final Object arg1) {
- this(messagePattern, new Object[] {arg0, arg1});
- }
-
- private void init(final String messagePattern) {
- this.messagePattern = messagePattern;
- final int len = Math.max(1, messagePattern == null ? 0 : messagePattern.length() >> 1); // divide by 2
- this.indices = new int[len]; // LOG4J2-1542 ensure non-zero array length
- final int placeholders = ParameterFormatter.countArgumentPlaceholders2(messagePattern, indices);
- initThrowable(argArray, placeholders);
- this.usedCount = Math.min(placeholders, argArray == null ? 0 : argArray.length);
- }
-
- private void initThrowable(final Object[] params, final int usedParams) {
- if (params != null) {
- final int argCount = params.length;
- if (usedParams < argCount && this.throwable == null && params[argCount - 1] instanceof Throwable) {
- this.throwable = (Throwable) params[argCount - 1];
- }
- }
+ public ParameterizedMessage(final String pattern, final Object arg0, final Object arg1) {
+ this(pattern, new Object[] {arg0, arg1});
}
/**
- * Returns the message pattern.
- * @return the message pattern.
+ * @return the message formatting pattern
*/
@Override
public String getFormat() {
- return messagePattern;
+ return pattern;
}
/**
- * Returns the message parameters.
- * @return the message parameters.
+ * @return the message arguments
*/
@Override
public Object[] getParameters() {
- return argArray;
+ return args;
}
/**
- * Returns the Throwable that was given as the last argument, if any.
- * It will not survive serialization. The Throwable exists as part of the message
- * primarily so that it can be extracted from the end of the list of parameters
- * and then be added to the LogEvent. As such, the Throwable in the event should
- * not be used once the LogEvent has been constructed.
+ * The {@link Throwable} provided along with the message by one of the following means:
+ *
+ * - explicitly in the constructor
+ * - as the last message argument that is not referred to by any placeholder in the formatting pattern
+ *
*
- * @return the Throwable, if any.
+ * @return the {@link Throwable} provided along with the message
*/
@Override
public Throwable getThrowable() {
@@ -179,7 +178,11 @@ public Throwable getThrowable() {
/**
* Returns the formatted message.
- * @return the formatted message.
+ *
+ * If possible, the result will be cached for subsequent invocations.
+ *
+ *
+ * @return the formatted message
*/
@Override
public String getFormattedMessage() {
@@ -200,23 +203,19 @@ public void formatTo(final StringBuilder buffer) {
if (formattedMessage != null) {
buffer.append(formattedMessage);
} else {
- if (indices[0] < 0) {
- ParameterFormatter.formatMessage(buffer, messagePattern, argArray, usedCount);
- } else {
- ParameterFormatter.formatMessage2(buffer, messagePattern, argArray, usedCount, indices);
- }
+ final int argCount = args != null ? args.length : 0;
+ ParameterFormatter.formatMessage(buffer, pattern, args, argCount, patternAnalysis);
}
}
/**
- * Replace placeholders in the given messagePattern with arguments.
- *
- * @param messagePattern the message pattern containing placeholders.
- * @param arguments the arguments to be used to replace placeholders.
- * @return the formatted message.
+ * @param pattern a message pattern containing argument placeholders
+ * @param args arguments to be used to replace placeholders
+ * @return the formatted message
*/
- public static String format(final String messagePattern, final Object[] arguments) {
- return ParameterFormatter.format(messagePattern, arguments);
+ public static String format(final String pattern, final Object[] args) {
+ final int argCount = args != null ? args.length : 0;
+ return ParameterFormatter.format(pattern, args, argCount);
}
@Override
@@ -224,26 +223,29 @@ public boolean equals(final Object object) {
if (this == object) {
return true;
}
- if (!(object instanceof ParameterizedMessage)) {
+ if (object == null || getClass() != object.getClass()) {
return false;
}
final ParameterizedMessage that = (ParameterizedMessage) object;
- return Objects.equals(this.messagePattern, that.messagePattern) && Arrays.equals(this.argArray, that.argArray);
+ return Objects.equals(pattern, that.pattern) && Arrays.equals(args, that.args);
}
@Override
public int hashCode() {
- int result = Objects.hash(messagePattern);
- result = 31 * result + Arrays.hashCode(argArray);
+ int result = pattern != null ? pattern.hashCode() : 0;
+ result = 31 * result + (args != null ? Arrays.hashCode(args) : 0);
return result;
}
/**
- * Returns the number of argument placeholders.
- * @param messagePattern the message pattern to be analyzed
+ * @param pattern the message pattern to be analyzed
+ * @return the number of argument placeholders
*/
- public static int countArgumentPlaceholders(final String messagePattern) {
- return ParameterFormatter.countArgumentPlaceholders(messagePattern);
+ public static int countArgumentPlaceholders(final String pattern) {
+ if (pattern == null) {
+ return 0;
+ }
+ return analyzePattern(pattern, -1).placeholderCount;
}
/**
@@ -294,7 +296,7 @@ public static String identityToString(final Object obj) {
@Override
public String toString() {
- return "ParameterizedMessage[messagePattern=" + messagePattern + ", stringArgs=" + Arrays.toString(argArray)
+ return "ParameterizedMessage[messagePattern=" + pattern + ", stringArgs=" + Arrays.toString(args)
+ ", throwable=" + throwable + ']';
}
}
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 225eecc78b3..6d58644bf68 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
@@ -78,9 +78,7 @@ public Throwable getThrowable() {
/**
* Constructs a message factory with default flow strings.
*/
- public ParameterizedNoReferenceMessageFactory() {
- super();
- }
+ public ParameterizedNoReferenceMessageFactory() {}
/**
* Instance of ParameterizedStatusMessageFactory.
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 3b71f2896ff..6ec36d5308a 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
@@ -65,7 +65,7 @@ public ReusableMessageFactory(final RecyclerFactory recyclerFactory) {
* @param message the message to make available again
* @since 2.7
*/
- @SuppressWarnings("deprecation")
+ @SuppressWarnings("removal")
public static void release(final Message message) { // LOG4J2-1583
if (message instanceof ReusableMessage) {
((ReusableMessage) message).clear();
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java
index 928e201f1bc..db209f866df 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java
@@ -17,6 +17,7 @@
package org.apache.logging.log4j.message;
import java.util.Arrays;
+import org.apache.logging.log4j.message.ParameterFormatter.MessagePatternAnalysis;
import org.apache.logging.log4j.spi.LoggingSystem;
import org.apache.logging.log4j.spi.recycler.Recycler;
import org.apache.logging.log4j.spi.recycler.RecyclerFactory;
@@ -35,14 +36,13 @@
public class ReusableParameterizedMessage implements ReusableMessage, ParameterVisitable {
private static final int MIN_BUILDER_SIZE = 512;
- private static final int MAX_PARMS = 10;
+ private static final int MAX_PARAMS = 10;
private String messagePattern;
+ private final MessagePatternAnalysis patternAnalysis = new MessagePatternAnalysis();
private int argCount;
- private int usedCount;
- private final int[] indices = new int[256];
private Object[] varargs;
- private Object[] params = new Object[MAX_PARMS];
+ private Object[] params = new Object[MAX_PARAMS];
private Throwable throwable;
private final Recycler bufferRecycler;
@@ -58,7 +58,7 @@ public ReusableParameterizedMessage(final RecyclerFactory recyclerFactory) {
bufferRecycler = recyclerFactory.create(
() -> {
final int currentPatternLength = messagePattern == null ? 0 : messagePattern.length();
- int capacity = Math.max(MIN_BUILDER_SIZE, Math.multiplyExact(currentPatternLength, 2));
+ final int capacity = Math.max(MIN_BUILDER_SIZE, Math.multiplyExact(currentPatternLength, 2));
return new StringBuilder(capacity);
},
buffer -> {
@@ -81,22 +81,20 @@ public Object[] swapParameters(final Object[] emptyReplacement) {
Object[] result;
if (varargs == null) {
result = params;
- if (emptyReplacement.length >= MAX_PARMS) {
+ if (emptyReplacement.length >= MAX_PARAMS) {
params = emptyReplacement;
- } else {
+ } else if (argCount <= emptyReplacement.length) {
// Bad replacement! Too small, may blow up future 10-arg messages.
- if (argCount <= emptyReplacement.length) {
- // copy params into the specified replacement array and return that
- System.arraycopy(params, 0, emptyReplacement, 0, argCount);
- // Do not retain references to objects in the reusable params array.
- for (int i = 0; i < argCount; i++) {
- params[i] = null;
- }
- result = emptyReplacement;
- } else {
- // replacement array is too small for current content and future content: discard it
- params = new Object[MAX_PARMS];
+ // copy params into the specified replacement array and return that
+ System.arraycopy(params, 0, emptyReplacement, 0, argCount);
+ // Do not retain references to objects in the reusable params array.
+ for (int i = 0; i < argCount; i++) {
+ params[i] = null;
}
+ result = emptyReplacement;
+ } else {
+ // replacement array is too small for current content and future content: discard it
+ params = new Object[MAX_PARAMS];
}
} else {
// The returned array will be reused by the caller in future swapParameter() calls.
@@ -105,7 +103,7 @@ public Object[] swapParameters(final Object[] emptyReplacement) {
// and return it. This helps the caller to retain a reusable array of at least 10 elements.
// NOTE: LOG4J2-1688 unearthed the use case that an application array (not a varargs array) is passed
// as the argument array. This array should not be modified, so it cannot be passed to the caller
- // who will at some point null out the elements in the array).
+ // who will at some point null out the elements in the array.
if (argCount <= emptyReplacement.length) {
result = emptyReplacement;
} else {
@@ -136,53 +134,44 @@ public Message memento() {
return new ParameterizedMessage(messagePattern, getTrimmedParams());
}
- private void init(final String messagePattern, final int argCount, final Object[] paramArray) {
+ private void init(final String messagePattern, final int argCount, final Object[] args) {
this.varargs = null;
this.messagePattern = messagePattern;
this.argCount = argCount;
- final int placeholderCount = count(messagePattern, indices);
- initThrowable(paramArray, argCount, placeholderCount);
- this.usedCount = Math.min(placeholderCount, argCount);
- }
-
- private static int count(final String messagePattern, final int[] indices) {
- try {
- // try the fast path first
- return ParameterFormatter.countArgumentPlaceholders2(messagePattern, indices);
- } catch (final Exception ex) { // fallback if more than int[] length (256) parameter placeholders
- return ParameterFormatter.countArgumentPlaceholders(messagePattern);
- }
+ ParameterFormatter.analyzePattern(messagePattern, argCount, patternAnalysis);
+ this.throwable = determineThrowable(args, argCount, patternAnalysis.placeholderCount);
}
- private void initThrowable(final Object[] params, final int argCount, final int usedParams) {
- if (usedParams < argCount && params[argCount - 1] instanceof Throwable) {
- this.throwable = (Throwable) params[argCount - 1];
- } else {
- this.throwable = null;
+ private static Throwable determineThrowable(final Object[] args, final int argCount, final int placeholderCount) {
+ if (placeholderCount < argCount) {
+ final Object lastArg = args[argCount - 1];
+ if (lastArg instanceof Throwable) {
+ return (Throwable) lastArg;
+ }
}
+ return null;
}
- protected ReusableParameterizedMessage set(final String messagePattern, final Object... arguments) {
+ ReusableParameterizedMessage set(final String messagePattern, final Object... arguments) {
init(messagePattern, arguments == null ? 0 : arguments.length, arguments);
varargs = arguments;
return this;
}
- protected ReusableParameterizedMessage set(final String messagePattern, final Object p0) {
+ ReusableParameterizedMessage set(final String messagePattern, final Object p0) {
params[0] = p0;
init(messagePattern, 1, params);
return this;
}
- protected ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1) {
+ ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1) {
params[0] = p0;
params[1] = p1;
init(messagePattern, 2, params);
return this;
}
- protected ReusableParameterizedMessage set(
- final String messagePattern, final Object p0, final Object p1, final Object p2) {
+ ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2) {
params[0] = p0;
params[1] = p1;
params[2] = p2;
@@ -190,7 +179,7 @@ protected ReusableParameterizedMessage set(
return this;
}
- protected ReusableParameterizedMessage set(
+ ReusableParameterizedMessage set(
final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3) {
params[0] = p0;
params[1] = p1;
@@ -200,7 +189,7 @@ protected ReusableParameterizedMessage set(
return this;
}
- protected ReusableParameterizedMessage set(
+ ReusableParameterizedMessage set(
final String messagePattern,
final Object p0,
final Object p1,
@@ -216,7 +205,7 @@ protected ReusableParameterizedMessage set(
return this;
}
- protected ReusableParameterizedMessage set(
+ ReusableParameterizedMessage set(
final String messagePattern,
final Object p0,
final Object p1,
@@ -234,7 +223,7 @@ protected ReusableParameterizedMessage set(
return this;
}
- protected ReusableParameterizedMessage set(
+ ReusableParameterizedMessage set(
final String messagePattern,
final Object p0,
final Object p1,
@@ -254,7 +243,7 @@ protected ReusableParameterizedMessage set(
return this;
}
- protected ReusableParameterizedMessage set(
+ ReusableParameterizedMessage set(
final String messagePattern,
final Object p0,
final Object p1,
@@ -276,7 +265,7 @@ protected ReusableParameterizedMessage set(
return this;
}
- protected ReusableParameterizedMessage set(
+ ReusableParameterizedMessage set(
final String messagePattern,
final Object p0,
final Object p1,
@@ -300,7 +289,7 @@ protected ReusableParameterizedMessage set(
return this;
}
- protected ReusableParameterizedMessage set(
+ ReusableParameterizedMessage set(
final String messagePattern,
final Object p0,
final Object p1,
@@ -375,11 +364,7 @@ public String getFormattedMessage() {
@Override
public void formatTo(final StringBuilder builder) {
- if (indices[0] < 0) {
- ParameterFormatter.formatMessage(builder, messagePattern, getParams(), argCount);
- } else {
- ParameterFormatter.formatMessage2(builder, messagePattern, getParams(), usedCount, indices);
- }
+ ParameterFormatter.formatMessage(builder, messagePattern, getParams(), argCount, patternAnalysis);
}
@Override
@@ -395,5 +380,11 @@ public void clear() { // LOG4J2-1583
varargs = null;
messagePattern = null;
throwable = null;
+ // Cut down on the memory usage after an analysis with an excessive argument count
+ final int placeholderCharIndicesMaxLength = 16;
+ if (patternAnalysis.placeholderCharIndices != null
+ && patternAnalysis.placeholderCharIndices.length > placeholderCharIndicesMaxLength) {
+ patternAnalysis.placeholderCharIndices = new int[placeholderCharIndicesMaxLength];
+ }
}
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableSimpleMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableSimpleMessage.java
index 88712bb5fef..bdf775b92bb 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableSimpleMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableSimpleMessage.java
@@ -24,7 +24,6 @@
*/
@PerformanceSensitive("allocation")
public class ReusableSimpleMessage implements ReusableMessage, CharSequence, ParameterVisitable {
- private static final Object[] EMPTY_PARAMS = new Object[0];
private CharSequence charSequence;
public void set(final String message) {
@@ -47,7 +46,7 @@ public String getFormat() {
@Override
public Object[] getParameters() {
- return EMPTY_PARAMS;
+ return Constants.EMPTY_OBJECT_ARRAY;
}
@Override
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 ad1e56fda5b..6cb17092e17 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
@@ -17,7 +17,8 @@
package org.apache.logging.log4j.message;
/**
- * Creates {@link FormattedMessage} instances for {@link MessageFactory} methods.
+ * Creates {@link FormattedMessage} instances for {@link MessageFactory2} methods (and {@link MessageFactory} by
+ * extension.)
*
* This uses is the simplest possible implementation of {@link Message}, the where you give the message to the
* constructor argument as a String.
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 7096b4d3694..7ce4296ba57 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
@@ -44,9 +44,7 @@ public final class StringFormatterMessageFactory implements MessageFactory {
/**
* Constructs a message factory with default flow strings.
*/
- public StringFormatterMessageFactory() {
- super();
- }
+ public StringFormatterMessageFactory() {}
/**
* Creates {@link StringFormattedMessage} instances.
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ThreadDumpMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ThreadDumpMessage.java
index b0d699f69c0..31bcf595478 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ThreadDumpMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ThreadDumpMessage.java
@@ -16,6 +16,8 @@
*/
package org.apache.logging.log4j.message;
+import static org.apache.logging.log4j.util.Chars.LF;
+
import aQute.bnd.annotation.Cardinality;
import aQute.bnd.annotation.Resolution;
import aQute.bnd.annotation.spi.ServiceConsumer;
@@ -41,6 +43,7 @@ public class ThreadDumpMessage implements Message, StringBuilderFormattable {
private final Map threads;
private final String title;
+ private String formattedMessage;
/**
* Generate a ThreadDumpMessage with a title.
@@ -62,6 +65,9 @@ public String toString() {
*/
@Override
public String getFormattedMessage() {
+ if (formattedMessage != null) {
+ return formattedMessage;
+ }
final StringBuilder sb = new StringBuilder(255);
formatTo(sb);
return sb.toString();
@@ -70,14 +76,14 @@ public String getFormattedMessage() {
@Override
public void formatTo(final StringBuilder sb) {
sb.append(title);
- if (!title.isEmpty()) {
- sb.append('\n');
+ if (title.length() > 0) {
+ sb.append(LF);
}
for (final Map.Entry entry : threads.entrySet()) {
final ThreadInformation info = entry.getKey();
info.printThreadInfo(sb);
info.printStack(sb, entry.getValue());
- sb.append('\n');
+ sb.append(LF);
}
}
@@ -106,7 +112,7 @@ public Object[] getParameters() {
* Implementations of this class are loaded via the standard java Service Provider interface.
*
*/
- public interface ThreadInfoFactory {
+ public static interface ThreadInfoFactory {
Map createThreadInfo();
}
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 5dd788c06b1..f5210e1452e 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
@@ -30,7 +30,6 @@
import org.apache.logging.log4j.spi.recycler.Recycler;
import org.apache.logging.log4j.spi.recycler.RecyclerFactory;
import org.apache.logging.log4j.status.StatusLogger;
-import org.apache.logging.log4j.util.Cast;
import org.apache.logging.log4j.util.LambdaUtil;
import org.apache.logging.log4j.util.MessageSupplier;
import org.apache.logging.log4j.util.PerformanceSensitive;
@@ -169,8 +168,8 @@ public static void checkMessageFactory(final ExtendedLogger logger, final Messag
}
@Override
- public void catching(final Level level, final Throwable t) {
- catching(FQCN, level, t);
+ public void catching(final Level level, final Throwable throwable) {
+ catching(FQCN, level, throwable);
}
/**
@@ -178,22 +177,22 @@ public void catching(final Level level, final Throwable t) {
*
* @param fqcn The fully qualified class name of the caller.
* @param level The logging level.
- * @param t The Throwable.
+ * @param throwable The Throwable.
*/
- protected void catching(final String fqcn, final Level level, final Throwable t) {
+ protected void catching(final String fqcn, final Level level, final Throwable throwable) {
if (isEnabled(level, CATCHING_MARKER, (Object) null, null)) {
- logMessageSafely(fqcn, level, CATCHING_MARKER, catchingMsg(t), t);
+ logMessageSafely(fqcn, level, CATCHING_MARKER, catchingMsg(throwable), throwable);
}
}
@Override
- public void catching(final Throwable t) {
+ public void catching(final Throwable throwable) {
if (isEnabled(Level.ERROR, CATCHING_MARKER, (Object) null, null)) {
- logMessageSafely(FQCN, Level.ERROR, CATCHING_MARKER, catchingMsg(t), t);
+ logMessageSafely(FQCN, Level.ERROR, CATCHING_MARKER, catchingMsg(throwable), throwable);
}
}
- protected Message catchingMsg(final Throwable t) {
+ protected Message catchingMsg(final Throwable throwable) {
return messageFactory.newMessage(CATCHING);
}
@@ -203,18 +202,18 @@ public void debug(final Marker marker, final CharSequence message) {
}
@Override
- public void debug(final Marker marker, final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, Level.DEBUG, marker, message, t);
+ public void debug(final Marker marker, final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.DEBUG, marker, message, throwable);
}
@Override
- public void debug(final Marker marker, final Message msg) {
- logIfEnabled(FQCN, Level.DEBUG, marker, msg, msg != null ? msg.getThrowable() : null);
+ public void debug(final Marker marker, final Message message) {
+ logIfEnabled(FQCN, Level.DEBUG, marker, message, message != null ? message.getThrowable() : null);
}
@Override
- public void debug(final Marker marker, final Message msg, final Throwable t) {
- logIfEnabled(FQCN, Level.DEBUG, marker, msg, t);
+ public void debug(final Marker marker, final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.DEBUG, marker, message, throwable);
}
@Override
@@ -223,8 +222,8 @@ public void debug(final Marker marker, final Object message) {
}
@Override
- public void debug(final Marker marker, final Object message, final Throwable t) {
- logIfEnabled(FQCN, Level.DEBUG, marker, message, t);
+ public void debug(final Marker marker, final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.DEBUG, marker, message, throwable);
}
@Override
@@ -238,18 +237,18 @@ public void debug(final Marker marker, final String message, final Object... par
}
@Override
- public void debug(final Marker marker, final String message, final Throwable t) {
- logIfEnabled(FQCN, Level.DEBUG, marker, message, t);
+ public void debug(final Marker marker, final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.DEBUG, marker, message, throwable);
}
@Override
- public void debug(final Message msg) {
- logIfEnabled(FQCN, Level.DEBUG, null, msg, msg != null ? msg.getThrowable() : null);
+ public void debug(final Message message) {
+ logIfEnabled(FQCN, Level.DEBUG, null, message, message != null ? message.getThrowable() : null);
}
@Override
- public void debug(final Message msg, final Throwable t) {
- logIfEnabled(FQCN, Level.DEBUG, null, msg, t);
+ public void debug(final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.DEBUG, null, message, throwable);
}
@Override
@@ -258,8 +257,8 @@ public void debug(final CharSequence message) {
}
@Override
- public void debug(final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, Level.DEBUG, null, message, t);
+ public void debug(final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.DEBUG, null, message, throwable);
}
@Override
@@ -268,8 +267,8 @@ public void debug(final Object message) {
}
@Override
- public void debug(final Object message, final Throwable t) {
- logIfEnabled(FQCN, Level.DEBUG, null, message, t);
+ public void debug(final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.DEBUG, null, message, throwable);
}
@Override
@@ -283,8 +282,8 @@ public void debug(final String message, final Object... params) {
}
@Override
- public void debug(final String message, final Throwable t) {
- logIfEnabled(FQCN, Level.DEBUG, null, message, t);
+ public void debug(final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.DEBUG, null, message, throwable);
}
@Override
@@ -324,23 +323,23 @@ public void debug(final String message, final Supplier>... paramSuppliers) {
}
@Override
- public void debug(final Marker marker, final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, Level.DEBUG, marker, msgSupplier, (Throwable) null);
+ public void debug(final Marker marker, final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, Level.DEBUG, marker, messageSupplier, (Throwable) null);
}
@Override
- public void debug(final Marker marker, final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, Level.DEBUG, marker, msgSupplier, t);
+ public void debug(final Marker marker, final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.DEBUG, marker, messageSupplier, throwable);
}
@Override
- public void debug(final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, Level.DEBUG, null, msgSupplier, (Throwable) null);
+ public void debug(final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, Level.DEBUG, null, messageSupplier, (Throwable) null);
}
@Override
- public void debug(final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, Level.DEBUG, null, msgSupplier, t);
+ public void debug(final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.DEBUG, null, messageSupplier, throwable);
}
@Override
@@ -648,13 +647,13 @@ protected EntryMessage entryMsg(final String format, final Supplier>... paramS
}
@Override
- public void error(final Marker marker, final Message msg) {
- logIfEnabled(FQCN, Level.ERROR, marker, msg, msg != null ? msg.getThrowable() : null);
+ public void error(final Marker marker, final Message message) {
+ logIfEnabled(FQCN, Level.ERROR, marker, message, message != null ? message.getThrowable() : null);
}
@Override
- public void error(final Marker marker, final Message msg, final Throwable t) {
- logIfEnabled(FQCN, Level.ERROR, marker, msg, t);
+ public void error(final Marker marker, final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.ERROR, marker, message, throwable);
}
@Override
@@ -663,8 +662,8 @@ public void error(final Marker marker, final CharSequence message) {
}
@Override
- public void error(final Marker marker, final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, Level.ERROR, marker, message, t);
+ public void error(final Marker marker, final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.ERROR, marker, message, throwable);
}
@Override
@@ -673,8 +672,8 @@ public void error(final Marker marker, final Object message) {
}
@Override
- public void error(final Marker marker, final Object message, final Throwable t) {
- logIfEnabled(FQCN, Level.ERROR, marker, message, t);
+ public void error(final Marker marker, final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.ERROR, marker, message, throwable);
}
@Override
@@ -688,18 +687,18 @@ public void error(final Marker marker, final String message, final Object... par
}
@Override
- public void error(final Marker marker, final String message, final Throwable t) {
- logIfEnabled(FQCN, Level.ERROR, marker, message, t);
+ public void error(final Marker marker, final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.ERROR, marker, message, throwable);
}
@Override
- public void error(final Message msg) {
- logIfEnabled(FQCN, Level.ERROR, null, msg, msg != null ? msg.getThrowable() : null);
+ public void error(final Message message) {
+ logIfEnabled(FQCN, Level.ERROR, null, message, message != null ? message.getThrowable() : null);
}
@Override
- public void error(final Message msg, final Throwable t) {
- logIfEnabled(FQCN, Level.ERROR, null, msg, t);
+ public void error(final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.ERROR, null, message, throwable);
}
@Override
@@ -708,8 +707,8 @@ public void error(final CharSequence message) {
}
@Override
- public void error(final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, Level.ERROR, null, message, t);
+ public void error(final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.ERROR, null, message, throwable);
}
@Override
@@ -718,8 +717,8 @@ public void error(final Object message) {
}
@Override
- public void error(final Object message, final Throwable t) {
- logIfEnabled(FQCN, Level.ERROR, null, message, t);
+ public void error(final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.ERROR, null, message, throwable);
}
@Override
@@ -733,8 +732,8 @@ public void error(final String message, final Object... params) {
}
@Override
- public void error(final String message, final Throwable t) {
- logIfEnabled(FQCN, Level.ERROR, null, message, t);
+ public void error(final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.ERROR, null, message, throwable);
}
@Override
@@ -774,23 +773,23 @@ public void error(final String message, final Supplier>... paramSuppliers) {
}
@Override
- public void error(final Marker marker, final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, Level.ERROR, marker, msgSupplier, (Throwable) null);
+ public void error(final Marker marker, final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, Level.ERROR, marker, messageSupplier, (Throwable) null);
}
@Override
- public void error(final Marker marker, final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, Level.ERROR, marker, msgSupplier, t);
+ public void error(final Marker marker, final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.ERROR, marker, messageSupplier, throwable);
}
@Override
- public void error(final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, Level.ERROR, null, msgSupplier, (Throwable) null);
+ public void error(final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, Level.ERROR, null, messageSupplier, (Throwable) null);
}
@Override
- public void error(final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, Level.ERROR, null, msgSupplier, t);
+ public void error(final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.ERROR, null, messageSupplier, throwable);
}
@Override
@@ -1038,13 +1037,13 @@ protected Message exitMsg(final String format, final Object result) {
}
@Override
- public void fatal(final Marker marker, final Message msg) {
- logIfEnabled(FQCN, Level.FATAL, marker, msg, msg != null ? msg.getThrowable() : null);
+ public void fatal(final Marker marker, final Message message) {
+ logIfEnabled(FQCN, Level.FATAL, marker, message, message != null ? message.getThrowable() : null);
}
@Override
- public void fatal(final Marker marker, final Message msg, final Throwable t) {
- logIfEnabled(FQCN, Level.FATAL, marker, msg, t);
+ public void fatal(final Marker marker, final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.FATAL, marker, message, throwable);
}
@Override
@@ -1053,8 +1052,8 @@ public void fatal(final Marker marker, final CharSequence message) {
}
@Override
- public void fatal(final Marker marker, final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, Level.FATAL, marker, message, t);
+ public void fatal(final Marker marker, final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.FATAL, marker, message, throwable);
}
@Override
@@ -1063,8 +1062,8 @@ public void fatal(final Marker marker, final Object message) {
}
@Override
- public void fatal(final Marker marker, final Object message, final Throwable t) {
- logIfEnabled(FQCN, Level.FATAL, marker, message, t);
+ public void fatal(final Marker marker, final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.FATAL, marker, message, throwable);
}
@Override
@@ -1078,18 +1077,18 @@ public void fatal(final Marker marker, final String message, final Object... par
}
@Override
- public void fatal(final Marker marker, final String message, final Throwable t) {
- logIfEnabled(FQCN, Level.FATAL, marker, message, t);
+ public void fatal(final Marker marker, final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.FATAL, marker, message, throwable);
}
@Override
- public void fatal(final Message msg) {
- logIfEnabled(FQCN, Level.FATAL, null, msg, msg != null ? msg.getThrowable() : null);
+ public void fatal(final Message message) {
+ logIfEnabled(FQCN, Level.FATAL, null, message, message != null ? message.getThrowable() : null);
}
@Override
- public void fatal(final Message msg, final Throwable t) {
- logIfEnabled(FQCN, Level.FATAL, null, msg, t);
+ public void fatal(final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.FATAL, null, message, throwable);
}
@Override
@@ -1098,8 +1097,8 @@ public void fatal(final CharSequence message) {
}
@Override
- public void fatal(final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, Level.FATAL, null, message, t);
+ public void fatal(final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.FATAL, null, message, throwable);
}
@Override
@@ -1108,8 +1107,8 @@ public void fatal(final Object message) {
}
@Override
- public void fatal(final Object message, final Throwable t) {
- logIfEnabled(FQCN, Level.FATAL, null, message, t);
+ public void fatal(final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.FATAL, null, message, throwable);
}
@Override
@@ -1123,8 +1122,8 @@ public void fatal(final String message, final Object... params) {
}
@Override
- public void fatal(final String message, final Throwable t) {
- logIfEnabled(FQCN, Level.FATAL, null, message, t);
+ public void fatal(final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.FATAL, null, message, throwable);
}
@Override
@@ -1164,23 +1163,23 @@ public void fatal(final String message, final Supplier>... paramSuppliers) {
}
@Override
- public void fatal(final Marker marker, final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, Level.FATAL, marker, msgSupplier, (Throwable) null);
+ public void fatal(final Marker marker, final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, Level.FATAL, marker, messageSupplier, (Throwable) null);
}
@Override
- public void fatal(final Marker marker, final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, Level.FATAL, marker, msgSupplier, t);
+ public void fatal(final Marker marker, final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.FATAL, marker, messageSupplier, throwable);
}
@Override
- public void fatal(final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, Level.FATAL, null, msgSupplier, (Throwable) null);
+ public void fatal(final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, Level.FATAL, null, messageSupplier, (Throwable) null);
}
@Override
- public void fatal(final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, Level.FATAL, null, msgSupplier, t);
+ public void fatal(final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.FATAL, null, messageSupplier, throwable);
}
@Override
@@ -1392,9 +1391,10 @@ public void fatal(
logIfEnabled(FQCN, Level.FATAL, null, message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
}
+ @SuppressWarnings("unchecked")
@Override
public MF getMessageFactory() {
- return Cast.cast(messageFactory);
+ return (MF) messageFactory;
}
@Override
@@ -1408,13 +1408,13 @@ public String getName() {
}
@Override
- public void info(final Marker marker, final Message msg) {
- logIfEnabled(FQCN, Level.INFO, marker, msg, msg != null ? msg.getThrowable() : null);
+ public void info(final Marker marker, final Message message) {
+ logIfEnabled(FQCN, Level.INFO, marker, message, message != null ? message.getThrowable() : null);
}
@Override
- public void info(final Marker marker, final Message msg, final Throwable t) {
- logIfEnabled(FQCN, Level.INFO, marker, msg, t);
+ public void info(final Marker marker, final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.INFO, marker, message, throwable);
}
@Override
@@ -1423,8 +1423,8 @@ public void info(final Marker marker, final CharSequence message) {
}
@Override
- public void info(final Marker marker, final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, Level.INFO, marker, message, t);
+ public void info(final Marker marker, final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.INFO, marker, message, throwable);
}
@Override
@@ -1433,8 +1433,8 @@ public void info(final Marker marker, final Object message) {
}
@Override
- public void info(final Marker marker, final Object message, final Throwable t) {
- logIfEnabled(FQCN, Level.INFO, marker, message, t);
+ public void info(final Marker marker, final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.INFO, marker, message, throwable);
}
@Override
@@ -1448,18 +1448,18 @@ public void info(final Marker marker, final String message, final Object... para
}
@Override
- public void info(final Marker marker, final String message, final Throwable t) {
- logIfEnabled(FQCN, Level.INFO, marker, message, t);
+ public void info(final Marker marker, final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.INFO, marker, message, throwable);
}
@Override
- public void info(final Message msg) {
- logIfEnabled(FQCN, Level.INFO, null, msg, msg != null ? msg.getThrowable() : null);
+ public void info(final Message message) {
+ logIfEnabled(FQCN, Level.INFO, null, message, message != null ? message.getThrowable() : null);
}
@Override
- public void info(final Message msg, final Throwable t) {
- logIfEnabled(FQCN, Level.INFO, null, msg, t);
+ public void info(final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.INFO, null, message, throwable);
}
@Override
@@ -1468,8 +1468,8 @@ public void info(final CharSequence message) {
}
@Override
- public void info(final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, Level.INFO, null, message, t);
+ public void info(final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.INFO, null, message, throwable);
}
@Override
@@ -1478,8 +1478,8 @@ public void info(final Object message) {
}
@Override
- public void info(final Object message, final Throwable t) {
- logIfEnabled(FQCN, Level.INFO, null, message, t);
+ public void info(final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.INFO, null, message, throwable);
}
@Override
@@ -1493,8 +1493,8 @@ public void info(final String message, final Object... params) {
}
@Override
- public void info(final String message, final Throwable t) {
- logIfEnabled(FQCN, Level.INFO, null, message, t);
+ public void info(final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.INFO, null, message, throwable);
}
@Override
@@ -1534,23 +1534,23 @@ public void info(final String message, final Supplier>... paramSuppliers) {
}
@Override
- public void info(final Marker marker, final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, Level.INFO, marker, msgSupplier, (Throwable) null);
+ public void info(final Marker marker, final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, Level.INFO, marker, messageSupplier, (Throwable) null);
}
@Override
- public void info(final Marker marker, final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, Level.INFO, marker, msgSupplier, t);
+ public void info(final Marker marker, final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.INFO, marker, messageSupplier, throwable);
}
@Override
- public void info(final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, Level.INFO, null, msgSupplier, (Throwable) null);
+ public void info(final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, Level.INFO, null, messageSupplier, (Throwable) null);
}
@Override
- public void info(final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, Level.INFO, null, msgSupplier, t);
+ public void info(final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.INFO, null, messageSupplier, throwable);
}
@Override
@@ -1833,13 +1833,13 @@ public boolean isWarnEnabled(final Marker marker) {
}
@Override
- public void log(final Level level, final Marker marker, final Message msg) {
- logIfEnabled(FQCN, level, marker, msg, msg != null ? msg.getThrowable() : null);
+ public void log(final Level level, final Marker marker, final Message message) {
+ logIfEnabled(FQCN, level, marker, message, message != null ? message.getThrowable() : null);
}
@Override
- public void log(final Level level, final Marker marker, final Message msg, final Throwable t) {
- logIfEnabled(FQCN, level, marker, msg, t);
+ public void log(final Level level, final Marker marker, final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, level, marker, message, throwable);
}
@Override
@@ -1848,9 +1848,9 @@ public void log(final Level level, final Marker marker, final CharSequence messa
}
@Override
- public void log(final Level level, final Marker marker, final CharSequence message, final Throwable t) {
- if (isEnabled(level, marker, message, t)) {
- logMessage(FQCN, level, marker, message, t);
+ public void log(final Level level, final Marker marker, final CharSequence message, final Throwable throwable) {
+ if (isEnabled(level, marker, message, throwable)) {
+ logMessage(FQCN, level, marker, message, throwable);
}
}
@@ -1860,9 +1860,9 @@ public void log(final Level level, final Marker marker, final Object message) {
}
@Override
- public void log(final Level level, final Marker marker, final Object message, final Throwable t) {
- if (isEnabled(level, marker, message, t)) {
- logMessage(FQCN, level, marker, message, t);
+ public void log(final Level level, final Marker marker, final Object message, final Throwable throwable) {
+ if (isEnabled(level, marker, message, throwable)) {
+ logMessage(FQCN, level, marker, message, throwable);
}
}
@@ -1877,18 +1877,18 @@ public void log(final Level level, final Marker marker, final String message, fi
}
@Override
- public void log(final Level level, final Marker marker, final String message, final Throwable t) {
- logIfEnabled(FQCN, level, marker, message, t);
+ public void log(final Level level, final Marker marker, final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, level, marker, message, throwable);
}
@Override
- public void log(final Level level, final Message msg) {
- logIfEnabled(FQCN, level, null, msg, msg != null ? msg.getThrowable() : null);
+ public void log(final Level level, final Message message) {
+ logIfEnabled(FQCN, level, null, message, message != null ? message.getThrowable() : null);
}
@Override
- public void log(final Level level, final Message msg, final Throwable t) {
- logIfEnabled(FQCN, level, null, msg, t);
+ public void log(final Level level, final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, level, null, message, throwable);
}
@Override
@@ -1897,8 +1897,8 @@ public void log(final Level level, final CharSequence message) {
}
@Override
- public void log(final Level level, final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, level, null, message, t);
+ public void log(final Level level, final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, level, null, message, throwable);
}
@Override
@@ -1907,8 +1907,8 @@ public void log(final Level level, final Object message) {
}
@Override
- public void log(final Level level, final Object message, final Throwable t) {
- logIfEnabled(FQCN, level, null, message, t);
+ public void log(final Level level, final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, level, null, message, throwable);
}
@Override
@@ -1922,8 +1922,8 @@ public void log(final Level level, final String message, final Object... params)
}
@Override
- public void log(final Level level, final String message, final Throwable t) {
- logIfEnabled(FQCN, level, null, message, t);
+ public void log(final Level level, final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, level, null, message, throwable);
}
@Override
@@ -1964,23 +1964,24 @@ public void log(final Level level, final String message, final Supplier>... pa
}
@Override
- public void log(final Level level, final Marker marker, final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, level, marker, msgSupplier, (Throwable) null);
+ public void log(final Level level, final Marker marker, final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, level, marker, messageSupplier, (Throwable) null);
}
@Override
- public void log(final Level level, final Marker marker, final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, level, marker, msgSupplier, t);
+ public void log(
+ final Level level, final Marker marker, final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, level, marker, messageSupplier, throwable);
}
@Override
- public void log(final Level level, final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, level, null, msgSupplier, (Throwable) null);
+ public void log(final Level level, final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, level, null, messageSupplier, (Throwable) null);
}
@Override
- public void log(final Level level, final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, level, null, msgSupplier, t);
+ public void log(final Level level, final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, level, null, messageSupplier, throwable);
}
@Override
@@ -2224,9 +2225,13 @@ public void log(
@Override
public void logIfEnabled(
- final String fqcn, final Level level, final Marker marker, final Message msg, final Throwable t) {
- if (isEnabled(level, marker, msg, t)) {
- logMessageSafely(fqcn, level, marker, msg, t);
+ final String fqcn,
+ final Level level,
+ final Marker marker,
+ final Message message,
+ final Throwable throwable) {
+ if (isEnabled(level, marker, message, throwable)) {
+ logMessageSafely(fqcn, level, marker, message, throwable);
}
}
@@ -2235,26 +2240,34 @@ public void logIfEnabled(
final String fqcn,
final Level level,
final Marker marker,
- final MessageSupplier msgSupplier,
- final Throwable t) {
- if (isEnabled(level, marker, msgSupplier, t)) {
- logMessage(fqcn, level, marker, msgSupplier, t);
+ final MessageSupplier messageSupplier,
+ final Throwable throwable) {
+ if (isEnabled(level, marker, messageSupplier, throwable)) {
+ logMessage(fqcn, level, marker, messageSupplier, throwable);
}
}
@Override
public void logIfEnabled(
- final String fqcn, final Level level, final Marker marker, final Object message, final Throwable t) {
- if (isEnabled(level, marker, message, t)) {
- logMessage(fqcn, level, marker, message, t);
+ final String fqcn,
+ final Level level,
+ final Marker marker,
+ final Object message,
+ final Throwable throwable) {
+ if (isEnabled(level, marker, message, throwable)) {
+ logMessage(fqcn, level, marker, message, throwable);
}
}
@Override
public void logIfEnabled(
- final String fqcn, final Level level, final Marker marker, final CharSequence message, final Throwable t) {
- if (isEnabled(level, marker, message, t)) {
- logMessage(fqcn, level, marker, message, t);
+ final String fqcn,
+ final Level level,
+ final Marker marker,
+ final CharSequence message,
+ final Throwable throwable) {
+ if (isEnabled(level, marker, message, throwable)) {
+ logMessage(fqcn, level, marker, message, throwable);
}
}
@@ -2462,30 +2475,44 @@ public void logIfEnabled(
@Override
public void logIfEnabled(
- final String fqcn, final Level level, final Marker marker, final String message, final Throwable t) {
- if (isEnabled(level, marker, message, t)) {
- logMessage(fqcn, level, marker, message, t);
+ final String fqcn,
+ final Level level,
+ final Marker marker,
+ final String message,
+ final Throwable throwable) {
+ if (isEnabled(level, marker, message, throwable)) {
+ logMessage(fqcn, level, marker, message, throwable);
}
}
protected void logMessage(
- final String fqcn, final Level level, final Marker marker, final CharSequence message, final Throwable t) {
- logMessageSafely(fqcn, level, marker, messageFactory.newMessage(message), t);
+ final String fqcn,
+ final Level level,
+ final Marker marker,
+ final CharSequence message,
+ final Throwable throwable) {
+ logMessageSafely(fqcn, level, marker, messageFactory.newMessage(message), throwable);
}
protected void logMessage(
- final String fqcn, final Level level, final Marker marker, final Object message, final Throwable t) {
- logMessageSafely(fqcn, level, marker, messageFactory.newMessage(message), t);
+ final String fqcn,
+ final Level level,
+ final Marker marker,
+ final Object message,
+ final Throwable throwable) {
+ logMessageSafely(fqcn, level, marker, messageFactory.newMessage(message), throwable);
}
protected void logMessage(
final String fqcn,
final Level level,
final Marker marker,
- final MessageSupplier msgSupplier,
- final Throwable t) {
- final Message message = LambdaUtil.get(msgSupplier);
- logMessageSafely(fqcn, level, marker, message, (t == null && message != null) ? message.getThrowable() : t);
+ final MessageSupplier messageSupplier,
+ final Throwable throwable) {
+ final Message message = LambdaUtil.get(messageSupplier);
+ final Throwable effectiveThrowable =
+ (throwable == null && message != null) ? message.getThrowable() : throwable;
+ logMessageSafely(fqcn, level, marker, message, effectiveThrowable);
}
@SuppressWarnings("deprecation")
@@ -2502,8 +2529,12 @@ protected void logMessage(
}
protected void logMessage(
- final String fqcn, final Level level, final Marker marker, final String message, final Throwable t) {
- logMessageSafely(fqcn, level, marker, messageFactory.newMessage(message), t);
+ final String fqcn,
+ final Level level,
+ final Marker marker,
+ final String message,
+ final Throwable throwable) {
+ logMessageSafely(fqcn, level, marker, messageFactory.newMessage(message), throwable);
}
protected void logMessage(final String fqcn, final Level level, final Marker marker, final String message) {
@@ -2701,16 +2732,16 @@ protected void log(
@Override
public void printf(final Level level, final Marker marker, final String format, final Object... params) {
if (isEnabled(level, marker, format, params)) {
- final Message msg = new StringFormattedMessage(format, params);
- logMessageSafely(FQCN, level, marker, msg, msg.getThrowable());
+ final Message message = new StringFormattedMessage(format, params);
+ logMessageSafely(FQCN, level, marker, message, message.getThrowable());
}
}
@Override
public void printf(final Level level, final String format, final Object... params) {
if (isEnabled(level, null, format, params)) {
- final Message msg = new StringFormattedMessage(format, params);
- logMessageSafely(FQCN, level, null, msg, msg.getThrowable());
+ final Message message = new StringFormattedMessage(format, params);
+ logMessageSafely(FQCN, level, null, message, message.getThrowable());
}
}
@@ -2718,12 +2749,16 @@ public void printf(final Level level, final String format, final Object... param
// NOTE: This is a hot method. Current implementation compiles to 30 bytes of byte code.
// This is within the 35 byte MaxInlineSize threshold. Modify with care!
private void logMessageSafely(
- final String fqcn, final Level level, final Marker marker, final Message msg, final Throwable throwable) {
+ final String fqcn,
+ final Level level,
+ final Marker marker,
+ final Message message,
+ final Throwable throwable) {
try {
- logMessageTrackRecursion(fqcn, level, marker, msg, throwable);
+ logMessageTrackRecursion(fqcn, level, marker, message, throwable);
} finally {
// LOG4J2-1583 prevent scrambled logs when logging calls are nested (logging in toString())
- messageFactory.recycle(msg);
+ messageFactory.recycle(message);
}
}
@@ -2731,10 +2766,14 @@ private void logMessageSafely(
// NOTE: This is a hot method. Current implementation compiles to 33 bytes of byte code.
// This is within the 35 byte MaxInlineSize threshold. Modify with care!
private void logMessageTrackRecursion(
- final String fqcn, final Level level, final Marker marker, final Message msg, final Throwable throwable) {
+ final String fqcn,
+ final Level level,
+ final Marker marker,
+ final Message message,
+ final Throwable throwable) {
try {
incrementRecursionDepth(); // LOG4J2-1518, LOG4J2-2031
- tryLogMessage(fqcn, getLocation(fqcn), level, marker, msg, throwable);
+ tryLogMessage(fqcn, getLocation(fqcn), level, marker, message, throwable);
} finally {
decrementRecursionDepth();
}
@@ -2771,7 +2810,7 @@ public static int getRecursionDepth() {
}
@PerformanceSensitive
- // NOTE: This is a hot method. Current implementation compiles to 27 bytes of byte code.
+ // NOTE: This is a hot method. Current implementation compiles to 26 bytes of byte code.
// This is within the 35 byte MaxInlineSize threshold. Modify with care!
private void tryLogMessage(
final String fqcn,
@@ -2812,13 +2851,13 @@ private void handleLogMessageException(final Throwable throwable, final String f
}
@Override
- public T throwing(final T t) {
- return throwing(FQCN, Level.ERROR, t);
+ public T throwing(final T throwable) {
+ return throwing(FQCN, Level.ERROR, throwable);
}
@Override
- public T throwing(final Level level, final T t) {
- return throwing(FQCN, level, t);
+ public T throwing(final Level level, final T throwable) {
+ return throwing(FQCN, level, throwable);
}
/**
@@ -2827,28 +2866,28 @@ public T throwing(final Level level, final T t) {
* @param the type of the Throwable.
* @param fqcn the fully qualified class name of this Logger implementation.
* @param level The logging Level.
- * @param t The Throwable.
+ * @param throwable The Throwable.
* @return the Throwable.
*/
- protected T throwing(final String fqcn, final Level level, final T t) {
+ protected T throwing(final String fqcn, final Level level, final T throwable) {
if (isEnabled(level, THROWING_MARKER, (Object) null, null)) {
- logMessageSafely(fqcn, level, THROWING_MARKER, throwingMsg(t), t);
+ logMessageSafely(fqcn, level, THROWING_MARKER, throwingMsg(throwable), throwable);
}
- return t;
+ return throwable;
}
- protected Message throwingMsg(final Throwable t) {
+ protected Message throwingMsg(final Throwable throwable) {
return messageFactory.newMessage(THROWING);
}
@Override
- public void trace(final Marker marker, final Message msg) {
- logIfEnabled(FQCN, Level.TRACE, marker, msg, msg != null ? msg.getThrowable() : null);
+ public void trace(final Marker marker, final Message message) {
+ logIfEnabled(FQCN, Level.TRACE, marker, message, message != null ? message.getThrowable() : null);
}
@Override
- public void trace(final Marker marker, final Message msg, final Throwable t) {
- logIfEnabled(FQCN, Level.TRACE, marker, msg, t);
+ public void trace(final Marker marker, final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.TRACE, marker, message, throwable);
}
@Override
@@ -2857,8 +2896,8 @@ public void trace(final Marker marker, final CharSequence message) {
}
@Override
- public void trace(final Marker marker, final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, Level.TRACE, marker, message, t);
+ public void trace(final Marker marker, final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.TRACE, marker, message, throwable);
}
@Override
@@ -2867,8 +2906,8 @@ public void trace(final Marker marker, final Object message) {
}
@Override
- public void trace(final Marker marker, final Object message, final Throwable t) {
- logIfEnabled(FQCN, Level.TRACE, marker, message, t);
+ public void trace(final Marker marker, final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.TRACE, marker, message, throwable);
}
@Override
@@ -2882,18 +2921,18 @@ public void trace(final Marker marker, final String message, final Object... par
}
@Override
- public void trace(final Marker marker, final String message, final Throwable t) {
- logIfEnabled(FQCN, Level.TRACE, marker, message, t);
+ public void trace(final Marker marker, final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.TRACE, marker, message, throwable);
}
@Override
- public void trace(final Message msg) {
- logIfEnabled(FQCN, Level.TRACE, null, msg, msg != null ? msg.getThrowable() : null);
+ public void trace(final Message message) {
+ logIfEnabled(FQCN, Level.TRACE, null, message, message != null ? message.getThrowable() : null);
}
@Override
- public void trace(final Message msg, final Throwable t) {
- logIfEnabled(FQCN, Level.TRACE, null, msg, t);
+ public void trace(final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.TRACE, null, message, throwable);
}
@Override
@@ -2902,8 +2941,8 @@ public void trace(final CharSequence message) {
}
@Override
- public void trace(final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, Level.TRACE, null, message, t);
+ public void trace(final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.TRACE, null, message, throwable);
}
@Override
@@ -2912,8 +2951,8 @@ public void trace(final Object message) {
}
@Override
- public void trace(final Object message, final Throwable t) {
- logIfEnabled(FQCN, Level.TRACE, null, message, t);
+ public void trace(final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.TRACE, null, message, throwable);
}
@Override
@@ -2927,8 +2966,8 @@ public void trace(final String message, final Object... params) {
}
@Override
- public void trace(final String message, final Throwable t) {
- logIfEnabled(FQCN, Level.TRACE, null, message, t);
+ public void trace(final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.TRACE, null, message, throwable);
}
@Override
@@ -2968,23 +3007,23 @@ public void trace(final String message, final Supplier>... paramSuppliers) {
}
@Override
- public void trace(final Marker marker, final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, Level.TRACE, marker, msgSupplier, (Throwable) null);
+ public void trace(final Marker marker, final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, Level.TRACE, marker, messageSupplier, (Throwable) null);
}
@Override
- public void trace(final Marker marker, final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, Level.TRACE, marker, msgSupplier, t);
+ public void trace(final Marker marker, final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.TRACE, marker, messageSupplier, throwable);
}
@Override
- public void trace(final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, Level.TRACE, null, msgSupplier, (Throwable) null);
+ public void trace(final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, Level.TRACE, null, messageSupplier, (Throwable) null);
}
@Override
- public void trace(final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, Level.TRACE, null, msgSupplier, t);
+ public void trace(final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.TRACE, null, messageSupplier, throwable);
}
@Override
@@ -3268,13 +3307,13 @@ public R traceExit(final Message message, final R result) {
}
@Override
- public void warn(final Marker marker, final Message msg) {
- logIfEnabled(FQCN, Level.WARN, marker, msg, msg != null ? msg.getThrowable() : null);
+ public void warn(final Marker marker, final Message message) {
+ logIfEnabled(FQCN, Level.WARN, marker, message, message != null ? message.getThrowable() : null);
}
@Override
- public void warn(final Marker marker, final Message msg, final Throwable t) {
- logIfEnabled(FQCN, Level.WARN, marker, msg, t);
+ public void warn(final Marker marker, final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.WARN, marker, message, throwable);
}
@Override
@@ -3283,8 +3322,8 @@ public void warn(final Marker marker, final CharSequence message) {
}
@Override
- public void warn(final Marker marker, final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, Level.WARN, marker, message, t);
+ public void warn(final Marker marker, final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.WARN, marker, message, throwable);
}
@Override
@@ -3293,8 +3332,8 @@ public void warn(final Marker marker, final Object message) {
}
@Override
- public void warn(final Marker marker, final Object message, final Throwable t) {
- logIfEnabled(FQCN, Level.WARN, marker, message, t);
+ public void warn(final Marker marker, final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.WARN, marker, message, throwable);
}
@Override
@@ -3308,18 +3347,18 @@ public void warn(final Marker marker, final String message, final Object... para
}
@Override
- public void warn(final Marker marker, final String message, final Throwable t) {
- logIfEnabled(FQCN, Level.WARN, marker, message, t);
+ public void warn(final Marker marker, final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.WARN, marker, message, throwable);
}
@Override
- public void warn(final Message msg) {
- logIfEnabled(FQCN, Level.WARN, null, msg, msg != null ? msg.getThrowable() : null);
+ public void warn(final Message message) {
+ logIfEnabled(FQCN, Level.WARN, null, message, message != null ? message.getThrowable() : null);
}
@Override
- public void warn(final Message msg, final Throwable t) {
- logIfEnabled(FQCN, Level.WARN, null, msg, t);
+ public void warn(final Message message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.WARN, null, message, throwable);
}
@Override
@@ -3328,8 +3367,8 @@ public void warn(final CharSequence message) {
}
@Override
- public void warn(final CharSequence message, final Throwable t) {
- logIfEnabled(FQCN, Level.WARN, null, message, t);
+ public void warn(final CharSequence message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.WARN, null, message, throwable);
}
@Override
@@ -3338,8 +3377,8 @@ public void warn(final Object message) {
}
@Override
- public void warn(final Object message, final Throwable t) {
- logIfEnabled(FQCN, Level.WARN, null, message, t);
+ public void warn(final Object message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.WARN, null, message, throwable);
}
@Override
@@ -3353,8 +3392,8 @@ public void warn(final String message, final Object... params) {
}
@Override
- public void warn(final String message, final Throwable t) {
- logIfEnabled(FQCN, Level.WARN, null, message, t);
+ public void warn(final String message, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.WARN, null, message, throwable);
}
@Override
@@ -3394,23 +3433,23 @@ public void warn(final String message, final Supplier>... paramSuppliers) {
}
@Override
- public void warn(final Marker marker, final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, Level.WARN, marker, msgSupplier, (Throwable) null);
+ public void warn(final Marker marker, final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, Level.WARN, marker, messageSupplier, (Throwable) null);
}
@Override
- public void warn(final Marker marker, final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, Level.WARN, marker, msgSupplier, t);
+ public void warn(final Marker marker, final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.WARN, marker, messageSupplier, throwable);
}
@Override
- public void warn(final MessageSupplier msgSupplier) {
- logIfEnabled(FQCN, Level.WARN, null, msgSupplier, (Throwable) null);
+ public void warn(final MessageSupplier messageSupplier) {
+ logIfEnabled(FQCN, Level.WARN, null, messageSupplier, (Throwable) null);
}
@Override
- public void warn(final MessageSupplier msgSupplier, final Throwable t) {
- logIfEnabled(FQCN, Level.WARN, null, msgSupplier, t);
+ public void warn(final MessageSupplier messageSupplier, final Throwable throwable) {
+ logIfEnabled(FQCN, Level.WARN, null, messageSupplier, throwable);
}
@Override
@@ -3714,7 +3753,7 @@ public LogBuilder atLevel(final Level level) {
*
* @since 2.20.0
*/
- protected LogBuilder getLogBuilder(Level level) {
+ protected LogBuilder getLogBuilder(final Level level) {
DefaultLogBuilder builder = recycler.acquire();
return builder.reset(this, level);
}
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/GarbageFreeSortedArrayThreadContextMap.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/GarbageFreeSortedArrayThreadContextMap.java
index 542962dd484..5fe721ee39b 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/GarbageFreeSortedArrayThreadContextMap.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/GarbageFreeSortedArrayThreadContextMap.java
@@ -155,7 +155,7 @@ public String get(final String key) {
@Override
public V getValue(final String key) {
final StringMap map = localMap.get();
- return map == null ? null : map.getValue(key);
+ return map == null ? null : map.getValue(key);
}
@Override
diff --git a/log4j-perf-test/src/main/java/org/apache/logging/log4j/message/ParameterFormatterBenchmark.java b/log4j-perf-test/src/main/java/org/apache/logging/log4j/message/ParameterFormatterBenchmark.java
index 8ec3f10ef11..b4d35002f53 100644
--- a/log4j-perf-test/src/main/java/org/apache/logging/log4j/message/ParameterFormatterBenchmark.java
+++ b/log4j-perf-test/src/main/java/org/apache/logging/log4j/message/ParameterFormatterBenchmark.java
@@ -46,153 +46,48 @@ public class ParameterFormatterBenchmark {
@State(Scope.Thread)
public static class ThreadState {
- StringBuilder buffer = new StringBuilder(2048);
- int[] indices = new int[255];
- char[] copy = new char[4096];
- }
- @Benchmark
- @BenchmarkMode(Mode.SampleTime)
- @OutputTimeUnit(TimeUnit.NANOSECONDS)
- public int latency3ParamsV3(final ThreadState state) {
- state.buffer.setLength(0);
- final String STR = "p1={}, p2={}, p3={}";
- final int length = STR.length();
- STR.getChars(0, length, state.copy, 0);
- final int count = ParameterFormatter.countArgumentPlaceholders3(state.copy, length, state.indices);
- ParameterFormatter.formatMessage3(state.buffer, state.copy, length, ARGS, count, state.indices);
- return state.buffer.length();
- }
+ private final MessagePatternAnalysis analysis = new MessagePatternAnalysis();
- @Benchmark
- @BenchmarkMode(Mode.SampleTime)
- @OutputTimeUnit(TimeUnit.NANOSECONDS)
- public int latency5ParamsV3(final ThreadState state) {
- state.buffer.setLength(0);
- final String STR = "p1={}, p2={}, p3={}, p4={}, p5={}";
- final int length = STR.length();
- STR.getChars(0, length, state.copy, 0);
- final int count = ParameterFormatter.countArgumentPlaceholders3(state.copy, length, state.indices);
- ParameterFormatter.formatMessage3(state.buffer, state.copy, length, ARGS, count, state.indices);
- return state.buffer.length();
- }
+ private final StringBuilder buffer = new StringBuilder(2048);
- @Benchmark
- @BenchmarkMode(Mode.SampleTime)
- @OutputTimeUnit(TimeUnit.NANOSECONDS)
- public int latency7ParamsV3(final ThreadState state) {
- state.buffer.setLength(0);
- final String STR = "p1={}, p2={}, p3={}, p4={}, p5={}, p6={}, p7={}";
- final int length = STR.length();
- STR.getChars(0, length, state.copy, 0);
- final int count = ParameterFormatter.countArgumentPlaceholders3(state.copy, length, state.indices);
- ParameterFormatter.formatMessage3(state.buffer, state.copy, length, ARGS, count, state.indices);
- return state.buffer.length();
- }
-
- @Benchmark
- @BenchmarkMode(Mode.SampleTime)
- @OutputTimeUnit(TimeUnit.NANOSECONDS)
- public int latency9ParamsV3(final ThreadState state) {
- state.buffer.setLength(0);
- final String STR = "p1={}, p2={}, p3={}, p4={}, p5={}, p6={}, p7={}, p8={}, p9={}";
- final int length = STR.length();
- STR.getChars(0, length, state.copy, 0);
- final int count = ParameterFormatter.countArgumentPlaceholders3(state.copy, length, state.indices);
- ParameterFormatter.formatMessage3(state.buffer, state.copy, length, ARGS, count, state.indices);
- return state.buffer.length();
- }
-
- @Benchmark
- @BenchmarkMode(Mode.SampleTime)
- @OutputTimeUnit(TimeUnit.NANOSECONDS)
- public int latency3ParamsV2(final ThreadState state) {
- state.buffer.setLength(0);
- final int count = ParameterFormatter.countArgumentPlaceholders2("p1={}, p2={}, p3={}", state.indices);
- ParameterFormatter.formatMessage2(state.buffer, "p1={}, p2={}, p3={}", ARGS, count, state.indices);
- return state.buffer.length();
- }
-
- @Benchmark
- @BenchmarkMode(Mode.SampleTime)
- @OutputTimeUnit(TimeUnit.NANOSECONDS)
- public int latency5ParamsV2(final ThreadState state) {
- state.buffer.setLength(0);
- final int count =
- ParameterFormatter.countArgumentPlaceholders2("p1={}, p2={}, p3={}, p4={}, p5={}", state.indices);
- ParameterFormatter.formatMessage2(
- state.buffer, "p1={}, p2={}, p3={}, p4={}, p5={}", ARGS, count, state.indices);
- return state.buffer.length();
- }
-
- @Benchmark
- @BenchmarkMode(Mode.SampleTime)
- @OutputTimeUnit(TimeUnit.NANOSECONDS)
- public int latency7ParamsV2(final ThreadState state) {
- state.buffer.setLength(0);
- final int count = ParameterFormatter.countArgumentPlaceholders2(
- "p1={}, p2={}, p3={}, p4={}, p5={}, p6={}, p7={}", state.indices);
- ParameterFormatter.formatMessage2(
- state.buffer, "p1={}, p2={}, p3={}, p4={}, p5={}, p6={}, p7={}", ARGS, count, state.indices);
- return state.buffer.length();
- }
-
- @Benchmark
- @BenchmarkMode(Mode.SampleTime)
- @OutputTimeUnit(TimeUnit.NANOSECONDS)
- public int latency9ParamsV2(final ThreadState state) {
- state.buffer.setLength(0);
- final int count = ParameterFormatter.countArgumentPlaceholders2(
- "p1={}, p2={}, p3={}, p4={}, p5={}, p6={}, p7={}, p8={}, p9={}", state.indices);
- ParameterFormatter.formatMessage2(
- state.buffer,
- "p1={}, p2={}, p3={}, p4={}, p5={}, p6={}, p7={}, p8={}, p9={}",
- ARGS,
- count,
- state.indices);
- return state.buffer.length();
+ public ThreadState() {
+ analysis.placeholderCharIndices = new int[10];
+ }
}
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public int latency3Params(final ThreadState state) {
- state.buffer.setLength(0);
- final int count = ParameterFormatter.countArgumentPlaceholders("p1={}, p2={}, p3={}");
- ParameterFormatter.formatMessage(state.buffer, "p1={}, p2={}, p3={}", ARGS, count);
- return state.buffer.length();
+ return latencyParams(state, "p1={}, p2={}, p3={}");
}
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public int latency5Params(final ThreadState state) {
- state.buffer.setLength(0);
- final int count = ParameterFormatter.countArgumentPlaceholders("p1={}, p2={}, p3={}, p4={}, p5={}");
- ParameterFormatter.formatMessage(state.buffer, "p1={}, p2={}, p3={}, p4={}, p5={}", ARGS, count);
- return state.buffer.length();
+ return latencyParams(state, "p1={}, p2={}, p3={}, p4={}, p5={}");
}
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public int latency7Params(final ThreadState state) {
- state.buffer.setLength(0);
- final int count =
- ParameterFormatter.countArgumentPlaceholders("p1={}, p2={}, p3={}, p4={}, p5={}, p6={}, p7={}");
- ParameterFormatter.formatMessage(state.buffer, "p1={}, p2={}, p3={}, p4={}, p5={}, p6={}, p7={}", ARGS, count);
- return state.buffer.length();
+ return latencyParams(state, "p1={}, p2={}, p3={}, p4={}, p5={}, p6={}, p7={}");
}
@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public int latency9Params(final ThreadState state) {
+ return latencyParams(state, "p1={}, p2={}, p3={}, p4={}, p5={}, p6={}, p7={}, p8={}, p9={}");
+ }
+
+ private static int latencyParams(final ThreadState state, final String pattern) {
state.buffer.setLength(0);
- final int count = ParameterFormatter.countArgumentPlaceholders(
- "p1={}, p2={}, p3={}, p4={}, p5={}, p6={}, p7={}, p8={}, p9={}");
- ParameterFormatter.formatMessage(
- state.buffer, "p1={}, p2={}, p3={}, p4={}, p5={}, p6={}, p7={}, p8={}, p9={}", ARGS, count);
+ ParameterFormatter.analyzePattern(pattern, -1, state.analysis);
+ ParameterFormatter.formatMessage(state.buffer, pattern, ARGS, state.analysis.placeholderCount, state.analysis);
return state.buffer.length();
}
}
diff --git a/src/changelog/.3.x.x/1223_change_formatted_message_heuristic.xml b/src/changelog/.3.x.x/1223_change_formatted_message_heuristic.xml
new file mode 100644
index 00000000000..4aedfc4c24c
--- /dev/null
+++ b/src/changelog/.3.x.x/1223_change_formatted_message_heuristic.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ Change the order of evaluation of `FormattedMessage` formatters.
+ Messages are evaluated using `java.util.Format` only if they don't comply to the `java.text.MessageFormat` or `ParameterizedMessage` format.
+
+
diff --git a/src/changelog/.3.x.x/1626_parameter_format_rewrite.xml b/src/changelog/.3.x.x/1626_parameter_format_rewrite.xml
new file mode 100644
index 00000000000..da776840520
--- /dev/null
+++ b/src/changelog/.3.x.x/1626_parameter_format_rewrite.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ Rewrote message parameter formatter with improved escape handling
+