Formatting Results

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Formatting Results

Fred Eisele
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: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Formatting Results

Volkan Yazıcı
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 <[hidden email]> 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: [hidden email]
> For additional commands, e-mail: [hidden email]
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Formatting Results

Fred Eisele
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ı <[hidden email]>
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 <[hidden email]>
> 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: [hidden email]
> > For additional commands, e-mail: [hidden email]
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Formatting Results

Volkan Yazıcı
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 <[hidden email]> 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ı <[hidden email]>
> 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 <[hidden email]>
> > 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: [hidden email]
> > > For additional commands, e-mail: [hidden email]
> > >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [hidden email]
> > For additional commands, e-mail: [hidden email]
> >
> >

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Formatting Results

Volkan Yazıcı
Created LOG4J2-2874[1]. Forwarding the mail to the dev list, let's see
what others think about it. Thanks for the report Fred.

[1] https://issues.apache.org/jira/browse/LOG4J2-2874

On Wed, Jun 17, 2020 at 7:41 PM Volkan Yazıcı <[hidden email]> wrote:

>
> 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 <[hidden email]> 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ı <[hidden email]>
> > 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 <[hidden email]>
> > > 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: [hidden email]
> > > > For additional commands, e-mail: [hidden email]
> > > >
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: [hidden email]
> > > For additional commands, e-mail: [hidden email]
> > >
> > >

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Formatting Results

Fred Eisele
Thanks for listening.

On Thu, Jun 18, 2020 at 4:32 AM Volkan Yazıcı <[hidden email]>
wrote:

> Created LOG4J2-2874[1]. Forwarding the mail to the dev list, let's see
> what others think about it. Thanks for the report Fred.
>
> [1] https://issues.apache.org/jira/browse/LOG4J2-2874
>
> On Wed, Jun 17, 2020 at 7:41 PM Volkan Yazıcı <[hidden email]>
> wrote:
> >
> > 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 <[hidden email]>
> 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ı <[hidden email]
> >
> > > 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 <
> [hidden email]>
> > > > 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: [hidden email]
> > > > > For additional commands, e-mail:
> [hidden email]
> > > > >
> > > >
> > > > ---------------------------------------------------------------------
> > > > To unsubscribe, e-mail: [hidden email]
> > > > For additional commands, e-mail: [hidden email]
> > > >
> > > >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>