backtony/blog-code

[spring] logback-access

backtony opened this issue · 0 comments

logback-access

implementation 'ch.qos.logback:logback-access:1.2.7'
implementation 'ch.qos.logback:logback-classic:1.2.7'
implementation 'ch.qos.logback:logback-core:1.2.7'
implementation 'net.logstash.logback:logstash-logback-encoder:7.0.1'

버전에 맞는 logback을 선택하면 된다.
기본적으로 spring에는 기본적으로 logback-classic과 logback core가 포함되어 있는데 access는 따로 추가해줘야 한다.
external libraries에 보면 어떤 버전이 포함되어있는지 확인할 수 있고 각 버전을 같은 것으로 맞춰줘야 한다.
logstash logback을 추가하는 이유는 logstash logback에서 jsonEncoder를 제공하기 때문에 유용하게 사용할 수 있다.

logback access는 기본적으로 resources 위치에 logback-access.xml 파일을 찾아서 세팅한다. 환경별로 세팅해주기 위해서는 커스텀이 필요하다.

// https://logback.qos.ch/access.html
// LogbackValve는 tomcat의 LogbackValve를 확장한 것이다.
@Configuration
public class AccessLogsConfig {

    @Value("${spring.profiles.active}")
    private String profile;

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> webServerFactoryCustomizer() {
        return factory -> {
            LogbackValve logbackValve = new LogbackValve();
            // profile에 따라서 logback access 설정 파일 이름을 찾도록 변경
            logbackValve.setFilename("logback-access-" + profile + ".xml");
            logbackValve.setAsyncSupported(true);
            factory.addContextValves(logbackValve);
        };¡
    }
}

보통 access 설정 파일은 다음과 같이 세팅한다.

<!-- logback-access-local.xml -->
<configuration debug="false">
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!-- logstash logback 에서 제공하는 jsonEncoder를 사용 -->
        <encoder class="net.logstash.logback.encoder.AccessEventCompositeJsonEncoder">
            <providers>
                <pattern>
                    <omitEmptyFields>true</omitEmptyFields>
                    <pattern>
                        {
                        "date": "%date{yyyy-MM-dd'T'HH:mm:ssXXX}",
                        "remoteAddr": "%a",
                        "request": "%r",
                        "user": "%reqAttribute{userId}",
                        "httpXForwardedFor": "%i{X-Forwarded-For}",
                        "referer": "%i{Referer}",
                        "userAgent": "%i{User-Agent}",
                        "byteSent": "#asLong{%B}",
                        "duration": "#asDouble{%T}",
                        "status": "%s",
                        "contentType": "%responseHeader{Content-Type}"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
    </appender>
    <appender-ref ref="console"/>
</configuration>
<!-- logback-access-dev.xml -->
<configuration debug="false">
    <appender name="access.file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/Users/user/Desktop/blog-code/spring-logback/src/main/resources/access.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/Users/user/Desktop/blog-code/spring-logback/src/main/resources/access.log.%d{yyyyMMdd}</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>

        <!-- logstash logback 에서 제공하는 jsonEncoder를 사용 -->
        <encoder class="net.logstash.logback.encoder.AccessEventCompositeJsonEncoder">
            <providers>
                <pattern>
                    <omitEmptyFields>true</omitEmptyFields>
                    <pattern>
                        {
                        "date": "%date{yyyy-MM-dd'T'HH:mm:ssXXX}",
                        "remoteAddr": "%a",
                        "request": "%r",
                        "user": "%reqAttribute{userId}",
                        "httpXForwardedFor": "%i{X-Forwarded-For}",
                        "referer": "%i{Referer}",
                        "userAgent": "%i{User-Agent}",
                        "byteSent": "#asLong{%B}",
                        "duration": "#asDouble{%T}",
                        "status": "%s",
                        "contentType": "%responseHeader{Content-Type}"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
    </appender>

    <!-- logstash logback에서 제공하는 async한 appdender로 fileAppender를 wrapping해서 비동기 처리 -->
    <appender name="async" class="net.logstash.logback.appender.AccessEventAsyncDisruptorAppender">
        <appender-ref ref="access.file"/>
    </appender>

    <appender-ref ref="async"/>
</configuration>