Access Log를 남겨보자.
환경은 다음과 같다.
- jdk 11.0.21
- springboot 2.7.18
먼저 pom 에 dependency 추가 한다. - 작성일 기준 2.x 마지막 버전 2.16.0 으로 진행
<!-- pom.xml -->
<dependency>
<groupId>org.zalando</groupId>
<artifactId>logbook-spring-boot-starter</artifactId>
<version>2.16.0</version>
</dependency>
logback에도 관련 설정을 추가해 본다.
<!-- logback-spring.xml -->
<!-- Console Appenders -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOGS_CONSOLE_PATTERN}</pattern>
</encoder>
</appender>
<!-- Access Log Appenders -->
<appender name="ACCESS_FILE_ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS_ABSOLUTE_PATH}/${LOGS_FILE_NAME}-access.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<encoder>
<pattern>${LOGS_FILE_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOGS_ABSOLUTE_PATH}/${LOGS_FILE_NAME}-access.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 100MB -->
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
</appender>
<!-- Access Loggers -->
<logger name="com.dev.log.common.log.AccessLogWriter" level="INFO" additivity="false">
<appender-ref ref="STDOUT" /> <!-- 파일 appender는 필요시 아래에 추가 -->
</logger>
application.yml에서 log 관련 설정을 추가한다.
access log 를 TRACE로 찍고 있으니 제외시킬 exclude 대상을 지정해준다.
logging:
config: classpath:logback-spring.xml
#log path
logs:
absolute:
path: C:/dev/log
level:
root: INFO
com: DEBUG
name: fullmooney-tistory-com
logbook:
exclude:
- '**/health'
- '**/v3/api-docs/**'
- '**/v2/api-docs/**'
- '**/v1/api-docs/**'
- '**/swagger-resources/**'
- '**/configuration/security'
- '**/swagger'
- '**/csrf'
- '**/error'
- '**/configuration'
- '**/swagger-ui.html'
- '**/favicon.*'
- '**/h2-console/**'
- '**/webjars/**'
- '**/swagger-ui/**'
- '**/swagger-ui/*'
- '**/swagger-resources/**'
- '**/etrack/exportArchive'
- '**/*-stream'
HttpLogWriter 인터페이스를 구현하는 AccessLogWriter 컴포넌트를 추가한다.
import java.io.IOException;
import org.springframework.stereotype.Component;
import org.zalando.logbook.Correlation;
import org.zalando.logbook.HttpLogWriter;
import org.zalando.logbook.Precorrelation;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class AccessLogWriter implements HttpLogWriter {
@Override
public void write(Precorrelation precorrelation, String request) throws IOException {
if(log.isInfoEnabled()) {
log.info("############################ request: {}", request);
}
}
@Override
public void write(Correlation correlation, String response) throws IOException {
if(log.isInfoEnabled()) {
log.info("############################ response: {}", response);
}
}
}
이제 api 를 추가하고 swagger를 통해 테스트 해보자.
import java.util.ArrayList;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.dev.log.domain.SampleVO;
@RestController
@RequestMapping("/api/logbook")
public class LogbookTestController {
@PostMapping("/logging-access-log")
public ResponseEntity<List<SampleVO>> postMethodName(@RequestBody SampleVO vo) {
List<SampleVO> listVO = new ArrayList<>();
SampleVO tot = new SampleVO();
tot.setLeague("PL");
tot.setTeam("TOT");
tot.setName("Son Heung-min");
tot.setNumber(7);
listVO.add(tot);
listVO.add(vo);
return ResponseEntity.ok(listVO);
}
}
swagger 실행 결과는 다음과 같이 정상으로 수행되었다.

console 출력에도 request와 response가 잘 출력되었다.

글씨가 작아 다시 옮겨보면..
20240104 10:11:42.449 [http-nio-8080-exec-5] INFO c.d.log.common.log.AccessLogWriter [19]-[fullmooney-tistory-com,59e6c3acd97c298a]-############################ request: {"origin":"remote","type":"request","correlation":"c7626b8e22728fa2","protocol":"HTTP/1.1","remote":"0:0:0:0:0:0:0:1","method":"POST","uri":"http://localhost:8080/api/logbook/logging-access-log","host":"localhost","path":"/api/logbook/logging-access-log","scheme":"http","port":"8080","headers":{"accept":["*/*"],"accept-encoding":["gzip, deflate, br"],"accept-language":["ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7"],"connection":["keep-alive"],"content-length":["94"],"content-type":["application/json"],"cookie":["JSESSIONID=7F79E354F3E2D29A2509BF09D7FABE59"],"host":["localhost:8080"],"origin":["http://localhost:8080"],"referer":["http://localhost:8080/swagger-ui/index.html"],"sec-ch-ua":["\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\", \"Google Chrome\";v=\"120\""],"sec-ch-ua-mobile":["?0"],"sec-ch-ua-platform":["\"Windows\""],"sec-fetch-dest":["empty"],"sec-fetch-mode":["cors"],"sec-fetch-site":["same-origin"],"user-agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"]},"body":{"league":"Ligue1","team":"PSG","name":"Lee Gang-in","number":0,"wage":0}}
20240104 10:11:42.469 [http-nio-8080-exec-5] INFO c.d.log.common.log.AccessLogWriter [26]-[fullmooney-tistory-com,59e6c3acd97c298a]-############################ response: {"origin":"local","type":"response","correlation":"c7626b8e22728fa2","duration":28,"protocol":"HTTP/1.1","status":200,"headers":{"Connection":["keep-alive"],"Content-Type":["application/json"],"Date":["Thu, 04 Jan 2024 01:11:42 GMT"],"Keep-Alive":["timeout=60"],"Transfer-Encoding":["chunked"]},"body":[{"league":"PL","team":"TOT","name":"Son Heung-min","number":7,"wage":0},{"league":"Ligue1","team":"PSG","name":"Lee Gang-in","number":0,"wage":0}]}
Git: tistory/log at e4bf956766416f11a03e6d818d2d10c92212d0f7 · FullMooney/tistory (github.com)
728x90
'개발 > java' 카테고리의 다른 글
| springboot + redis @Cacheable 사용 (3) | 2024.01.11 |
|---|---|
| springboot redis client 만들기 (1) | 2024.01.08 |
| mybatis interceptor 암복호화 처리 (1) | 2023.12.13 |
| JPA EntityListener로 multi JpaRepository save (1) | 2022.09.07 |
| Runtime에서 annotation attribute 변경 - influxDB @Measurement 공통 DTO 만들기 (1) | 2022.09.07 |