This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 8209dfc1d645ef81e07253c03281fdcfc933d50c
Author: PanLongfei <[email protected]>
AuthorDate: Sat Mar 23 20:21:33 2024 +0800

    Fix issue 2380: Log messages with sufficient parameters include exception 
should not give waring log
---
 .../log4j/message/ParameterizedMessageTest.java    | 57 +++++++++++++---------
 .../logging/log4j/message/ParameterFormatter.java  | 19 +++++---
 2 files changed, 45 insertions(+), 31 deletions(-)

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 3f6ba36da0..4bd5df91be 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
@@ -185,27 +185,44 @@ class ParameterizedMessageTest {
         
assertThat(actual.getFormattedMessage()).isEqualTo(expected.getFormattedMessage());
     }
 
-    @Test
-    void formatToWithMoreArgsButNoWarn() {
-        final String pattern = "no warn {} {}";
-        final String expectedMessage = "no warn a b";
-        final Object[] args = {"a", "b", new RuntimeException()};
+    /**
+     * In this test cases, constructed the following scenarios: <br>
+     * <p>
+     * 1. The arguments contains an exception, and the count of placeholder is 
equal to arguments include exception. <br>
+     * 2. The arguments contains an exception, and the count of placeholder is 
equal to arguments except exception.<br>
+     * All of these should not logged in status logger.
+     * </p>
+     *
+     * @return Streams
+     */
+    static Stream<Object[]> testCasesWithExceptionArgsButNoWarn() {
+        return Stream.of(
+                new Object[] {
+                    "with exception {} {}",
+                    new Object[] {"a", new RuntimeException()},
+                    "with exception a java.lang.RuntimeException"
+                },
+                new Object[] {
+                    "with exception {} {}", new Object[] {"a", "b", new 
RuntimeException()}, "with exception a b"
+                });
+    }
+
+    @ParameterizedTest
+    @MethodSource("testCasesWithExceptionArgsButNoWarn")
+    void formatToWithExceptionButNoWarn(final String pattern, final Object[] 
args, final String expected) {
         final ParameterizedMessage message = new ParameterizedMessage(pattern, 
args);
         final StringBuilder buffer = new StringBuilder();
         message.formatTo(buffer);
-        assertThat(buffer.toString()).isEqualTo(expectedMessage);
-        
assertThat(message.getThrowable()).isInstanceOf(RuntimeException.class);
+        assertThat(buffer.toString()).isEqualTo(expected);
         final List<StatusData> statusDataList = 
statusListener.getStatusData().collect(Collectors.toList());
         assertThat(statusDataList).hasSize(0);
     }
 
-    @Test
-    void formatWithMoreArgsButNoWarn() {
-        final String pattern = "no warn {} {}";
-        final String expectedMessage = "no warn a b";
-        final Object[] args = {"a", "b", new RuntimeException()};
+    @ParameterizedTest
+    @MethodSource("testCasesWithExceptionArgsButNoWarn")
+    void formatWithExceptionButNoWarn(final String pattern, final Object[] 
args, final String expected) {
         final String message = ParameterizedMessage.format(pattern, args);
-        assertThat(message).isEqualTo(expectedMessage);
+        assertThat(message).isEqualTo(expected);
         final List<StatusData> statusDataList = 
statusListener.getStatusData().collect(Collectors.toList());
         assertThat(statusDataList).hasSize(0);
     }
@@ -228,12 +245,6 @@ class ParameterizedMessageTest {
                 new Object[] {"more {} {} {}", 3, new Object[] {"a"}, "more a 
{} {}"},
                 new Object[] {"less {}", 1, new Object[] {"a", "b"}, "less a"},
                 new Object[] {"less {} {}", 2, new Object[] {"a", "b", "c"}, 
"less a b"},
-                new Object[] {
-                    "more throwable {} {}",
-                    2,
-                    new Object[] {"a", new RuntimeException()},
-                    "more throwable a java.lang.RuntimeException"
-                },
                 new Object[] {
                     "more throwable {} {} {}",
                     3,
@@ -247,8 +258,8 @@ class ParameterizedMessageTest {
 
     @ParameterizedTest
     @MethodSource("testCasesForInsufficientFormatArgs")
-    void formatTo_should_warn_on_insufficient_args(
-            final String pattern, final int placeholderCount, Object[] args, 
final String expected) {
+    void formatToShouldWarnOnInsufficientArgs(
+            final String pattern, final int placeholderCount, final Object[] 
args, final String expected) {
         final int argCount = args == null ? 0 : args.length;
         verifyFormattingFailureOnInsufficientArgs(pattern, placeholderCount, 
argCount, expected, () -> {
             final ParameterizedMessage message = new 
ParameterizedMessage(pattern, args);
@@ -260,8 +271,8 @@ class ParameterizedMessageTest {
 
     @ParameterizedTest
     @MethodSource("testCasesForInsufficientFormatArgs")
-    void format_should_warn_on_insufficient_args(
-            final String pattern, final int placeholderCount, Object[] args, 
final String expected) {
+    void formatShouldWarnOnInsufficientArgs(
+            final String pattern, final int placeholderCount, final Object[] 
args, final String expected) {
         final int argCount = args == null ? 0 : args.length;
         verifyFormattingFailureOnInsufficientArgs(
                 pattern, placeholderCount, argCount, expected, () -> 
ParameterizedMessage.format(pattern, args));
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 9964d118b7..cdc0e1de69 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
@@ -244,14 +244,17 @@ final class ParameterFormatter {
             return;
         }
 
-        // check if there are insufficient arguments that do not include 
Throwable arg
-        final int realArgCount = args.length;
-        final int noThrowableArgCount = realArgCount - ((args[realArgCount - 
1] instanceof Throwable) ? 1 : 0);
-        if (analysis.placeholderCount != noThrowableArgCount) {
-            final String message = String.format(
-                    "found %d argument placeholders, but provided %d for 
pattern `%s`",
-                    analysis.placeholderCount, realArgCount, pattern);
-            STATUS_LOGGER.warn(message);
+        // #2380: check if the count of placeholder is not equal to the count 
of arguments
+        if (analysis.placeholderCount != argCount) {
+            final int realArgCount = args.length;
+            final int noThrowableArgCount = realArgCount - ((args[realArgCount 
- 1] instanceof Throwable) ? 1 : 0);
+            if (analysis.placeholderCount != noThrowableArgCount) {
+                STATUS_LOGGER.warn(
+                        "found {} argument placeholders, but provided {} for 
pattern `{}`",
+                        analysis.placeholderCount,
+                        Math.min(realArgCount, argCount),
+                        pattern);
+            }
         }
 
         // Fast-path for patterns containing no escapes

Reply via email to