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());
即可。