4xx, 5xx 에러 로그 남기기

현재 회사는 모듈들이 다 나눠져 있습니다. 그리고 현재 제가 맡은 모듈은 다른 모듈과 통신할 때 HTTP 통신을 사용하고 있죠.

그러다보니 RestClient를 사용해 HTTP 통신을 하면서 4xx, 5xx 에러 로그를 남기고 싶었습니다.

로그를 남기지 않으니 문제를 파악하기가 너무 어렵더라구요.

RestClientHttpClient

실제 HTTP 요청을 수행하는 클라이언트 구현체입니다.

@Slf4j
@Component
@RequiredArgsConstructor
public class RestClientHttpClient implements HttpClient {

    private final RestClient restClient;
    private final RestClientErrorHandler errorHandler;
    private final RestClientExceptionHandler exceptionHandler;

    @Override
    public <T> T post(String url, Object request, Class<T> responseType, UUID transactionId) {
        return exceptionHandler.executeWithExceptionHandling(
                () -> restClient.post()
                        .uri(url)
                        .body(request)
                        .retrieve()
                        .onStatus(HttpStatusCode::isError, errorHandler.createErrorHandler(transactionId))
                        .body(responseType),
                transactionId
        );
    }
}
  1. UUID transactionId

RestClientExceptionHandler

RestClient 호출 시 발생하는 네트워크 레벨 예외를 처리합니다.

@Slf4j
@Component
public class RestClientExceptionHandler {

    public <T> T executeWithExceptionHandling(Supplier<T> apiCall, UUID transactionId) {
        try {
            return apiCall.get();
        } catch (ResourceAccessException e) {
            return handleNetworkError(e, transactionId);
        } catch (RestClientException e) {
            return handleRestClientError(e, transactionId);
        }
    }

    private <T> T handleNetworkError(ResourceAccessException e, UUID transactionId) {
        LOGGER.info("[{}] Network error: {}", transactionId, e.getMessage(), e);
        throw new BaseBusinessException(
                MessageSourceUtil.getMessage(
                        "conductor-service.workflow.http.network-error",
                        new Object[]{transactionId}
                )
        );
    }

    private <T> T handleRestClientError(RestClientException e, UUID transactionId) {
        LOGGER.info("[{}] RestClient error: {}", transactionId, e.getMessage(), e);
        throw new BaseBusinessException(
                MessageSourceUtil.getMessage(
                        "conductor-service.workflow.http.client-error",
                        new Object[]{transactionId}
                )
        );
    }

}

  1. Supplier
  2. ResourceAccessException
  3. RestClientException
  4. BaseBusinessException