@Override
    @SuppressFBWarnings({ "SERVLET_HEADER_REFERER", "SERVLET_HEADER_USER_AGENT" })
    public String format(ContainerRequestType servletRequest, ContainerResponseType servletResponse, SecurityContext ctx) {
        //LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
        StringBuilder logLineBuilder = new StringBuilder();
        AwsProxyRequestContext gatewayContext = (AwsProxyRequestContext)servletRequest.getAttribute(API_GATEWAY_CONTEXT_PROPERTY);
        HttpApiV2ProxyRequestContext httpApiContext = (HttpApiV2ProxyRequestContext)servletRequest.getAttribute(HTTP_API_CONTEXT_PROPERTY);

        // %h
        logLineBuilder.append(servletRequest.getRemoteAddr());
        logLineBuilder.append(" ");

        // %l
        if (servletRequest.getUserPrincipal() != null) {
            logLineBuilder.append(servletRequest.getUserPrincipal().getName());
        } else {
            logLineBuilder.append("-");
        }
        if (gatewayContext != null && gatewayContext.getIdentity() != null && gatewayContext.getIdentity().getUserArn() != null) {
                logLineBuilder.append(gatewayContext.getIdentity().getUserArn());
        } else {
            logLineBuilder.append("-");
        }
        logLineBuilder.append(" ");

        // %u
        if (servletRequest.getUserPrincipal() != null) {
            logLineBuilder.append(servletRequest.getUserPrincipal().getName());
        }
        logLineBuilder.append(" ");


        // %t
        long timeEpoch = ZonedDateTime.now(clock).toEpochSecond();
        if (gatewayContext != null && gatewayContext.getRequestTimeEpoch() > 0) {
            timeEpoch = gatewayContext.getRequestTimeEpoch() / 1000;
        } else if (httpApiContext != null && httpApiContext.getTimeEpoch() > 0) {
            timeEpoch = httpApiContext.getTimeEpoch() / 1000;
        }
        logLineBuilder.append(
                dateFormat.format(ZonedDateTime.of(
                        LocalDateTime.ofEpochSecond(timeEpoch, 0, ZoneOffset.UTC),
                        clock.getZone())
                ));
        logLineBuilder.append(" ");

        // %r
        logLineBuilder.append("\"");
        logLineBuilder.append(servletRequest.getMethod().toUpperCase(Locale.ENGLISH));
        logLineBuilder.append(" ");
        logLineBuilder.append(servletRequest.getRequestURI());
        logLineBuilder.append(" ");
        logLineBuilder.append(servletRequest.getProtocol());
        logLineBuilder.append("\" ");

        // %>s
        logLineBuilder.append(servletResponse.getStatus());
        logLineBuilder.append(" ");

        // %b
        if (servletResponse instanceof AwsHttpServletResponse) {
            AwsHttpServletResponse awsResponse = (AwsHttpServletResponse)servletResponse;
            if (awsResponse.getAwsResponseBodyBytes().length > 0) {
                logLineBuilder.append(awsResponse.getAwsResponseBodyBytes().length);
            } else {
                logLineBuilder.append("-");
            }
        } else {
            logLineBuilder.append("-");
        }
        logLineBuilder.append(" ");

        // \"%{Referer}i\"
        logLineBuilder.append("\"");
        if (servletRequest.getHeader("referer") != null) {
            logLineBuilder.append(servletRequest.getHeader("referer"));
        } else {
            logLineBuilder.append("-");
        }
        logLineBuilder.append("\" ");

        // \"%{User-agent}i\"
        logLineBuilder.append("\"");
        if (servletRequest.getHeader("user-agent") != null) {
            logLineBuilder.append(servletRequest.getHeader("user-agent"));
        } else {
            logLineBuilder.append("-");
        }
        logLineBuilder.append("\" ");

        logLineBuilder.append("combined");

        return logLineBuilder.toString();
    }
@Test
    void logsRequestTimeWhenRequestTimeEpochGreaterThanZero() {
        // given
        context.setRequestTimeEpoch(1563023494000L);

        // when
        String actual = sut.format(mockServletRequest, mockServletResponse, null);

        // then
        assertThat(actual, containsString("[13/07/2019:13:11:34Z]"));
    }