class DeferredLoggingConsumer
      implements AsyncBody.Consumer<List<ByteBuffer>> {

    private static final long MAX_BODY_SIZE = 2097152L; // 2MiB

    private final HttpLogger httpLogger;
    private final HttpRequest originalRequest;
    private final AsyncBody.Consumer<List<ByteBuffer>> originalConsumer;
    private final AtomicLong responseBodySize;
    private final Queue<ByteBuffer> responseBody;
    private final AtomicBoolean bodyTruncated = new AtomicBoolean();

    public DeferredLoggingConsumer(HttpLogger httpLogger, HttpRequest originalRequest,
        AsyncBody.Consumer<List<ByteBuffer>> originalConsumer) {
      this.httpLogger = httpLogger;
      this.originalRequest = originalRequest;
      this.originalConsumer = originalConsumer;
      responseBodySize = new AtomicLong(0);
      responseBody = new ConcurrentLinkedQueue<>();
    }

    @Override
    public void consume(List<ByteBuffer> value, AsyncBody asyncBody) throws Exception {
      try {
        value.stream().forEach(bb -> {
          if (responseBodySize.addAndGet(bb.remaining()) < MAX_BODY_SIZE && !bodyTruncated.get()
              && BufferUtil.isPlainText(bb)) {
            responseBody.add(copy(bb));
          } else {
            bodyTruncated.set(true);
          }
        });
      } finally {
        originalConsumer.consume(value, asyncBody);
      }
    }

    @Override
    public <U> U unwrap(Class<U> target) {
      return Optional.ofNullable(AsyncBody.Consumer.super.unwrap(target)).orElse(originalConsumer.unwrap(target));
    }

    /**
     * Registers the asyncBody.done() callback.
     *
     * @param asyncBody the AsyncBody instance to register the callback on the done() future.
     * @param response
     */
    private void processAsyncBody(AsyncBody asyncBody, HttpResponse<?> response) {<FILL_FUNCTION_BODY>}
  }

      asyncBody.done().whenComplete((Void v, Throwable throwable) -> {
        httpLogger.logStart();
        // TODO: we also have access to the response.request, which may be different than originalRequest
        httpLogger.logRequest(originalRequest);
        httpLogger.logResponse(response);
        httpLogger.logResponseBody(responseBody, responseBodySize.get(), bodyTruncated.get());
        httpLogger.logEnd();
        responseBody.clear();
      });
    
<no_super_class>