[ 
https://issues.apache.org/jira/browse/LOG4J2-1510?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15418388#comment-15418388
 ] 

Remko Popma commented on LOG4J2-1510:
-------------------------------------

Yes, this is on purpose.  With asynchronous logging, we need to copy the 
contents of the ReusableObjectMessage (cannot pass the reference) because the 
application thread may modify the ReusableObjectMessage before the background 
thread has had a chance to write it to the log file.

There are two ways you can pass the original object to the appender or layout:
* use a parameterized message: in your code, write {{logger.info("{}", 
myObject);}} This will allow the layout or appender to obtain a reference to 
_myObject_ with {{logEvent.getMessage().getParameters()[0];}}
* switch off garbage-free mode by setting system property 
{{log4j2.enable.threadlocals}} to {{false}}. This will make Log4j use plain 
{{ObjectMessage}} instances instead of the reusable variant.

> why MutableLogEvent don't keep original log object or even the 
> ReusableObjectMessage 
> -------------------------------------------------------------------------------------
>
>                 Key: LOG4J2-1510
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-1510
>             Project: Log4j 2
>          Issue Type: Question
>          Components: Core
>    Affects Versions: 2.6.2
>            Reporter: Maple Wang
>            Priority: Blocker
>
> After upgrading Log4j from 2.5 to 2.6.2, I found that log event catched by my 
> appender is changed from Log4jLogEvent to MutableLogEvent, it's fine except 
> that I can't get the ObjectMessage from MutableLogEvent. If I sent object 
> message though log4j API like log.info(object);, I assume object can be 
> obtained in ReusableObjectMessage, but since MutableLogEvent look like don't 
> keep it as below:
> {code}
> public void setMessage(final Message msg) {
>         if (msg instanceof ReusableMessage) {
>             final ReusableMessage reusable = (ReusableMessage) msg;
>             reusable.formatTo(getMessageTextForWriting());
>             if (parameters != null) {
>                 parameters = reusable.swapParameters(parameters);
>                 parameterCount = reusable.getParameterCount();
>             }
>         } else {
>             // if the Message instance is reused, there is no point in 
> freezing its message here
>             if (!Constants.FORMAT_MESSAGES_IN_BACKGROUND && msg != null) { // 
> LOG4J2-898: user may choose
>                 msg.getFormattedMessage(); // LOG4J2-763: ask message to 
> freeze parameters
>             }
>             this.message = msg;
>         }
> }
> {code}
> So ,  when I call the getMessage from MutableLogEvent like below, I only can 
> get the instance of MutableLogEvent itself.
> {code}
> public Message getMessage() {
>         if (message == null) {
>             return (messageText == null) ? EMPTY : this;
>         }
>         return message;
>     }
> {code}
> If I use the ReusableMessageFactory and ReusableLogEventFactory, then when I 
> send out an object though API, it seems impossible to get it from 
> MutableLogEvent.
> I know I can use other MessageFactory to bypass it, but why MutableLogEvent 
> don't keep the ReusableObjectMessage or original object, is that on purpose? 
> Is there other way to get the ReusableObjectMessage or original object from 
> MutableLogEvent? 
> Best reagrds.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

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

Reply via email to