private void propagateRequestSideLog(RequestLog child) { child.addListener(log -> startRequest0(log.channel(), log.sessionProtocol(), null, log.requestStartTimeNanos(), log.requestStartTimeMicros(), true), REQUEST_START); child.addListener(log -> serializationFormat(log.serializationFormat()), SCHEME); child.addListener(log -> requestFirstBytesTransferred(log.requestFirstBytesTransferredTimeNanos()), REQUEST_FIRST_BYTES_TRANSFERRED); child.addListener(log -> requestHeaders(log.requestHeaders()), REQUEST_HEADERS); child.addListener(log -> requestContent(log.requestContent(), log.rawRequestContent()), REQUEST_CONTENT); child.addListener(log -> endRequest0(log.requestCause(), log.requestEndTimeNanos()), REQUEST_END); }
private void addCallbackAndFlush(Throwable cause, State oldState, ChannelFuture future) { if (oldState != State.DONE) { future.addListener(unused -> { // Write an access log always with a cause. Respect the first specified cause. if (tryComplete()) { logBuilder().endResponse(cause); reqCtx.log().addListener(accessLogWriter::log, RequestLogAvailability.COMPLETE); } }); } ctx.flush(); }
public static void setup(RequestContext ctx, MeterIdPrefixFunction meterIdPrefixFunction) { if (ctx.hasAttr(ATTR_REQUEST_METRICS_SET)) { return; } ctx.attr(ATTR_REQUEST_METRICS_SET).set(true); ctx.log().addListener(log -> onRequest(log, meterIdPrefixFunction), RequestLogAvailability.REQUEST_HEADERS, RequestLogAvailability.REQUEST_CONTENT); }
@Override public O execute(ClientRequestContext ctx, I req) throws Exception { if (sampler.isSampled()) { ctx.log().addListener(log -> logRequest(logger, log, requestLogLevel, requestHeadersSanitizer, requestContentSanitizer), RequestLogAvailability.REQUEST_END); ctx.log().addListener(log -> logResponse(logger, log, requestLogLevel, requestHeadersSanitizer, requestContentSanitizer, successfulResponseLogLevel, failedResponseLogLevel, responseHeadersSanitizer, responseContentSanitizer), RequestLogAvailability.COMPLETE); } return delegate().execute(ctx, req); } }
@Override public O serve(ServiceRequestContext ctx, I req) throws Exception { ctx.log().addListener(log -> { final L structuredLog = logBuilder.build(log); if (structuredLog != null) { writeLog(log, structuredLog); } }, RequestLogAvailability.COMPLETE); return delegate().serve(ctx, req); }
private ClientRequestContext newContext(HttpMethod method, HttpRequest req) { final ReleasableHolder<EventLoop> eventLoop = factory().acquireEventLoop(endpoint); final ClientRequestContext ctx = new DefaultClientRequestContext( eventLoop.get(), meterRegistry, sessionProtocol, endpoint, method, uri().getRawPath(), uri().getRawQuery(), null, options(), req); ctx.log().addListener(log -> eventLoop.release(), RequestLogAvailability.COMPLETE); return ctx; } }
@Override public O serve(ServiceRequestContext ctx, I req) throws Exception { if (sampler.isSampled()) { ctx.log().addListener(log -> logRequest(((ServiceRequestContext) log.context()).logger(), log, requestLogLevel, requestHeadersSanitizer, requestContentSanitizer), RequestLogAvailability.REQUEST_END); ctx.log().addListener(log -> logResponse(((ServiceRequestContext) log.context()).logger(), log, requestLogLevel, requestHeadersSanitizer, requestContentSanitizer, successfulResponseLogLevel, failedResponseLogLevel, responseHeadersSanitizer, responseContentSanitizer), RequestLogAvailability.COMPLETE); } return delegate().serve(ctx, req); } }
releasableEventLoop.get(), meterRegistry, sessionProtocol, endpoint, method, path, query, fragment, options(), req); ctx.log().addListener(log -> releasableEventLoop.release(), RequestLogAvailability.COMPLETE); } else { ctx = new DefaultClientRequestContext(eventLoop, meterRegistry, sessionProtocol, endpoint,
private void propagateResponseSideLog(RequestLog lastChild) { // update the available logs if the lastChild already has them if (lastChild.isAvailable(RESPONSE_START)) { startResponse0(lastChild.responseStartTimeNanos(), lastChild.responseStartTimeMicros(), true); } if (lastChild.isAvailable(RESPONSE_FIRST_BYTES_TRANSFERRED)) { responseFirstBytesTransferred(lastChild.responseFirstBytesTransferredTimeNanos()); } if (lastChild.isAvailable(RESPONSE_HEADERS)) { responseHeaders(lastChild.responseHeaders()); } if (lastChild.isAvailable(RESPONSE_CONTENT)) { responseContent(lastChild.responseContent(), lastChild.rawResponseContent()); } if (lastChild.isAvailable(RESPONSE_END)) { endResponse0(lastChild.responseCause(), lastChild.responseEndTimeNanos()); } lastChild.addListener(log -> startResponse0( log.responseStartTimeNanos(), log.responseStartTimeMicros(), true), RESPONSE_START); lastChild.addListener(log -> responseFirstBytesTransferred( log.responseFirstBytesTransferredTimeNanos()), RESPONSE_FIRST_BYTES_TRANSFERRED); lastChild.addListener(log -> responseHeaders(log.responseHeaders()), RESPONSE_HEADERS); lastChild.addListener(log -> responseContent( log.responseContent(), log.rawResponseContent()), RESPONSE_CONTENT); lastChild.addListener(log -> endResponse0( log.responseCause(), log.responseEndTimeNanos()), RESPONSE_END); }
private static HelloService.Iface newSchemeCapturingClient( String uri, AtomicReference<SessionProtocol> sessionProtocol) { return new ClientBuilder(uri) .rpcDecorator((delegate, ctx, req) -> { ctx.log().addListener(log -> sessionProtocol.set(log.sessionProtocol()), RequestLogAvailability.REQUEST_START); return delegate.execute(ctx, req); }) .build(HelloService.Iface.class); }
@Override protected void configure(ServerBuilder sb) throws Exception { sb.service( "/", THttpService.of(ImmutableMap.of("", (Iface) name -> "none:" + name, "foo", name -> "foo:" + name, "bar", name -> "bar:" + name)) .decorate((delegate, ctx, req) -> { ctx.log().addListener(log -> { final RpcRequest call = (RpcRequest) log.requestContent(); if (call != null) { methodNames.add(call.method()); } }, RequestLogAvailability.REQUEST_CONTENT); return delegate.serve(ctx, req); })); } };
private static void onRequest(RequestLog log, MeterIdPrefixFunction meterIdPrefixFunction) { final RequestContext ctx = log.context(); final MeterRegistry registry = ctx.meterRegistry(); final MeterIdPrefix activeRequestsId = meterIdPrefixFunction.activeRequestPrefix(registry, log) .append("activeRequests"); final ActiveRequestMetrics activeRequestMetrics = MicrometerUtil.register( registry, activeRequestsId, ActiveRequestMetrics.class, (reg, prefix) -> reg.gauge(prefix.name(), prefix.tags(), new ActiveRequestMetrics(), ActiveRequestMetrics::doubleValue)); activeRequestMetrics.increment(); ctx.log().addListener(requestLog -> onResponse(requestLog, meterIdPrefixFunction, activeRequestMetrics), RequestLogAvailability.COMPLETE); }
decoBuilder.addRpc((delegate, ctx, req) -> { if (recordMessageLogs) { ctx.log().addListener(requestLogs::add, RequestLogAvailability.COMPLETE);
@Override public HttpResponse execute(ClientRequestContext ctx, HttpRequest req) throws Exception { final Span span = tracer.nextSpan(); injector.inject(span.context(), req.headers()); // For no-op spans, we only need to inject into headers and don't set any other attributes. if (span.isNoop()) { return delegate().execute(ctx, req); } final String method = ctx.method().name(); span.kind(Kind.CLIENT).name(method); ctx.log().addListener(log -> SpanContextUtil.startSpan(span, log), RequestLogAvailability.REQUEST_START); // Ensure the trace context propagates to children ctx.onChild(RequestContextCurrentTraceContext::copy); ctx.log().addListener(log -> { SpanTags.logWireSend(span, log.requestFirstBytesTransferredTimeNanos(), log); SpanTags.logWireReceive(span, log.responseFirstBytesTransferredTimeNanos(), log); finishSpan(span, log); }, RequestLogAvailability.COMPLETE); try (SpanInScope ignored = tracer.withSpanInScope(span)) { return delegate().execute(ctx, req); } }
@Override public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception { final TraceContextOrSamplingFlags contextOrFlags = extractor.extract(req.headers()); final Span span = contextOrFlags.context() != null ? tracer.joinSpan(contextOrFlags.context()) : tracer.nextSpan(contextOrFlags); // For no-op spans, nothing special to do. if (span.isNoop()) { return delegate().serve(ctx, req); } final String method = ctx.method().name(); span.kind(Kind.SERVER).name(method); ctx.log().addListener(log -> SpanContextUtil.startSpan(span, log), RequestLogAvailability.REQUEST_START); // Ensure the trace context propagates to children ctx.onChild(RequestContextCurrentTraceContext::copy); ctx.log().addListener(log -> { SpanTags.logWireReceive(span, log.requestFirstBytesTransferredTimeNanos(), log); SpanTags.logWireSend(span, log.responseFirstBytesTransferredTimeNanos(), log); SpanContextUtil.closeSpan(span, log); }, RequestLogAvailability.COMPLETE); try (SpanInScope ignored = tracer.withSpanInScope(span)) { return delegate().serve(ctx, req); } } }
@Override protected void configure(ServerBuilder sb) throws Exception { sb.workerGroup(EventLoopGroups.newEventLoopGroup(1), true); sb.defaultMaxRequestLength(Long.MAX_VALUE); sb.serviceUnder("/", new GrpcServiceBuilder() .addService(new UnitTestServiceImpl()) .build() .decorate(LoggingService.newDecorator()) .decorate((delegate, ctx, req) -> { ctx.log().addListener(requestLogQueue::add, RequestLogAvailability.COMPLETE); return delegate.serve(ctx, req); })); } };
@Override protected void configure(ServerBuilder sb) throws Exception { sb.workerGroup(EventLoopGroups.newEventLoopGroup(1), true); sb.defaultMaxRequestLength(0); sb.serviceUnder("/", new GrpcServiceBuilder() .addService(new UnitTestServiceImpl()) .build() .decorate(LoggingService.newDecorator()) .decorate((delegate, ctx, req) -> { ctx.log().addListener(requestLogQueue::add, RequestLogAvailability.COMPLETE); return delegate.serve(ctx, req); })); } };
@Before public void setUp() { requestLogQueue.clear(); final DecoratingClientFunction<HttpRequest, HttpResponse> requestLogRecorder = (delegate, ctx, req) -> { ctx.log().addListener(requestLogQueue::add, RequestLogAvailability.COMPLETE); return delegate.execute(ctx, req); }; blockingStub = new ClientBuilder("gproto+" + server.httpUri("/")) .defaultMaxResponseLength(MAX_MESSAGE_SIZE) .decorator(new LoggingClientBuilder().newDecorator()) .decorator(requestLogRecorder) .build(TestServiceBlockingStub.class); asyncStub = new ClientBuilder("gproto+" + server.httpUri("/")) .decorator(new LoggingClientBuilder().newDecorator()) .decorator(requestLogRecorder) .build(TestServiceStub.class); }
@Override protected HttpResponse doExecute(ClientRequestContext ctx, HttpRequest req, CircuitBreaker circuitBreaker) throws Exception { final HttpResponse response; try { response = delegate().execute(ctx, req); } catch (Throwable cause) { if (needsContentInStrategy) { reportSuccessOrFailure(circuitBreaker, strategyWithContent().shouldReportAsSuccess( ctx, HttpResponse.ofFailure(cause))); } else { reportSuccessOrFailure(circuitBreaker, strategy().shouldReportAsSuccess(ctx, cause)); } throw cause; } if (needsContentInStrategy) { final HttpResponseDuplicator resDuplicator = new HttpResponseDuplicator( response, maxSignalLength(ctx.maxResponseLength()), ctx.eventLoop()); reportSuccessOrFailure(circuitBreaker, strategyWithContent().shouldReportAsSuccess( ctx, resDuplicator.duplicateStream())); return resDuplicator.duplicateStream(true); } ctx.log().addListener(log -> { final Throwable cause = log.isAvailable(RequestLogAvailability.RESPONSE_END) ? log.responseCause() : null; reportSuccessOrFailure(circuitBreaker, strategy().shouldReportAsSuccess(ctx, cause)); }, RequestLogAvailability.RESPONSE_HEADERS); return response; }
@Override protected void configure(ServerBuilder sb) throws Exception { sb.workerGroup(EventLoopGroups.newEventLoopGroup(1), true); sb.defaultMaxRequestLength(0); sb.serviceUnder("/", new GrpcServiceBuilder() .setMaxInboundMessageSizeBytes(MAX_MESSAGE_SIZE) .addService(new UnitTestServiceImpl()) .enableUnframedRequests(true) .supportedSerializationFormats(GrpcSerializationFormats.values()) .build() .decorate(LoggingService.newDecorator()) .decorate((delegate, ctx, req) -> { ctx.log().addListener(requestLogQueue::add, RequestLogAvailability.COMPLETE); return delegate.serve(ctx, req); })); } };