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

Zack Slayton commented on LOG4J2-2118:
--------------------------------------

[[email protected]] Ah, that makes sense! Thank you for taking the time to 
explain it. I'll look into making a custom `Message` type.

[~garydgregory] I'm planning to make a binary `Layout` that encodes each 
message's components using [Jackson 2.9's new support for the Ion 
format|https://github.com/FasterXML/jackson/wiki/Jackson-Release-2.9#dataformat-ion].
 It ticks a lot of the feature boxes mentioned in 
[LOG4J2-1305|https://issues.apache.org/jira/browse/LOG4J2-1305]: it supports 
string lookup tables, has bindings in several languages, and field byte lengths 
are included in the encoding. As an added bonus, you don't have to encode 
logged parameters as text -- there's [a rich type 
system|https://amzn.github.io/ion-docs/] to take advantage of.

> MutableLogEvent does not retain the Message format string
> ---------------------------------------------------------
>
>                 Key: LOG4J2-2118
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-2118
>             Project: Log4j 2
>          Issue Type: Bug
>          Components: Layouts
>    Affects Versions: 2.8
>         Environment: Mac OS X 10.11.6
> Java 1.8.0_141
>            Reporter: Zack Slayton
>              Labels: layout
>
> I'm attempting to create a custom binary Layout that stores the provided 
> format string separate from the parameters rather than eagerly formatting 
> them all into a single piece of text. However, when I went to implement 
> `Layout::toByteArray`, I discovered that the `Message::getFormat` method 
> always returns null.
> {code:java}
> import org.apache.logging.log4j.LogManager;
> import org.apache.logging.log4j.Logger;
> import org.apache.logging.log4j.core.LogEvent;
> import org.apache.logging.log4j.core.config.plugins.Plugin;
> import org.apache.logging.log4j.core.config.plugins.PluginFactory;
> import org.apache.logging.log4j.core.layout.AbstractLayout;
> import java.io.Serializable;
> import java.util.Arrays;
> @Plugin(name = "MyLayout", category = "Core", elementType = "layout", 
> printObject = true)
> public class MyLayout extends AbstractLayout {
>     public MyLayout() {
>         super(null, null, null);
>     }
>     @PluginFactory
>     public static MyLayout createLayout(){
>         return new MyLayout();
>     }
>     public static void main(String[] args) {
>         Logger log = LogManager.getLogger(MyLayout.class);
>         log.info("Here's a thing: {}. And another: {}", 75, "walrus");
>     }
>     @Override
>     public byte[] toByteArray(LogEvent event) {
>         System.out.println("Format: " + event.getMessage().getFormat());
>         System.out.println("Parameters: " + 
> Arrays.toString(event.getMessage().getParameters()));
>         return new byte[0];
>     }
>     @Override
>     public Serializable toSerializable(LogEvent event) {
>         return null;
>     }
>     @Override
>     public String getContentType() {
>         return null;
>     }
>     @Override
>     public byte[] getFooter() {
>         return new byte[0];
>     }
>     @Override
>     public byte[] getHeader() {
>         return new byte[0];
>     }
> }
> {code}
> If I run `main` (with an extra `PatternLayout`+`Console` appender in my 
> config), I see the following output:
> {code}
> 17:55:28.524 [main] INFO  com.example.logging.plugins.MyLayout - Here's a 
> thing: 75. And another: walrus
> Format: null
> Parameters: [75, walrus]
> {code}
> I had expected to be able to see the format string and the array of 
> parameters, but instead I can only see the parameters. The format string is 
> always null.
> This appears to be due to the implementation of `MutableLogEvent::setMessage` 
> highlighted [in 
> LOG4J2-1510|https://issues.apache.org/jira/browse/LOG4J2-1510]. Because the 
> messages are reusable, they appear to be eagerly formatted and the format 
> string itself is discarded. The `getFormat` method is hardcoded to return 
> `null`.
> Is this by design? If so, what is the prescribed approach to getting the 
> format string in my layout? (Preferably one that does not disable the 
> performance optimizations offered by enabling threadlocals.)
> Thanks!



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to