Matthew Campbell
Matthew Campbell

Reputation: 1884

logback, How to change message in logging event before appending

Using logback 1.2.3 and Java 9...

Googled around trying to find a built-in way to alter the log message before it hits an appender. Is the only way through an encoder slash layout? Basically looking for the something like enrichment as provided by Serilog where you can alter a message (event) before it drops into a sink.

Here is the use case: before a log event makes it's way to an appender a hook is needed to at least alter the message text.

Upvotes: 12

Views: 11003

Answers (2)

glytching
glytching

Reputation: 47905

Logback's PatternLayout contains defaultConverterMap which maps conversion words (%msg, %n, %ex etc) to implementations of ch.qos.logback.core.pattern.Converter.

You could provide your own implementation of MessageConverter and associate it with a custom conversion word as follows:

  1. Add this to logback.xml

     <!-- using mx to imply 'message extended' -->
     <conversionRule conversionWord="mx" converterClass="some.package.CustomMessageConverter" />
    
  2. Implement some.package.CustomMessageConverter as follows:

     import ch.qos.logback.classic.pattern.MessageConverter;
     import ch.qos.logback.classic.spi.ILoggingEvent;
    
     public class CustomMessageConverter extends MessageConverter {
    
         public String convert(ILoggingEvent event) {
             return enhance(super.convert(event));
         }
    
         // implement your "hook ... to at least alter the message text"
         private String enhance(String incoming) {
             // ...
         }
     }
    
  3. Update your encoder pattern to use the conversion word mx:

     <encoder>
         <pattern>%d{yyyy-MM-dd HH:mm:ss}|[%thread]|[%X{complexNestedValue:-NA}]|%-5level|%logger{36}|%mx %n</pattern>
     </encoder>
    

With these changes in place your custom converter will be engaged and the output will include whatever CustomMessageConverter.convert returns for each log event

Upvotes: 13

Steve Lohse
Steve Lohse

Reputation: 31

Just extending on glytching's answer, you can pass a Spring property to the CustomMessageConverter if required.

In your application.yml

my.logging.properties: PropertyOne, PropertyTwo

In your logback.xml

<springProperty scope="context" name="myLoggingPoperties" source="my.logging.properties"/>

Your encoder pattern becomes

<encoder>
    <pattern>%d{yyyy-MM-dd HH:mm:ss}|[%thread]|[%X{complexNestedValue:-NA}]|%-5level|%logger{36}|%mx{${myLoggingPoperties}} %n</pattern>
</encoder>

The properties are available as a List<String> in your CustomMessageConverter

// implement your "hook ... to at least alter the message text"
private String enhance(String incoming) {
  List<String> properties = getOptionList();
  // ...
}

Upvotes: 3

Related Questions