content: package com.ofg.infrastructure.web.logging;
  
  import static com.ofg.infrastructure.web.logging.HttpDataExtractor.extractHeaders;
  import static com.ofg.infrastructure.web.logging.HttpDataExtractor.extractStatus;
  import static com.ofg.infrastructure.web.logging.HttpDataFactory.createHttpData;
  
  import java.io.IOException;
  import java.nio.charset.StandardCharsets;
  
  import feign.Request;
  import feign.Response;
  import feign.Util;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  public class FeignCallObfuscatingLogger extends feign.Logger.JavaLogger {
  
      private static final String TAG = "CLIENT";
      private static final Logger log = LoggerFactory.getLogger(RequestResponseLogger.class);
  
      private final RequestDataProvider requestDataProvider;
      private final RequestIdProvider requestIdProvider;
      private final RequestResponseLogger requestResponseLogger;
  
      public FeignCallObfuscatingLogger(RequestDataProvider requestDataProvider, RequestIdProvider requestIdProvider, RequestResponseLogger requestResponseLogger) {
          this.requestDataProvider = requestDataProvider;
          this.requestIdProvider = requestIdProvider;
          this.requestResponseLogger = requestResponseLogger;
      }
  
      @Override
      protected void logRequest(String configKey, feign.Logger.Level logLevel, Request request) {
          HttpData reqData = createHttpData(request);
          String requestId = requestIdProvider.getRequestId();
          requestDataProvider.store(requestId, reqData);
          requestResponseLogger.logObfuscatedRequest(reqData, TAG);
          super.logRequest(configKey, logLevel, request);
      }
  
      @Override
      protected Response logAndRebufferResponse(String configKey, feign.Logger.Level logLevel, Response response,
                                                long elapsedTime) throws IOException {
          String requestId = requestIdProvider.getRequestId();
          HttpData reqData = requestDataProvider.retrieve(requestId);
          if (requestTraceable(reqData)) {
              byte[] bodyData = Util.toByteArray(response.body().asInputStream());
              String content = new String(bodyData, StandardCharsets.UTF_8.name());
              HttpData resData = new HttpData(extractHeaders(response), extractStatus(response), content);
              Response rebufferedResponse = Response.create(response.status(), response.reason(), response.headers(),
                      bodyData);
              requestResponseLogger.logObfuscatedResponse(reqData, resData, TAG);
              requestDataProvider.remove(requestId);
              return super.logAndRebufferResponse(configKey, logLevel, rebufferedResponse, elapsedTime);
          } else {
              log.debug("Cannot obfuscate response, matching request data lost");
              return super.logAndRebufferResponse(configKey, logLevel, response, elapsedTime);
          }
      }
  
      private boolean requestTraceable(HttpData reqData) {
          return reqData != null;
      }
  
  }