Search code examples
spring-bootlog4j2

How to print log4j2 json attributes only if it's value is present in ThreadContext using JsonLayoutTemplate


I want to log 2 custom fields in log4j2 Json Format, out of which one is having fixed value, and other one is derived from ThreadContext. I'm using JsonTemplateLayout and want to print the field only if they have some value, else ommit them from log.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
   <Appenders>
      <Console name="console" target="SYSTEM_OUT">
          <JsonTemplateLayout eventTemplateUri="classpath:JsonLayout.json">
              <EventTemplateAdditionalField key="myApp" value="MYAPPLICATION" />
              <EventTemplateAdditionalField key="customKey1" value="$${ctx:customKey1:-}" />
                        
          </JsonTemplateLayout>
      </Console>
   </Appenders>
    <Loggers>
        <Root level="info" additivity="false">
            <AppenderRef ref="console" />
        </Root>
    </Loggers>
</Configuration>

Here, I'm setting the value of customKey1 only for a few specific log statements in the my application, for rest of the log statements this customKey1 would not be set. So, my expectation is to avoid printing customKey1 in log format, but only print default fields and myApp field in logs, when the threadcontext is not set for this key.

Version Info: "org.springframework.boot:spring-boot-starter-log4j2:2.7.18" "org.apache.logging.log4j:log4j-layout-template-json:2.21.1"

With JsonLayout this works, there customKey1 is visible only when a value is set for the same in threadcontext; but with JsonTemplateLayout, the customKey1 is still visible even if customKey1 is not set.


Solution

  • <EventTemplateAdditionalField key="customKey1" value="$${ctx:customKey1:-}" />
    

    Don't use a lookup. Prefer native JTL resolvers instead:

    <EventTemplateAdditionalField key="customKey1"
                                  format="JSON"
                                  value='{"$resolver": "mdc", "key": "customKey1"}'/>
    

    This will discard customKey1 field if it is found to be blank (i.e., empty or null).