서버 응답 지연이나 Timeout 관련 이슈를 추적하려면, 요청/응답 시간 로그를 직접 남기거나, Spring에 커스텀 Filter 또는 Feign Logger 를 활용하면 아주 효과적입니다. 아래에서 두 가지 케이스 모두 다뤄볼게요.
✅ 1. Feign 요청/응답 시간 로깅 필터
🔧 요청 전에 시간 저장 → 응답 후 소요 시간 측정
@Component
public class FeignRequestTimingInterceptor implements RequestInterceptor {
private static final Logger log = LoggerFactory.getLogger(FeignRequestTimingInterceptor.class);
@Override
public void apply(RequestTemplate template) {
template.header("X-Request-Start-Time", String.valueOf(System.currentTimeMillis()));
}
}
그리고 ErrorDecoder나 FeignClientExceptionDecoder 에서 시간 로그 출력:
long start = Long.parseLong(response.request().headers().getOrDefault("X-Request-Start-Time", List.of("0")).get(0));
long elapsed = System.currentTimeMillis() - start;
log.warn("Feign request to {} took {} ms", response.request().url(), elapsed);
또는 Client를 커스텀해서 전체 요청 시간을 측정할 수도 있어요.
✅ 2. Spring Servlet Filter로 전/후 시간 체크 (서버 입장에서)
@Component
public class RequestTimingFilter implements Filter {
private static final Logger log = LoggerFactory.getLogger(RequestTimingFilter.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
long startTime = System.currentTimeMillis();
try {
chain.doFilter(request, response);
} finally {
long duration = System.currentTimeMillis() - startTime;
HttpServletRequest req = (HttpServletRequest) request;
log.info("[{} {}] took {} ms", req.getMethod(), req.getRequestURI(), duration);
}
}
}
이렇게 하면 모든 HTTP 요청 소요 시간을 측정할 수 있고, 느린 요청 로그만 추출할 수도 있어요.
✅ 3. Feign 자체의 로그 레벨 설정
logging:
level:
feign: DEBUG
your.package.client.YourFeignClient: DEBUG
또는 설정 클래스에서:
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
이렇게 하면 요청/응답 바디, 헤더, 타이밍까지 다 찍혀요.
✅ 4. Timeout 발생 시 자동 경고 알림 예시
try {
client.callSomething();
} catch (FeignException e) {
if (e.getCause() instanceof SocketTimeoutException) {
log.warn("Timeout 발생! URL: {}", e.request().url(), e);
}
throw e;
}
🎯 추천 조합
| 목적 | 도구 |
|---|---|
| 요청 소요 시간 측정 | Feign Interceptor + Header or Spring Filter |
| Timeout 예외 캐치 | FeignException 내부 Cause 체크 |
| 전체 요청 로그 추적 | Logger.Level.FULL |
| 느린 요청 추출 | Filter + 조건부 duration > 1000ms 로그 |