csharp/rocketmq-client-csharp/ClientLoggerInterceptor.cs (83 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Threading.Tasks; using Grpc.Core; using Grpc.Core.Interceptors; using Microsoft.Extensions.Logging; namespace Org.Apache.Rocketmq { public class ClientLoggerInterceptor : Interceptor { private static readonly ILogger Logger = MqLogManager.CreateLogger<ClientLoggerInterceptor>(); public override TResponse BlockingUnaryCall<TRequest, TResponse>( TRequest request, ClientInterceptorContext<TRequest, TResponse> context, BlockingUnaryCallContinuation<TRequest, TResponse> continuation) { LogCall(context.Method); AddCallerMetadata(ref context); return continuation(request, context); } public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>( TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation) { LogCall(context.Method); AddCallerMetadata(ref context); var call = continuation(request, context); return new AsyncUnaryCall<TResponse>(HandleResponse(call.ResponseAsync), call.ResponseHeadersAsync, call.GetStatus, call.GetTrailers, call.Dispose); } private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> t) { var response = await t; Logger.LogTrace($"Response received: {response}"); return response; } public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>( ClientInterceptorContext<TRequest, TResponse> context, AsyncClientStreamingCallContinuation<TRequest, TResponse> continuation) { LogCall(context.Method); AddCallerMetadata(ref context); return continuation(context); } public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>( TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncServerStreamingCallContinuation<TRequest, TResponse> continuation) { LogCall(context.Method); AddCallerMetadata(ref context); return continuation(request, context); } public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>( ClientInterceptorContext<TRequest, TResponse> context, AsyncDuplexStreamingCallContinuation<TRequest, TResponse> continuation) { LogCall(context.Method); AddCallerMetadata(ref context); return continuation(context); } private void LogCall<TRequest, TResponse>(Method<TRequest, TResponse> method) where TRequest : class where TResponse : class { Logger.LogTrace($"Starting call. Type: {method.Type}. Request: {typeof(TRequest)}. Response: {typeof(TResponse)}"); } private void AddCallerMetadata<TRequest, TResponse>(ref ClientInterceptorContext<TRequest, TResponse> context) where TRequest : class where TResponse : class { var headers = context.Options.Headers; // Call doesn't have a headers collection to add to. // Need to create a new context with headers for the call. if (headers == null) { headers = new Metadata(); var options = context.Options.WithHeaders(headers); context = new ClientInterceptorContext<TRequest, TResponse>(context.Method, context.Host, options); } // Add caller metadata to call headers headers.Add("caller-user", Environment.UserName); headers.Add("caller-machine", Environment.MachineName); headers.Add("caller-os", Environment.OSVersion.ToString()); } } }