You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@logging.apache.org by "Volkan Yazici (Jira)" <ji...@apache.org> on 2022/01/21 13:22:00 UTC

[jira] [Commented] (LOG4J2-3358) 2.17.1: JsonLayout Context no longer working.

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

Volkan Yazici commented on LOG4J2-3358:
---------------------------------------

For one, I strongly recommend you to use [JSON Template Layout|https://logging.apache.org/log4j/2.x/manual/json-template-layout.html] instead, which is the successor to JSON Layout. I would personally refrain from lookups depending on the user-provided (i.e., {{LogEvent}}) data. Using {{mdc}} resolver of JSON Template Layout, you can have your configuration as follows:

{code:java}
JsonTemplateLayout layout = JsonTemplateLayout
        .newBuilder()
        .setConfiguration(new DefaultConfiguration())
        .setEventTemplateUri("classpath:JsonLayout.json")
        .setStackTraceEnabled(true)
        .setLocationInfoEnabled(true)
        .setEventTemplateAdditionalFields(new EventTemplateAdditionalField[] {
                EventTemplateAdditionalField
                        .newBuilder()
                        .setFormat(EventTemplateAdditionalField.Format.JSON)
                        .setKey("who")
                        .setValue("{'$resolver': 'mdc', 'key': 'WHO', 'stringified': true}".replaceAll("'", "\""))
                        .build(),
                EventTemplateAdditionalField
                        .newBuilder()
                        .setFormat(EventTemplateAdditionalField.Format.JSON)
                        .setKey("what")
                        .setValue("{'$resolver': 'mdc', 'key': 'WHAT', 'stringified': true}".replaceAll("'", "\""))
                        .build(),
                EventTemplateAdditionalField
                        .newBuilder()
                        .setFormat(EventTemplateAdditionalField.Format.JSON)
                        .setKey("method")
                        .setValue("{'$resolver': 'mdc', 'key': 'METHOD', 'stringified': true}".replaceAll("'", "\""))
                        .build(),
                EventTemplateAdditionalField
                        .newBuilder()
                        .setFormat(EventTemplateAdditionalField.Format.JSON)
                        .setKey("parameters")
                        .setValue("{'$resolver': 'mdc', 'key': 'PARAMETERS', 'stringified': true}".replaceAll("'", "\""))
                        .build(),
        })
        .build();
{code}

That said, I can indeed reproduce the issue. The following test passes on 2.17.0 and fails on 2.17.1:

{code:java}
@Test
public void jsonLayout_should_substitute_lookups() {

    // Create the layout.
    KeyValuePair[] additionalFields = {
            KeyValuePair
                    .newBuilder()
                    .setKey("who")
                    .setValue("${ctx:WHO}")
                    .build()
    };
    JsonLayout layout = JsonLayout
            .newBuilder()
            .setConfiguration(new DefaultConfiguration())
            .setAdditionalFields(additionalFields)
            .build();

    // Create a log event containing `WHO` key in MDC.
    StringMap contextData = ContextDataFactory.createContextData();
    contextData.putValue("WHO", "mduft");
    LogEvent logEvent = Log4jLogEvent
            .newBuilder()
            .setContextData(contextData)
            .build();

    // Verify the `WHO` key.
    String serializedLogEvent = layout.toSerializable(logEvent);
    assertThat(serializedLogEvent).contains("\"who\": \"mduft\"");

}
{code}

I will try to figure out what is going on.

> 2.17.1: JsonLayout Context no longer working.
> ---------------------------------------------
>
>                 Key: LOG4J2-3358
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-3358
>             Project: Log4j 2
>          Issue Type: Bug
>          Components: Layouts
>    Affects Versions: 2.17.1
>            Reporter: Markus Duft
>            Priority: Major
>
> We're creating a RollingFileAppender programmatically using a JsonLayout. This uses fields using ${ctx:...} expansion. This stopped working when upgrading from 2.17.0 to 2.17.1.
> The code is as follows:
> {code:java}
> /**
>      * Creates a rolling file appender that write audit entries to a programmatically readable JSON file.
>      */
>     private RollingFileAppender createJsonAppender(Path logDir) {
>         List<KeyValuePair> fields = new ArrayList<>();
>         fields.add(KeyValuePair.newBuilder().setKey("who").setValue("${ctx:WHO}").build());
>         fields.add(KeyValuePair.newBuilder().setKey("what").setValue("${ctx:WHAT}").build());
>         fields.add(KeyValuePair.newBuilder().setKey("method").setValue("${ctx:METHOD}").build());
>         fields.add(KeyValuePair.newBuilder().setKey("parameters").setValue("${ctx:PARAMETERS}").build());        
>         RollingFileAppender.Builder<?> builder = RollingFileAppender.newBuilder();
>         builder.setName("auditJsonLogger");
>         builder.withFileName(logDir.resolve(LOG_JSON_FILENAME).toString());
>         builder.withFilePattern(logDir.resolve(LOG_JSON_FILEPATTERN).toString());
>         builder.withPolicy(SizeBasedTriggeringPolicy.createPolicy("10M"));
>         builder.setLayout(JsonLayout.newBuilder().setCompact(true).setEventEol(true).setConfiguration(new DefaultConfiguration())
>                 .setAdditionalFields(fields.toArray(new KeyValuePair[0])).build());
>         builder.withStrategy(
>                 DefaultRolloverStrategy.newBuilder().withCompressionLevelStr(String.valueOf(Deflater.DEFAULT_COMPRESSION))
>                         .withMax(Integer.toString(LOG_MAX_INDEX)).withFileIndex("min").build());
>         return builder.build();
>     } {code}
> We also tried to use %X\{...} as well as $${ctx:...} expansions instead to no avail. The log file always contains the *literal* string we use in .setValue(), i.e. lines like this:
> {noformat}
> {"instant":{"epochSecond":1642756242,"nanoOfSecond":271091900},"thread":"hive/fsck","level":"INFO","message":"Execute","endOfBatch":false,"threadId":65,"threadPriority":5,"who":"${ctx:WHO}","what":"${ctx:WHAT}","method":"${ctx:METHOD}","parameters":"${ctx:PARAMETERS}"}{noformat}
> Reverting to 2.17.0 will correctly give lines like this in the JSON file:
> {noformat}
> {"instant":{"epochSecond":1642756430,"nanoOfSecond":923210700},"thread":"hive/fsck","level":"INFO","message":"Execute","endOfBatch":false,"threadId":62,"threadPriority":5,"who":"marku","what":"ObjectConsistencyCheckOperation","method":"-","parameters":"{dryRun=false, roots=[io.bdeploy/demo/client-app/linux:1.0.0, io.bdeploy/demo/client-app/linux:2.0.0, io.bdeploy/demo/client-app/windows:1.0.0, ...]}"}{noformat}



--
This message was sent by Atlassian Jira
(v8.20.1#820001)