[공부] 프로그래밍/Spring・Spring Boot (JAVA)
Feign Client 구현 - 3
woodisco
2024. 5. 22. 10:26
♧ 전체 코드 : https://github.com/woodisco/feign-client
GitHub - woodisco/feign-client: feign-client 공부
feign-client 공부. Contribute to woodisco/feign-client development by creating an account on GitHub.
github.com
Logger 구현
① FeignCustomLogger 작성
@RequiredArgsConstructor
public class FeignCustomLogger extends Logger {
@Override
protected void log(String configKey, String format, Object... args) {
System.out.println(String.format(methodTag(configKey) + format, args));
}
@Override
protected void logRequest(String configKey, Level logLevel, Request request) {
System.out.println(request);
}
@Override
protected Response logAndRebufferResponse(String configKey, Level logLevel, Response response, long elapsedTime) throws IOException {
String protocolVersion = resolveProtocolVersion(response.protocolVersion());
String reason = response.reason() != null
&& logLevel.compareTo(Level.NONE) > 0 ? " " + response.reason() : "";
int status = response.status();
log(configKey, "<--- %s %s%s (%sms)", protocolVersion, status, reason, elapsedTime);
if (logLevel.ordinal() >= Level.HEADERS.ordinal()) {
for (String field : response.headers().keySet()) {
if (shouldLogResponseHeader(field)) {
for (String value : valuesOrEmpty(response.headers(), field)) {
log(configKey, "%s: %s", field, value);
}
}
}
int bodyLength = 0;
if (response.body() != null && !(status == 204 || status == 205)) {
// HTTP 204 No Content "...response MUST NOT include a message-body"
// HTTP 205 Reset Content "...response MUST NOT include an entity"
if (logLevel.ordinal() >= Level.FULL.ordinal()) {
log(configKey, ""); // CRLF
}
byte[] bodyData = Util.toByteArray(response.body().asInputStream());
bodyLength = bodyData.length;
if (logLevel.ordinal() >= Level.HEADERS.ordinal() && bodyLength > 0) {
log(configKey, "%s", decodeOrDefault(bodyData, UTF_8, "Binary data"));
}
// elapsedTime이 지정한 시간보다 오래 걸릴 경우, 로그 출력
if (elapsedTime > DEFAULT_SLOW_API_TIME) {
log(configKey, "[%s] elapsedTime : %s", SLOW_API_NOTICE, elapsedTime);
}
log(configKey, "<--- END HTTP (%s-byte body)", bodyLength);
return response.toBuilder().body(bodyData).build();
} else {
log(configKey, "<--- END HTTP (%s-byte body)", bodyLength);
}
}
return response;
}
}
▷ log 메소드 : log의 형식을 결정한다.
▷ logRequest 메서드 :
여기서 logLevel 은 aplication.yaml 에서 정의한 것이며 동작순서는 logRequest 메서드 진입 -> 외부 요청 -> logAndRebufferResponse 메서드 진입순으로 이루어진다.
▷ logAndRebufferResponse 메서드 :
처리 내용은 상위 Logger 클래스에서 복사한 내용으로 logAndRebufferResponse 메서드 내에선 Request, Response에 대한 정보를 log로 남길 수 있다.
② FeignConfig 작성
FeignCustomLogger는 글로벌한 설정값이기 때문에 FeignConfig에 추가하여 선언하기.
@Configuration
public class FeignConfig {
@Bean
public Logger feignLogger() {
return new FeignCustomLogger();
}
}
출처 : 패스트캠퍼스 10개 프로젝트로 완성하는 백엔드 웹개발(Java/Spring) 초격차 패키지 Online