為了減少系統中通過try catch來捕獲異常的重復工作,在.net Core中用過異常過濾器來捕獲全局異常,並通過Log4Net記錄所有的錯誤日志
一.Log4Net安裝和使用
(1)引入Nuget包
Microsoft.Extensions.Logging.Log4Net.AspNetCore

(2)添加Log4Net配置文件
Log4Net.config
1 <?xml version="1.0" encoding="utf-8"?> 2 <log4net> 3 <!-- Define some output appenders --> 4 <appender name="rollingAppender" type="log4net.Appender.RollingFileAppender"> 5 <file value="log\log.txt" /> 6 <!--追加日志內容--> 7 <appendToFile value="true" /> 8 <!--防止多線程時不能寫Log,官方說線程非安全--> 9 <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> 10 <!--可以為:Once|Size|Date|Composite--> 11 <!--Composite為Size和Date的組合--> 12 <rollingStyle value="Composite" /> 13 <!--當備份文件時,為文件名加的后綴--> 14 <datePattern value="yyyyMMdd.TXT" /> 15 <!--日志最大個數,都是最新的--> 16 <!--rollingStyle節點為Size時,只能有value個日志--> 17 <!--rollingStyle節點為Composite時,每天有value個日志--> 18 <maxSizeRollBackups value="20" /> 19 <!--可用的單位:KB|MB|GB--> 20 <maximumFileSize value="3MB" /> 21 <!--置為true,當前最新日志文件名永遠為file節中的名字--> 22 <staticLogFileName value="true" /> 23 <!--輸出級別在INFO和ERROR之間的日志--> 24 <!--過濾級別 FATAL > ERROR > WARN > INFO > DEBUG--> 25 <filter type="log4net.Filter.LevelRangeFilter"> 26 <param name="LevelMin" value="ALL" /> 27 <param name="LevelMax" value="FATAL" /> 28 </filter> 29 <layout type="log4net.Layout.PatternLayout"> 30 <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/> 31 </layout> 32 </appender> 33 <root> 34 <priority value="ALL"/> 35 <level value="Microsoft"/> 36 <appender-ref ref="rollingAppender" /> 37 </root> 38 </log4net>
(3)
更改配置文件屬性 Configure,注冊中間件
loggerFactory.AddLog4Net();

(4)通過注入的方式使用
1 private readonly Frame_DeptService _service; 2 private readonly ILogger<FrameDeptController> _logger; 3 public FrameDeptController(Frame_DeptService service, ILogger<FrameDeptController> logger) 4 { 5 _service = service; 6 _logger = logger; 7 } 8 public IActionResult Index() 9 { 10 _logger.LogInformation("這是一個日志"); 11 return View(); 12 }
總結:和Nlog使用方式基本一致,Nlog的使用詳情可參考:
https://www.cnblogs.com/ywkcode/p/11558581.html
二.自定義異常過濾器
(1)
自定義一個異常過濾器需要繼承接口IExceptionFilter或者ExceptionFilterAttribute
IExceptionFilter:

ExceptionFilterAttribute:

兩者本質都是IExceptionFilter
但是ExceptionFilterAttribute增加了Order屬性用於優先級處理,
以及OnExceptionAsync異步處理的方法,所以本次過濾器選擇繼承接口ExceptionFilterAttribute
(2)新建類
“HttpGlobalExceptionFilter.cs”
1 public class HttpGlobalExceptionFilter : ExceptionFilterAttribute 2 { 3 private readonly ILogger<HttpGlobalExceptionFilter> _logger; 4 public HttpGlobalExceptionFilter(ILogger<HttpGlobalExceptionFilter> logger) 5 { 6 _logger = logger; 7 } 8 9 public override void OnException(ExceptionContext context) 10 { 11 12 var actionName = context.HttpContext.Request.RouteValues["controller"] + "/" + context.HttpContext.Request.RouteValues["action"]; 13 _logger.LogError($"--------{actionName} Error Begin--------"); 14 _logger.LogError($" Error Detail:" + context.Exception.Message); 15 //攔截處理 16 if (!context.ExceptionHandled) 17 { 18 context.Result = new JsonResult(new TableData 19 { 20 status = false, 21 msg = context.Exception.Message 22 }); 23 context.ExceptionHandled = true; 24 } 25 _logger.LogError($"--------{actionName} Error End--------"); 26 } 27 }
通過步驟一中的Log4Net記錄錯誤信息:
_logger.LogError($" Error Detail:" + context.Exception.Message);
(3)在“Startup.cs”的“ConfigureServices”中全局注冊異常處理過濾器HttpGlobalExceptionFilter
1 services.AddMvc( 2 options => 3 { 4 options.Filters.Add<HttpGlobalExceptionFilter>();//全局注冊 5 });
(4)查看錯誤日志
在控制器中拋出一個異常,用於查看是否捕獲異常
[HttpPost] public string LoadDeptTree() { PageResponse resp = new PageResponse(); resp.Message = _service.LoadDeptTree(); throw new Exception("錯誤測試"); //return JsonHelper.Instance.Serialize(resp); }
打開日志文件 log.text,捕獲成功,如下圖所示

三.日志優化
在log.text中,級別為Info的信息也會被寫入,影響錯誤的查看,通過設置log級別過濾
在配置文件
log4net.config中,修改如下:
<param name="LevelMin" value="WARN" /> <param name="LevelMax" value="FATAL" />

重新打開log.text,如下:
