logbackspring-logbacklogstash-logback-encoder

How to pass the Patten and JsonFactoryDecorator programmatically in Logback in spring application


This is my logback.spring.xml

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                
                <arguments/>
               
                <stackTrace/>
               
                <mdc>
                    <excludeMdcKeyName>ClaimNo</excludeMdcKeyName>
                    <excludeMdcKeyName>ClaimId</excludeMdcKeyName>
                </mdc>
                <pattern>
                    <pattern>
                        {
                        "Claim": "[${logback.company}, ${logback.info}]",  // YML file value 
                        "Log level": "${logback.level}",    // YML value 
                        "Time": "%date",
                        "Thread ID": "%thread",
                        "claimId":"[%X{claimId}]",   //MDC key 
                        "Claim no": "[%X{CliamNo}]", // MDC Key
                        "Logger": "%logger",
                        "Message": "%msg"
                        }
                    </pattern>
                </pattern>
            </providers>
            <jsonFactoryDecorator class="net.logstash.logback.decorate.CharacterEscapesJsonFactoryDecorator">
                <escape>
                    <targetCharacterCode>9</targetCharacterCode> <!-- Tab-->
                    <escapeSequence></escapeSequence>
                </escape>
                <escape>
                    <targetCharacterCode>10</targetCharacterCode>  <!-- New Line-->
                    <escapeSequence></escapeSequence>
                </escape>
            </jsonFactoryDecorator>
        </encoder>

Since I am using different appender with same encode pattern and in order to reuse the pattern, I am trying to add programmatically as like below, but here I am not sure how to pass pattern, MDC value and CharacterEscapesJsonFactoryDecorator from class level. Please can you help me on this.

public class JsonEncoder extends LoggingEventCompositeJsonEncoder {
    public JsonEncoder() {
    }
    @Override
    public void start() {
       

        List<String> mdcList = new ArrayList<String>();
        mdcList.add("ClaimNo");
        mdcList.add("CliamId");
        MdcJsonProvider mdcJsonProvider= new MdcJsonProvider();
        mdcJsonProvider.setExcludeMdcKeyNames(mdcList);

        JsonProviders<ILoggingEvent> providers = getProviders();
        providers.addProvider(mdcJsonProvider);
        
        super.start();
    }
}

Logback.spring.xml

<encoder class="com.solution.JsonEncoder"></encoder>

Solution

  • The xml element names match the setter/adder methods on the underlying configuration classes.

    Also note that the pattern value should not contain comments.

    public class JsonEncoder extends LoggingEventCompositeJsonEncoder {
    
        @Override
        public void start() {
            /*
             * <providers>
             */
            JsonProviders<ILoggingEvent> providers = getProviders();
            providers.setContext(getContext());
    
            /*
             * <arguments/>
             */
            providers.addProvider(new ArgumentsJsonProvider());
    
            /*
             * <stackTrace/>
             */
            providers.addProvider(new StackTraceJsonProvider());
    
    
            /*
             * <mdc>
             *     <excludeMdcKeyName>ClaimNo</excludeMdcKeyName>
             *     <excludeMdcKeyName>ClaimId</excludeMdcKeyName>
             * </mdc>
             */
            MdcJsonProvider mdcJsonProvider= new MdcJsonProvider();
            List<String> mdcList = new ArrayList<String>();
            mdcList.add("ClaimNo");
            mdcList.add("ClaimId");
            mdcJsonProvider.setExcludeMdcKeyNames(mdcList);
            providers.addProvider(mdcJsonProvider);
    
            /*
             * <pattern>
             *     <pattern>...</pattern>
             * </pattern>
             */
            LoggingEventPatternJsonProvider patternJsonProvider = new LoggingEventPatternJsonProvider();
            patternJsonProvider.setPattern("{\n" +
                    "\"Claim\": \"[${logback.company}, ${logback.info}]\",\n" +
                    "\"Log level\": \"${logback.level}\",\n" +
                    "\"Time\": \"%date\",\n" +
                    "\"Thread ID\": \"%thread\",\n" +
                    "\"claimId\":\"[%X{claimId}]\",\n" +
                    "\"Claim no\": \"[%X{CliamNo}]\",\n" +
                    "\"Logger\": \"%logger\",\n" +
                    "\"Message\": \"%msg\"\n" +
                    "}");
            providers.addProvider(patternJsonProvider);
    
            /*
             * </providers>
             */
    
            /*
             * <jsonFactoryDecorator class="net.logstash.logback.decorate.CharacterEscapesJsonFactoryDecorator">
             *     <escape>
             *         <targetCharacterCode>9</targetCharacterCode> <!-- Tab-->
             *         <escapeSequence></escapeSequence>
             *     </escape>
             *     <escape>
             *         <targetCharacterCode>10</targetCharacterCode>  <!-- New Line-->
             *         <escapeSequence></escapeSequence>
             *     </escape>
             * </jsonFactoryDecorator>
             */
            CharacterEscapesJsonFactoryDecorator jsonFactoryDecorator = new CharacterEscapesJsonFactoryDecorator();
    
            CharacterEscapesJsonFactoryDecorator.Escape escape1 = new CharacterEscapesJsonFactoryDecorator.Escape();
            escape1.setTargetCharacterCode(9);
            escape1.setEscapeSequence("");
            jsonFactoryDecorator.addEscape(escape1);
    
            CharacterEscapesJsonFactoryDecorator.Escape escape2 = new CharacterEscapesJsonFactoryDecorator.Escape();
            escape2.setTargetCharacterCode(10);
            escape2.setEscapeSequence("");
            jsonFactoryDecorator.addEscape(escape2);
    
            setJsonFactoryDecorator(jsonFactoryDecorator);
    
            super.start();
        }
    }