qos-ch / logback

The reliable, generic, fast and flexible logging framework for Java.
http://logback.qos.ch
Other
3.01k stars 1.28k forks source link

Last argument of log message stripped if Throwable, even when cause is given as well #876

Open Maldivia opened 5 hours ago

Maldivia commented 5 hours ago

If a Throwable type is passed to match the last {} argument, it is ignored, and the formatted log message will write {} instead.

Example:

package com.test;

import ch.qos.logback.core.Appender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;

public class Test {
  static final Logger log = LoggerFactory.getLogger(Test.class);

  public static void main(String[] args) {
    log.info("SLF4J Version: {}", Logger.class.getPackage().getImplementationVersion());
    log.info("Logback Version: {}", Appender.class.getPackage().getImplementationVersion());

    Exception ex = new CustomException("Some message");
    log.error("Exception Message: {}", ex, ex);

    log.makeLoggingEventBuilder(Level.WARN)
        .setMessage("Exception Message: {}")
        .addArgument(ex)
        .setCause(ex)
        .log();
  }

  static class CustomException extends Exception {
    public CustomException(String msg) {
      super(msg);
    }

    @Override
    public String toString() {
      return "Custom Message";
    }
  }
}

Expected output:

[main] INFO com.test.Test -- SLF4J Version: 2.0.15
[main] INFO com.test.Test -- Logback Version: 1.5.11
[main] ERROR com.test.Test -- Exception Message: Custom Message
com.test.Test$CustomException: Some message
    at com.test.Test.main(Test.java:15)
[main] WARN com.test.Test -- Exception Message: Custom Message
com.test.Test$CustomException: Some message
    at com.test.Test.main(Test.java:15)

Actual output:

[main] INFO com.test.Test -- SLF4J Version: 2.0.15
[main] INFO com.test.Test -- Logback Version: 1.5.11
[main] ERROR com.test.Test -- Exception Message: {}
com.test.Test$CustomException: Some message
    at com.test.Test.main(Test.java:15)
[main] WARN com.test.Test -- Exception Message: {}
com.test.Test$CustomException: Some message
    at com.test.Test.main(Test.java:15)

Workaround: Explicitly calling .toString() on the argument (log.error("Exception Message: {}", ex.toString(), ex)), or adding a bogus extra "" argument (log.error("Exception Message: {}", ex, "", ex)) works as a work around, but causes static analysis tools, including the one in IntelliJ, to warn about it.

ceki commented 4 hours ago

Linked to https://jira.qos.ch/browse/LOGBACK-1775

ceki commented 3 hours ago

@Maldivia

Thank you for this report. Issue fixed in commit 85968fa3fe217a79760ec2b4a275e68cefeb8656

Please note that log.makeLoggingEventBuilder(Level.WARN) is a longer form for log.atWarn().