欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

gRPC全局异常捕获

程序员文章站 2022-04-14 18:36:49
gRPC全局异常捕获 引 一般的.net项目比如ASP.NET、控制台程序、Windows服务、桌面程序等都会有framework自带的全局异常捕获机制。ASP.NET的ExceptionFilterAttribute,控制台和Windos服务的AppDomain.CurrentDomain.Unh ......

grpc全局异常捕获

一般的.net项目比如asp.net、控制台程序、windows服务、桌面程序等都会有framework自带的全局异常捕获机制。asp.net的exceptionfilterattribute,控制台和windos服务的appdomain.currentdomain.unhandledexception。那么grpc的异常捕获是如何实现的。

思路

首先来说一下我走的弯路。我的grpc服务端是依托于.net的控制台程序,同时使用topshelf框架创建windows服务。topshelf有自带的全局异常内部实现也是对appdomain.currentdomain.unhandledexception做了一些封装。但是经过测试发现这种方式是不能捕获grpc内部的异常的。那么就判断了肯定grpc内部已经对全局的异常做了捕获,所以我们在控制台使用unhandledexception是不能捕获到的。然后查看grpc源码,发现grpc内部的所有异常都会内部消化,然后记录到一个叫ilogger的日志接口,因此我们只需要在控制台实现ilogger接口,在初始化grpc服务的时候声明就可以了。

实现

首先实现grpc内部的grpc.core.logging.ilogger接口

 public class grpclogger : ilogger
    {
        public ilogger fortype<t>()
        {
            return this;
        }

        public void debug(string message)
        {
            logutil.debug(message);
        }

        public void debug(string format, params object[] formatargs)
        {
            logutil.debug(format);
        }

        public void error(string message)
        {
            logutil.error(message);
        }

        public void error(string format, params object[] formatargs)
        {
            logutil.error(format);
        }

        public void error(exception exception, string message)
        {
            logutil.error($"{message}:{exception.tostring()}");
        }

        public void info(string message)
        {
            logutil.info(message);
        }

        public void info(string format, params object[] formatargs)
        {
            logutil.info(format);
        }

        public void warning(string message)
        {
            logutil.warn(message);
        }

        public void warning(string format, params object[] formatargs)
        {
            logutil.warn(format);
        }

        public void warning(exception exception, string message)
        {
            logutil.warn($"{message}:{exception.tostring()}");
        }
    }

logutil是我的项目里面的日志系统工具类。此处就相当于把grpc内部的异常日志全部记录到我自己实现的日志系统中,可以自行控制。

fortype()是返回指定类型的日志记录器,可以通过此方法来筛选需要记录的日志。

第二步就是直接把这个grpclogger类在服务初始化之后,服务开启之前申明

    grpcenvironment.setlogger(new grpclogger());

即可。