Logging with separation based on service Class

Posted By : Harshit Verma | 21-Sep-2018

One of the novel features of Logback is "SiftingAppender". It's a proxy appender that creates the one-child appender per each unique value of the given runtime property. Typically this property is taken from the MDC. The basic idea of the Mapped Diagnostic Context is to provide the way to enrich log messages with pieces of the information that could be not available in scope where the logging actually occurs, but that can be indeed useful to the better track execution of the program.

The MDC is available in the SLF4J too, under a condition that it is supported by the underlying logging library. Both the Logback and the Log4j supports the MDC as we have just seen, so we need nothing special to use it with the standard set up.MDC has lots of applications, mainly in the scenarios in which execution of the several different threads causes the interleaved log messages that, would be otherwise, it's hard to read.

You can set the value of MDC in any filters, as I stated that :

@Aspect
@Component
public class UserActionsLogAudit {
    private static Logger log = LoggerFactory.getLogger(AuthenticationFilter.class);
    @Around("@annotation(org.springframework.web.bind.annotation.RequestMapping) ")
    public Object auditLog(final ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .currentRequestAttributes())
                .getRequest();
        Object value;
        try {
            value = proceedingJoinPoint.proceed();


        } catch (Throwable throwable) {
            throw throwable;
        } finally {        
            String service = request.getRequestURI();
            String result = service.split("/")[3];
            MDC.put("service",result);
           log.info(
            "  [HttpMethod -> {}, Method-Name -> {}, by user -> {} , from the IP address ->{}]",               
                    request.getMethod(),
                    request.getRequestURI(),
                    request.getRemoteUser(),
                    request.getLocalAddr()
            );
        }
        return value;
    }
}

Now, we are going to configure the logback.xml, for the sift appender with the combination of rollingFileAppender that archive the log file, and creates the new log file as per the new service. It will generate a new file as per the service class and the default logs are getting recorded in the default log file. We can apply more filter if we want, as it must be more configurable.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="logPattern"
              value="%date{'yyyy-MM-dd', UTC} %d{HH:mm:ss.SSS} %-4relative [%thread] %-5level %logger{35} - %msg%n" />
    <property name="logEncoding" value="UTF-8" />

    <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook" />

    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
        <discriminator>
            <key>service</key>
            <defaultValue>unknown</defaultValue>
        </discriminator>
       <sift>

            <appender name="FILE-${service}"
                      class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>${logDirectory}/${service}.log</file>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <fileNamePattern>${logDirectory}/${archive}/${service}_%d{yyyy-MM-dd}.%i.log
                    </fileNamePattern>
                    <timeBasedFileNamingAndTriggeringPolicy
                            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                        <maxFileSize>60MB</maxFileSize>
                    </timeBasedFileNamingAndTriggeringPolicy>
                </rollingPolicy>
                <encoder>
                    <charset>${logEncoding}</charset>
                    <pattern>${logPattern}</pattern>
                </encoder>

            </appender>
        </sift>
    </appender>

    <root level="ALL">
        <appender-ref ref="SIFT" />
    </root>
</configuration>
Related Tags

About Author

Author Image
Harshit Verma

Harshit is a bright Web Developer with expertise in Java and Spring framework and ORM tools Hibernate.

Request for Proposal

Name is required

Comment is required

Sending message..