[ 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)