Search⌘ K
AI Features

Solution Review: Applying Logging Interceptors

Explore how to implement logging interceptors in a gRPC solution for ASP.NET Core applications. Understand how to register interceptors on both server and client sides, enabling detailed monitoring of gRPC calls to improve application observability and maintainability.

We'll cover the following...

Overview

The complete solution to the challenge is presented in the setup below. The modified lines of code are highlighted.

using Grpc.Core;
using Grpc.Core.Interceptors;
using Microsoft.Extensions.Logging;

namespace BasicGrpcService;

public class LoggingInterceptor : Interceptor
{
    private readonly ILogger<LoggingInterceptor> _logger;

    public LoggingInterceptor(ILogger<LoggingInterceptor>  logger)
    {
        _logger = logger;
    }

    public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation)
    {
        LogCall(context);

        try
        {
            return await continuation(request, context);
        }
        catch (Exception ex)
        {
            LogException(ex);
            throw;
        }
    }

    public override async Task<TResponse> ClientStreamingServerHandler<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, ServerCallContext context, ClientStreamingServerMethod<TRequest, TResponse> continuation)
    {
        LogCall(context);

        try
        {
            return await continuation(requestStream, context);
        }
        catch (Exception ex)
        {
            LogException(ex);
            throw;
        }
    }

    public override async Task ServerStreamingServerHandler<TRequest, TResponse>(TRequest request, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, ServerStreamingServerMethod<TRequest, TResponse> continuation)
    {
        LogCall(context);

        try
        {
            await continuation(request, responseStream, context);
        }
        catch (Exception ex)
        {
            LogException(ex);
            throw;
        }
    }

    public override async Task DuplexStreamingServerHandler<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, DuplexStreamingServerMethod<TRequest, TResponse> continuation)
    {
        LogCall(context);

        try
        {
            await continuation(requestStream, responseStream, context);
        }
        catch (Exception ex)
        {
            LogException(ex);
            throw;
        }
    }

    private void LogCall(ServerCallContext context)
    {
        _logger.LogDebug($"gRPC request: {context.GetHttpContext().Request.Path}");
    }

    private void LogException(Exception ex)
    {
        _logger.LogError(ex, "gRPC error occurred");
    }
}
Complete solution setup

Solving the challenge

To register ...