@Override
  public void handle(final RoutingContext routingContext) {
    routingContext.addEndHandler(ar -> {
      // After the response is complete, log results here.
      final int status = routingContext.request().response().getStatusCode();
      if (!loggingRateLimiter.shouldLog(logger, routingContext.request().path(), status)) {
        return;
      }
      final long contentLength = routingContext.request().response().bytesWritten();
      final HttpVersion version = routingContext.request().version();
      final HttpMethod method = routingContext.request().method();
      final String uri = enableQueryLogging
          ? routingContext.request().uri()
          : routingContext.request().path();

      if (endpointFilter.isPresent() && endpointFilter.get().matcher(uri).matches()) {
        return;
      }

      final long requestBodyLength = routingContext.request().bytesRead();
      final String versionFormatted;
      switch (version) {
        case HTTP_1_0:
          versionFormatted = "HTTP/1.0";
          break;
        case HTTP_1_1:
          versionFormatted = "HTTP/1.1";
          break;
        case HTTP_2:
          versionFormatted = "HTTP/2.0";
          break;
        default:
          versionFormatted = "-";
      }
      final String name = Optional.ofNullable((ApiUser) routingContext.user())
          .map(u -> u.getPrincipal().getName())
          .orElse("-");
      final String userAgent = Optional.ofNullable(
          routingContext.request().getHeader(HTTP_HEADER_USER_AGENT)).orElse("-");
      final String timestamp = Utils.formatRFC1123DateTime(clock.millis());
      final SocketAddress socketAddress = routingContext.request().remoteAddress();
      final String message = String.format(
          "%s - %s [%s] \"%s %s %s\" %d %d \"-\" \"%s\" %d",
          socketAddress == null ? "null" : socketAddress.host(),
          name,
          timestamp,
          method,
          uri,
          versionFormatted,
          status,
          contentLength,
          userAgent,
          requestBodyLength);
      doLog(status, message);
    });
    routingContext.next();
  }
@Test
  public void shouldSkipLog() {
    // Given:
    when(response.getStatusCode()).thenReturn(401);
    when(loggingRateLimiter.shouldLog(logger, "/query", 401)).thenReturn(false);

    // When:
    loggingHandler.handle(routingContext);
    verify(routingContext).addEndHandler(endCallback.capture());
    endCallback.getValue().handle(null);

    // Then:
    verify(logger, never()).info(any());
    verify(logger, never()).warn(any());
    verify(logger, never()).error(any());
  }