/** * Returns {@code true} if all of the specified {@link RequestLogAvailability}s are satisfied. */ default boolean isAvailable(RequestLogAvailability... availabilities) { for (RequestLogAvailability k : requireNonNull(availabilities, "availabilities")) { if (!isAvailable(k)) { return false; } } return true; }
/** * Returns {@code true} if all of the specified {@link RequestLogAvailability}s are satisfied. */ default boolean isAvailable(Iterable<RequestLogAvailability> availabilities) { for (RequestLogAvailability k : requireNonNull(availabilities, "availabilities")) { if (!isAvailable(k)) { return false; } } return true; }
/** * Ensures that all of the specified {@link RequestLogAvailability}s are satisfied. * * @throws RequestLogAvailabilityException if not satisfied yet */ default void ensureAvailability(RequestLogAvailability... availabilities) { if (!isAvailable(availabilities)) { throw new RequestLogAvailabilityException(Arrays.toString(availabilities)); } }
private static void exportRequestContentLength(Map<String, String> out, RequestLog log) { if (log.isAvailable(RequestLogAvailability.REQUEST_END)) { out.put(REQ_CONTENT_LENGTH.mdcKey, String.valueOf(log.requestLength())); } }
private static void exportElapsedNanos(Map<String, String> out, RequestLog log) { if (log.isAvailable(RequestLogAvailability.COMPLETE)) { out.put(ELAPSED_NANOS.mdcKey, String.valueOf(log.totalDurationNanos())); } }
/** * Ensures that all of the specified {@link RequestLogAvailability}s are satisfied. * * @throws RequestLogAvailabilityException if not satisfied yet */ default void ensureAvailability(Iterable<RequestLogAvailability> properties) { if (!isAvailable(properties)) { throw new RequestLogAvailabilityException(properties.toString()); } }
private static void exportResponseContentLength(Map<String, String> out, RequestLog log) { if (log.isAvailable(RequestLogAvailability.RESPONSE_END)) { out.put(RES_CONTENT_LENGTH.mdcKey, String.valueOf(log.responseLength())); } }
private static void exportStatusCode(Map<String, String> out, RequestLog log) { if (log.isAvailable(RequestLogAvailability.RESPONSE_HEADERS)) { out.put(RES_STATUS_CODE.mdcKey, log.status().codeAsText()); } }
/** * Ensures that the specified {@link RequestLogAvailability} is satisfied. * * @throws RequestLogAvailabilityException if not satisfied yet */ default void ensureAvailability(RequestLogAvailability availability) { if (!isAvailable(availability)) { throw new RequestLogAvailabilityException(availability.name()); } }
private void exportHttpResponseHeaders(Map<String, String> out, RequestLog log) { if (httpResHeaders == null || !log.isAvailable(RequestLogAvailability.RESPONSE_HEADERS)) { return; } exportHttpHeaders(out, log.responseHeaders(), httpResHeaders); }
private void exportHttpRequestHeaders(Map<String, String> out, RequestLog log) { if (httpReqHeaders == null || !log.isAvailable(RequestLogAvailability.REQUEST_HEADERS)) { return; } exportHttpHeaders(out, log.requestHeaders(), httpReqHeaders); }
@Override public CompletionStage<Backoff> shouldRetry(ClientRequestContext ctx, @Nullable Throwable cause) { final HttpStatus status; if (ctx.log().isAvailable(RequestLogAvailability.RESPONSE_HEADERS)) { status = ctx.log().responseHeaders().status(); } else { status = null; } return CompletableFuture.completedFuture(backoffFunction.apply(status, cause)); } }
@Override public CompletionStage<Boolean> shouldReportAsSuccess(ClientRequestContext ctx, @Nullable Throwable cause) { if (cause instanceof UnprocessedRequestException) { return CompletableFuture.completedFuture(null); // Neither success nor failure. } final HttpStatus status; if (ctx.log().isAvailable(RequestLogAvailability.RESPONSE_HEADERS)) { status = ctx.log().responseHeaders().status(); } else { status = null; } return CompletableFuture.completedFuture(function.apply(status, cause)); } }
private static void exportScheme(Map<String, String> out, RequestContext ctx, RequestLog log) { if (log.isAvailable(RequestLogAvailability.SCHEME)) { out.put(SCHEME.mdcKey, log.scheme().uriText()); } else { out.put(SCHEME.mdcKey, "unknown+" + ctx.sessionProtocol().uriText()); } }
private void exportRpcResponse(Map<String, String> out, RequestLog log) { if (!log.isAvailable(RequestLogAvailability.RESPONSE_CONTENT)) { return; } final Object responseContent = log.responseContent(); if (responseContent instanceof RpcResponse) { final RpcResponse rpcRes = (RpcResponse) responseContent; if (builtIns.contains(RES_RPC_RESULT) && !rpcRes.isCompletedExceptionally()) { try { out.put(RES_RPC_RESULT.mdcKey, String.valueOf(rpcRes.get())); } catch (Exception e) { // Should never reach here because RpcResponse must be completed. throw new Error(e); } } } }
private void exportRpcRequest(Map<String, String> out, RequestLog log) { if (!log.isAvailable(RequestLogAvailability.REQUEST_CONTENT)) { return; } final Object requestContent = log.requestContent(); if (requestContent instanceof RpcRequest) { final RpcRequest rpcReq = (RpcRequest) requestContent; if (builtIns.contains(REQ_RPC_METHOD)) { out.put(REQ_RPC_METHOD.mdcKey, rpcReq.method()); } if (builtIns.contains(REQ_RPC_PARAMS)) { out.put(REQ_RPC_PARAMS.mdcKey, String.valueOf(rpcReq.params())); } } }
public static <I extends Request, O extends Response, U extends Client<I, O>> O executeWithFallback( U delegate, ClientRequestContext ctx, I req, BiFunction<ClientRequestContext, Throwable, O> fallback) { requireNonNull(delegate, "delegate"); requireNonNull(ctx, "ctx"); requireNonNull(req, "req"); requireNonNull(fallback, "fallback"); try (SafeCloseable ignored = ctx.push()) { return delegate.execute(ctx, req); } catch (Throwable cause) { final O fallbackRes = fallback.apply(ctx, cause); final RequestLogBuilder logBuilder = ctx.logBuilder(); if (!ctx.log().isAvailable(RequestLogAvailability.REQUEST_START)) { // An exception is raised even before sending a request, so end the request with the exception. logBuilder.endRequest(cause); } logBuilder.endResponse(cause); return fallbackRes; } }
@Override public MeterIdPrefix apply(MeterRegistry registry, RequestLog log) { final List<Tag> tags = buildTags(log); // Add the 'httpStatus' tag. final HttpStatus status; if (log.isAvailable(RequestLogAvailability.RESPONSE_HEADERS)) { status = log.status(); } else { status = HttpStatus.UNKNOWN; } tags.add(Tag.of("httpStatus", status.codeAsText())); return new MeterIdPrefix(name, tags); }
@Override public void endOfStream() { setClientStreamClosed(); if (!closeCalled) { if (!ctx.log().isAvailable(RequestLogAvailability.REQUEST_CONTENT)) { ctx.logBuilder().requestContent(GrpcLogUtil.rpcRequest(method), null); } if (useBlockingTaskExecutor) { ctx.blockingTaskExecutor().execute(this::invokeHalfClose); } else { invokeHalfClose(); } } }
private HttpResponse execute(@Nullable EventLoop eventLoop, HttpRequest req) { final String concatPaths = concatPaths(uri().getRawPath(), req.path()); req.path(concatPaths); final PathAndQuery pathAndQuery = PathAndQuery.parse(concatPaths); if (pathAndQuery == null) { req.abort(); return HttpResponse.ofFailure(new IllegalArgumentException("invalid path: " + concatPaths)); } return execute(eventLoop, req.method(), pathAndQuery.path(), pathAndQuery.query(), null, req, (ctx, cause) -> { if (ctx != null && !ctx.log().isAvailable(RequestLogAvailability.REQUEST_START)) { // An exception is raised even before sending a request, so abort the request to // release the elements. req.abort(); } return HttpResponse.ofFailure(cause); }); }