/// <summary> /// Handles the logging of asynchronous unary calls. /// </summary> /// <typeparam name="TRequest">The type of the request.</typeparam> /// <typeparam name="TResponse">The type of the response.</typeparam> /// <param name="request">The request.</param> /// <param name="context">The context.</param> /// <param name="oldTask">The old task.</param> /// <param name="call">The call.</param> internal void HandleAsyncUnaryLogging <TRequest, TResponse>(TRequest request, ClientInterceptorContext <TRequest, TResponse> context, Task <TResponse> oldTask, AsyncUnaryCall <TResponse> call) where TRequest : class where TResponse : class { // Generating log entry is expensive, so let's do that only if the log source // has been configured to do so. if (TraceUtilities.ShouldGenerateRequestLogs()) { LogEntry logEntry = new LogEntry() { Host = config.ServerUrl, Method = context.Method.FullName, RequestHeaders = context.Options.Headers, Request = request, ResponseHeaders = Merge(GetResponseHeader(call.ResponseHeadersAsync), call.GetTrailers()), Response = (oldTask.IsFaulted) ? default : oldTask.Result, Exception = UnaryRpcInterceptor.ParseTaskException(oldTask.Exception), IsFailure = oldTask.IsFaulted, CustomerId = GetCustomerId(request), PartialFailures = (oldTask.IsFaulted) ? "" : GetPartialFailures(oldTask.Result) }; WriteLogs(logEntry); } }
/// <summary> /// Intercepts an asynchronous invocation of a simple remote call. /// </summary> /// <param name="request">The request message of the invocation.</param> /// <param name="context">The <see cref="ClientInterceptorContext{TRequest, TResponse}" /> /// associated with the current invocation.</param> /// <param name="continuation">The callback that continues the invocation process. /// This can be invoked zero or more times by the interceptor. /// The interceptor can invoke the continuation passing the given /// request value and context arguments, or substitute them as it sees fit.</param> /// <returns> /// An instance of <see cref="AsyncUnaryCall{TResponse}" /> /// representing an asynchronous unary invocation. /// The interceptor can simply return the return value of the /// continuation delegate passed to it intact, or construct its /// own substitute as it sees fit. /// </returns> public override AsyncUnaryCall <TResponse> AsyncUnaryCall <TRequest, TResponse>( TRequest request, ClientInterceptorContext <TRequest, TResponse> context, AsyncUnaryCallContinuation <TRequest, TResponse> continuation) { AsyncUnaryCall <TResponse> call = continuation(request, context); Task t = call.ResponseAsync.ContinueWith( delegate(Task <TResponse> oldTask) { // Generating log entry is expensive, so let's do that only if the log source // has been configured to do so. if (TraceUtilities.ShouldGenerateRequestLogs()) { LogEntry logEntry = new LogEntry() { Host = Config.ServerUrl, Method = context.Method.FullName, RequestHeaders = context.Options.Headers, Request = request, ResponseHeaders = GetResponseHeader(call), Response = (oldTask.IsFaulted) ? default(TResponse) : oldTask.Result, Exception = GetGoogleAdsException(oldTask.Exception), IsFailure = oldTask.IsFaulted, CustomerId = GetCustomerId(request), PartialFailures = (oldTask.IsFaulted)? "" : GetPartialFailures(oldTask.Result) }; OnLogEventAvailable?.Invoke(this, logEntry); } }); t.Wait(); return(call); }
/// <summary> /// Handles the logging of asynchronous server streaming calls. /// </summary> /// <typeparam name="TRequest">The type of the request.</typeparam> /// <typeparam name="TResponse">The type of the response.</typeparam> /// <param name="request">The request.</param> /// <param name="response">The response.</param> /// <param name="context">The context.</param> /// <param name="rpcException">The RPC exception.</param> /// <param name="call">The call.</param> internal void HandleAsyncServerStreamingLogging <TRequest, TResponse>(TRequest request, TResponse response, ClientInterceptorContext <TRequest, TResponse> context, AggregateException rpcException, AsyncServerStreamingCall <TResponse> call) where TRequest : class where TResponse : class { // Generating log entry is expensive, so let's do that only if the log source // has been configured to do so. if (TraceUtilities.ShouldGenerateRequestLogs()) { LogEntry logEntry = new LogEntry() { Host = config.ServerUrl, Method = context.Method.FullName, RequestHeaders = context.Options.Headers, Request = request, ResponseHeaders = Merge(GetResponseHeader(call.ResponseHeadersAsync), TryGetCallTrailers(call)), Response = response, Exception = UnaryRpcInterceptor.ParseTaskException(rpcException), IsFailure = (rpcException != null), CustomerId = GetCustomerId(request), PartialFailures = (rpcException != null) ? "" : GetPartialFailures(response) }; WriteLogs(logEntry); } }