Uploaded image for project: 'Log4j 2'
  1. Log4j 2
  2. LOG4J2-2874

StringBuilderFormattable check failure in layouts due to wrapped Message

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Open
    • Priority: Blocker
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None

      Description

      Upon further investigation on Fred Eisele's question in the mailing list, I figured Layout's way of handling Message's of type StringBuilderFormattable is broken when the actual message is wrapped by some other message. Consider the following Java code:

      import org.apache.logging.log4j.message.Message;
      import org.apache.logging.log4j.util.StringBuilderFormattable;
      import org.junit.Test;
      
      public class TraceExitTest {
      
          @Test
          public void test() {
              System.setProperty(
                      "log4j.configurationFile",
                      "/tmp/traceExit.xml");
              Logger logger = LogManager.getLogger("TraceExit");
              int result = logger.traceExit(
                      new CustomMessage("Volkan was here"),
                      1);
              logger.warn("result = %d", result);
          }
      
          private static final class CustomMessage
                  implements Message, StringBuilderFormattable {
      
              private final String text;
      
              private CustomMessage(String text) {
                  this.text = text;
              }
      
              @Override
              public String getFormattedMessage() {
                  throw new UnsupportedOperationException();
              }
      
              @Override
              public String getFormat() {
                  return "";
              }
      
              @Override
              public Object[] getParameters() {
                  return new Object[0];
              }
      
              @Override
              public Throwable getThrowable() {
                  return null;
              }
      
              @Override
              public void formatTo(StringBuilder buffer) {
                  buffer.append(text);
              }
      
          }
      
      }
      

      In combination with the following /tmp/traceExit.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <Configuration status="ERROR">
          <Appenders>
              <Console name="Console" target="SYSTEM_OUT">
                  <PatternLayout pattern="%msg%n%throwable"/>
              </Console>
          </Appenders>
          <Loggers>
              <Root level="TRACE">
                  <AppenderRef ref="Console"/>
              </Root>
          </Loggers>
      </Configuration>
      

      Log4j produces the An exception occurred processing Appender Console java.lang.UnsupportedOperationException error message. In the case of
      PatternLayout, it handles StringBuilderFormattable with a simple
      instanceof check – just like any other layout. Though check out the
      following AbstractLogger#traceExit() implementation:

      @Override
      public <R> R traceExit(final Message message, final R result) {
          // If the message is null, traceEnter returned null because ...
          if (message != null && isEnabled(Level.TRACE, EXIT_MARKER, message, null)) {
              logMessageSafely(...,
      flowMessageFactory.newExitMessage(result, message), null);
          }
          return result;
      }
      

       
      CustomMessage gets wrapped by a DefaultFlowMessageFactory.SimpleExitMessage invalidating the instanceof StringBuilderFormattable check.

      One can fix the existing layouts by improving the check as follows:

      final boolean formattable =
              logEvent.getMessage() instanceof StringBuilderFormattable ||
                      (logEvent.getMessage() instanceof FlowMessage && ((FlowMessage) logEvent.getMessage()) instanceof StringBuilderFormattable);
      

      Though I have my doubts if this will cover every single case.

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              vy Volkan Yazici
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated: