DefaultRequestLog implements RequestLog, RequestLogBuilder { @Override public void addChild(RequestLogAccess child) { checkState(!hasLastChild, "last child is already added"); requireNonNull(child, "child"); if (child instanceof DefaultRequestLog) { checkState(((DefaultRequestLog) child).parent == null, "child has parent already"); ((DefaultRequestLog) child).parent = this; } if (children == null) { children = new ArrayList<>(); propagateRequestSideLog(child); } children.add(child); } DefaultRequestLog(RequestContext ctx); @Override boolean isComplete(); @Override boolean isRequestComplete(); @Override boolean isAvailable(RequestLogProperty property); @Override boolean isAvailable(RequestLogProperty... properties); @Override boolean isAvailable(Iterable<RequestLogProperty> properties); @Override RequestLog partial(); @Override CompletableFuture<RequestLog> whenComplete(); @Override CompletableFuture<RequestOnlyLog> whenRequestComplete(); @Override CompletableFuture<RequestLog> whenAvailable(RequestLogProperty property); @Override CompletableFuture<RequestLog> whenAvailable(RequestLogProperty... properties); @Override CompletableFuture<RequestLog> whenAvailable(Iterable<RequestLogProperty> properties); @Override RequestLog ensureComplete(); @Override RequestOnlyLog ensureRequestComplete(); @Override RequestLog ensureAvailable(RequestLogProperty property); @Override RequestLog ensureAvailable(RequestLogProperty... properties); @Override RequestLog ensureAvailable(Iterable<RequestLogProperty> properties); @Override int availabilityStamp(); @Override RequestContext context(); @Nullable @Override RequestLogAccess parent(); @Override List<RequestLogAccess> children(); @Override boolean isDeferred(RequestLogProperty property); @Override boolean isDeferred(RequestLogProperty... properties); @Override boolean isDeferred(Iterable<RequestLogProperty> properties); @Override void defer(RequestLogProperty property); @Override void defer(RequestLogProperty... properties); @Override void defer(Iterable<RequestLogProperty> properties); @Override void addChild(RequestLogAccess child); @Override void endResponseWithLastChild(); @Override void startRequest(long requestStartTimeNanos, long requestStartTimeMicros); @Override long requestStartTimeMicros(); @Override long requestStartTimeMillis(); @Override long requestStartTimeNanos(); @Override Long requestFirstBytesTransferredTimeNanos(); @Override long requestEndTimeNanos(); @Override long requestDurationNanos(); @Override Throwable requestCause(); @Override void session(@Nullable Channel channel, SessionProtocol sessionProtocol,
                        @Nullable ClientConnectionTimings connectionTimings); @Override void session(@Nullable Channel channel, SessionProtocol sessionProtocol,
                        @Nullable SSLSession sslSession, @Nullable ClientConnectionTimings connectionTimings); @Override Channel channel(); @Override SSLSession sslSession(); @Override SessionProtocol sessionProtocol(); @Nullable @Override ClientConnectionTimings connectionTimings(); @Override void serializationFormat(SerializationFormat serializationFormat); @Override SerializationFormat serializationFormat(); @Override Scheme scheme(); @Nullable @Override String serviceName(); @Override String name(); @Override void name(String name); @Override void name(String serviceName, String name); @Override String fullName(); @Override long requestLength(); @Override void requestLength(long requestLength); @Override void requestFirstBytesTransferred(); @Override void requestFirstBytesTransferred(long requestFirstBytesTransferredTimeNanos); @Override void increaseRequestLength(long deltaBytes); @Override void increaseRequestLength(HttpData data); @Override RequestHeaders requestHeaders(); @Override void requestHeaders(RequestHeaders requestHeaders); @Override Object requestContent(); @Override void requestContent(@Nullable Object requestContent, @Nullable Object rawRequestContent); @Override Object rawRequestContent(); @Override String requestContentPreview(); @Override void requestContentPreview(@Nullable String requestContentPreview); @Override HttpHeaders requestTrailers(); @Override void requestTrailers(HttpHeaders requestTrailers); @Override void endRequest(); @Override void endRequest(Throwable requestCause); @Override void endRequest(long requestEndTimeNanos); @Override void endRequest(Throwable requestCause, long requestEndTimeNanos); @Override void startResponse(); @Override void startResponse(long responseStartTimeNanos, long responseStartTimeMicros); @Override long responseStartTimeMicros(); @Override long responseStartTimeMillis(); @Override long responseStartTimeNanos(); @Override Long responseFirstBytesTransferredTimeNanos(); @Override long responseEndTimeNanos(); @Override long responseDurationNanos(); @Override long totalDurationNanos(); @Override Throwable responseCause(); @Override long responseLength(); @Override void responseLength(long responseLength); @Override void responseFirstBytesTransferred(); @Override void responseFirstBytesTransferred(long responseFirstBytesTransferredTimeNanos); @Override void increaseResponseLength(long deltaBytes); @Override void increaseResponseLength(HttpData data); @Override ResponseHeaders responseHeaders(); @Override void responseHeaders(ResponseHeaders responseHeaders); @Override Object responseContent(); @Override void responseContent(@Nullable Object responseContent, @Nullable Object rawResponseContent); @Override String responseContentPreview(); @Override void responseContentPreview(@Nullable String responseContentPreview); @Override Object rawResponseContent(); @Override HttpHeaders responseTrailers(); @Override void responseTrailers(HttpHeaders responseTrailers); @Override void endResponse(); @Override void endResponse(Throwable responseCause); @Override void endResponse(long responseEndTimeNanos); @Override void endResponse(Throwable responseCause, long responseEndTimeNanos); @Override String toString(); @Override String toStringRequestOnly(
            BiFunction<? super RequestContext, ? super RequestHeaders, ?> headersSanitizer,
            BiFunction<? super RequestContext, Object, ?> contentSanitizer,
            BiFunction<? super RequestContext, ? super HttpHeaders, ?> trailersSanitizer); @Override String toStringResponseOnly(
            BiFunction<? super RequestContext, ? super ResponseHeaders, ?> headersSanitizer,
            BiFunction<? super RequestContext, Object, ?> contentSanitizer,
            BiFunction<? super RequestContext, ? super HttpHeaders, ?> trailersSanitizer);  }
@Test void addChild() { when(ctx.method()).thenReturn(HttpMethod.GET); final DefaultRequestLog child = new DefaultRequestLog(ctx); log.addChild(child); child.startRequest(); child.session(channel, SessionProtocol.H2C, null, null); assertThat(log.requestStartTimeMicros()).isEqualTo(child.requestStartTimeMicros()); assertThat(log.channel()).isSameAs(channel); assertThat(log.sessionProtocol()).isSameAs(SessionProtocol.H2C); child.serializationFormat(SerializationFormat.NONE); assertThat(log.scheme().serializationFormat()).isSameAs(SerializationFormat.NONE); child.requestFirstBytesTransferred(); assertThat(log.requestFirstBytesTransferredTimeNanos()) .isEqualTo(child.requestFirstBytesTransferredTimeNanos()); final RequestHeaders foo = RequestHeaders.of(HttpMethod.GET, "/foo"); child.requestHeaders(foo); assertThat(log.requestHeaders()).isSameAs(foo); final String requestContent = "baz"; final String rawRequestContent = "qux"; child.requestContent(requestContent, rawRequestContent); assertThat(log.requestContent()).isSameAs(requestContent); assertThat(log.rawRequestContent()).isSameAs(rawRequestContent); child.endRequest(); assertThat(log.requestDurationNanos()).isEqualTo(child.requestDurationNanos()); child.startResponse(); assertThatThrownBy(() -> log.responseStartTimeMicros()) .isExactlyInstanceOf(RequestLogAvailabilityException.class); child.responseFirstBytesTransferred(); assertThatThrownBy(() -> log.responseFirstBytesTransferredTimeNanos()) .isExactlyInstanceOf(RequestLogAvailabilityException.class); final ResponseHeaders bar = ResponseHeaders.of(200); child.responseHeaders(bar); assertThatThrownBy(() -> log.responseHeaders()) .isExactlyInstanceOf(RequestLogAvailabilityException.class); log.endResponseWithLastChild(); assertThat(log.responseStartTimeMicros()).isEqualTo(child.responseStartTimeMicros()); assertThat(log.responseFirstBytesTransferredTimeNanos()) .isEqualTo(child.responseFirstBytesTransferredTimeNanos()); assertThat(log.responseHeaders()).isSameAs(bar); final String responseContent = "baz1"; final String rawResponseContent = "qux1"; child.responseContent(responseContent, rawResponseContent); child.endResponse(new AnticipatedException("Oops!")); assertThat(log.responseContent()).isSameAs(responseContent); assertThat(log.rawResponseContent()).isSameAs(rawResponseContent); assertThat(log.responseDurationNanos()).isEqualTo(child.responseDurationNanos()); assertThat(log.totalDurationNanos()).isEqualTo(child.totalDurationNanos()); }