Yes, I guess I am able to reproduce the error. Given the following 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. Would anybody mind
confirming the bug, please? If so, I will create a JIRA ticket and a
branch containing the reproduction test(s).
Kind regards.
On Wed, Jun 17, 2020 at 6:53 PM Fred Eisele <[email protected]> wrote:
>
> You are right I need to give more detail.
>
> If the first argument is a String then it is presumed to be a format
> specification.
> In that case the second argument, if it is a StringBuilderFormattable, has
> its formatTo() method called.
> [All good]
>
> If the first argument is a Message then the formatTo() is not called.
>
> class Foo implements StringBuilderFormattable {
> @Override
> public void formatTo(StringBuilder buffer) { buffer.append("bar"); }
> }
> ...
> final Message em = log.traceEntry();
> ...
> log.traceExit("{}", new Foo()); // logs the formatTo method [all good]
> log.traceExit(em, new Foo()); // logs the toString method *[not what I
> expected]*
>
>
>
> On Wed, Jun 17, 2020 at 4:05 AM Volkan Yazıcı <[email protected]>
> wrote:
>
> > Hello Fred,
> >
> > If the Message you pass to traceExit(Message,R) implements
> > StringBuilderFormattable, indeed formatTo(StringBuilder) will be used
> > by the layout for serialization. What do you mean by "this does not
> > seem to be the case"? Would you mind elaborating a bit more on what
> > you're exactly trying to do? Further, a reproduction path will be
> > greatly appreciated.
> >
> > Kind regards.
> >
> > On Tue, Jun 16, 2020 at 4:16 PM Fred Eisele <[email protected]>
> > wrote:
> > >
> > > When traceExit(m,r) is used...
> > > Is there a mechanism for controlling the formatting of the result?
> > > Other than overriding the 'toString()' method.
> > > When formatted messages are used and the object's class implements
> > > the StringBuilderFormattable interface the 'formatTo()' method
> > > is used preferentially over 'toString()'.
> > > This does not seem to be the case for serializing the result by
> > traceExit.
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: [email protected]
> > > For additional commands, e-mail: [email protected]
> > >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [email protected]
> > For additional commands, e-mail: [email protected]
> >
> >
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]