<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration scan="true" scanPeriod="60 seconds">
<springProperty scope="context" name="LOG_FILE" source="logging.file.name"/>
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
<springProperty scope="context" name="MAX_SIZE" source="logging.file.max-size" defaultValue="3GB"/>
<springProperty scope="context" name="LOG_DIR" source="logging.file.path" defaultValue="./log/"/>
<springProperty scope="context" name="MAX_HISTORY" source="logging.file.max-history" defaultValue="90"/>
<springProperty scope="context" name="DAILY_LOG_DIR" source="app.log.daily-log-dir" defaultValue="./log/"/>
<springProperty scope="context" name="LOG_FILE_ENABLED" source="app.log.file.enabled" defaultValue="true"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/${LOG_FILE}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${DAILY_LOG_DIR}/${LOG_FILE}.%d{yyyy-MM-dd}.log</fileNamePattern>
<totalSizeCap>${MAX_SIZE}</totalSizeCap>
<maxHistory>${MAX_HISTORY}</maxHistory>
</rollingPolicy>
<!-- logstash logback encoder -->
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<pattern>yyyy-MM-dd'T'HH:mm:ss.SSS,Asia/Dhaka</pattern>
<timeZone>Etc/UTC</timeZone>
</timestamp>
<callerData/>
<logLevel/>
<mdc/>
<loggerName>
<shortenedLoggerNameLength>40</shortenedLoggerNameLength>
</loggerName>
<throwableClassName/>
<throwableRootCauseClassName/>
<pattern>
<pattern>
{
"appname": "${APP_NAME}"
}
</pattern>
</pattern>
<logstashMarkers/>
<threadName/>
<message/>
<tags />
<stackTrace>
<throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
<maxDepthPerThrowable>20</maxDepthPerThrowable>
<maxLength>2048</maxLength>
<shortenedClassNameLength>40</shortenedClassNameLength>
<!-- generated class names -->
<exclude>\$\$FastClassByCGLIB\$\$</exclude>
<exclude>\$\$EnhancerBySpringCGLIB\$\$</exclude>
<exclude>^sun\.reflect\..*\.invoke</exclude>
<!-- JDK internals -->
<exclude>^com\.sun\.</exclude>
<exclude>^sun\.net\.</exclude>
<!-- dynamic invocation -->
<exclude>^net\.sf\.cglib\.proxy\.MethodProxy\.invoke</exclude>
<exclude>^org\.springframework\.cglib\.</exclude>
<exclude>^org\.springframework\.transaction\.</exclude>
<exclude>^org\.springframework\.validation\.</exclude>
<exclude>^org\.springframework\.app\.</exclude>
<exclude>^org\.springframework\.aop\.</exclude>
<exclude>^java\.lang\.reflect\.Method\.invoke</exclude>
<!-- Spring plumbing -->
<exclude>^org\.springframework\.ws\..*\.invoke</exclude>
<exclude>^org\.springframework\.ws\.transport\.</exclude>
<exclude>^org\.springframework\.ws\.soap\.saaj\.SaajSoapMessage\.</exclude>
<exclude>^org\.springframework\.ws\.client\.core\.WebServiceTemplate\.</exclude>
<exclude>^org\.springframework\.web\.filter\.</exclude>
<!-- Tomcat internals -->
<exclude>^org\.apache\.tomcat\.</exclude>
<exclude>^org\.apache\.catalina\.</exclude>
<exclude>^org\.apache\.coyote\.</exclude>
<exclude>^java\.util\.concurrent\.ThreadPoolExecutor\.runWorker</exclude>
<exclude>^java\.lang\.Thread\.run$</exclude>
<rootCauseFirst>true</rootCauseFirst>
<inlineHash>true</inlineHash>
</throwableConverter>
</stackTrace>
<arguments/>
<sequence/>
</providers>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<withJansi>true</withJansi>
<encoder>
<pattern>
%d{dd-MM-yyyy HH:mm:ss.SSS} %magenta([%thread]) %highlight(%-5level) %logger{36}.%M - %boldGreen(%msg)
%n%boldRed(%ex)
</pattern>
</encoder>
</appender>
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<root level="${logging.level.root}">
<if condition='"${LOG_FILE_ENABLED}".equals("true")'>
<then>
<appender-ref ref="FILE"/>
<appender-ref ref="STDOUT"/>
</then>
<else>
<appender-ref ref="STDOUT"/>
</else>
</if>
</root>
</configuration>