asp.net core添加全局异常处理及log4net、Nlog应用
一、介紹
?
此篇文章將會介紹項目的全局異常收集以及采用log4net或者NLog記錄。
眾所周知,一旦自己的項目報錯,如果沒有進行處理都是顯示不友好的,有得甚至直接爆出錯誤頁面,看的也是很奇怪。
?為了避免出現這樣的錯誤以及在錯誤出現的時候可以進行收集錯誤,供維護人員進行bug修改,因此需要進行全局異常的收集。
?讓我們開始部署吧。?
此篇文章的目錄
1、log4net使用
2、Nlog使用
后期將會把NLog+ELK進行結合部署收集我們的asp.net core的項目。大家可以拭目以待吧。?
二、部署(log4net使用)
?1、新建一個asp.net core webapi的項目
然后目前我先引入 log4net? ?nuget包。
2、然后創建一個log4net.config文件
此文件中,我創建了一個是記錄 錯誤的文件夾(LogError)以及是記錄操作的文件夾(LogInfo),代碼如下:我把需要記錄的文件放在了log文件夾下面。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
? <log4net>
? ? <!-- 錯誤日志類-->
? ? <logger name="logerror">
? ? ? <level value="ALL" />
? ? ? <appender-ref ref="ErrorAppender" />
? ? </logger>
? ? <!-- 錯誤日志附加介質-->
? ? <appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
? ? ? <!--日志文件路徑-->
? ? ? <param name="File" value="Log\\LogError\\" />
? ? ? <!--是否是向文件中追加日志-->
? ? ? <param name="AppendToFile" value="true" />
? ? ? <!--log保留天數-->
? ? ? <param name="MaxSizeRollBackups" value="1000" />
? ? ? <!--最大文件大小-->
? ? ? <param name="MaxFileSize" value="10240" />
? ? ? <!--日志文件名是否是固定不變的-->
? ? ? <param name="StaticLogFileName" value="false" />
? ? ? <!--日志文件名格式為:2008-08-31.log-->
? ? ? <param name="DatePattern" value="yyyy-MM-dd".htm"" />
? ? ? <!--日志根據日期滾動-->
? ? ? <param name="RollingStyle" value="Date" />
? ? ? <!--信息日志布局-->
? ? ? <layout type="log4net.Layout.PatternLayout">
? ? ? ? <param name="ConversionPattern" value="<HR COLOR=red>%n【異常時間】:%d [%t] <BR>%n【異常級別】:%-5p <BR>%n%m <BR>%n <HR Size=1>"? />
? ? ? </layout>
? ? </appender>
? ? <!-- 信息日志類 -->
? ? <logger name="loginfo">
? ? ? <level value="ALL" />
? ? ? <appender-ref ref="InfoAppender" />
? ? </logger>
? ? <!-- 信息日志附加介質-->
? ? <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
? ? ? <!--日志文件路徑-->
? ? ? <param name="File" value="Log\\LogInfo\\" />
? ? ? <!--是否是向文件中追加日志-->
? ? ? <param name="AppendToFile" value="true" />
? ? ? <!--log保留天數-->
? ? ? <param name="MaxSizeRollBackups" value="100" />
? ? ? <param name="MaxFileSize" value="1" />
? ? ? <!--日志文件名是否是固定不變的-->
? ? ? <param name="StaticLogFileName" value="false" />
? ? ? <!--日志文件名格式為:2008-08-31.log-->
? ? ? <param name="DatePattern" value="yyyy-MM-dd".htm"" />
? ? ? <!--日志根據日期滾動-->
? ? ? <param name="RollingStyle" value="Date" />
? ? ? <!--信息日志布局-->
? ? ? <layout type="log4net.Layout.PatternLayout">
? ? ? ? <param name="ConversionPattern" value="<HR COLOR=blue>%n日志時間:%d [%t] <BR>%n日志級別:%-5p <BR>%n%m <BR>%n <HR Size=1>"? />
? ? ? </layout>
? ? </appender>
? </log4net>
? <!-- To customize the asp.net core module uncomment and edit the following section.?
? For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->
? <!--
? <system.webServer>
? ? <handlers>
? ? ? <remove name="aspNetCore"/>
? ? ? <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
? ? </handlers>
? ? <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
? </system.webServer>
? -->
</configuration>
3、在asp.net core項目中 Startup.cs 中需要添加初始化log4net的倉儲名,主要是用來給log4net標記一個名稱,這邊可以隨意。
?
4、在項目中創建一個類用來記錄log的日志格式以及數據分類存放
創建LogHelper.cs,
?定義log格式,當然自己可以隨意定義哈。
#region 全局異常錯誤記錄持久化
? ? ? ? /// <summary>
? ? ? ? /// 全局異常錯誤記錄持久化
? ? ? ? /// </summary>
? ? ? ? /// <param name="throwMsg"></param>
? ? ? ? /// <param name="ex"></param>
? ? ? ? public static void ErrorLog(string throwMsg, Exception ex)
? ? ? ? {
? ? ? ? ? ? string errorMsg = string.Format("【拋出信息】:{0} <br>【異常類型】:{1} <br>【異常信息】:{2} <br>【堆棧調用】:{3}", new object[] { throwMsg,
? ? ? ? ? ? ? ? ex.GetType().Name, ex.Message, ex.StackTrace });
? ? ? ? ? ? errorMsg = errorMsg.Replace("\r\n", "<br>");
? ? ? ? ? ? errorMsg = errorMsg.Replace("位置", "<strong style=\"color:red\">位置</strong>");
? ? ? ? ? ? logerror.Error(errorMsg);
? ? ? ? }
? ? ? ? #endregion
#region 自定義操作記錄
? ? ? ? /// <summary>
? ? ? ? /// 自定義操作記錄,與倉儲中的增刪改的日志是記錄同一張表
? ? ? ? /// </summary>
? ? ? ? /// <param name="throwMsg"></param>
? ? ? ? /// <param name="ex"></param>
? ? ? ? public static void WriteLog(string throwMsg, Exception ex)
? ? ? ? {
? ? ? ? ? ? string errorMsg = string.Format("【拋出信息】:{0} <br>【異常類型】:{1} <br>【異常信息】:{2} <br>【堆棧調用】:{3}", new object[] { throwMsg,
? ? ? ? ? ? ? ? ex.GetType().Name, ex.Message, ex.StackTrace });
? ? ? ? ? ? errorMsg = errorMsg.Replace("\r\n", "<br>");
? ? ? ? ? ? errorMsg = errorMsg.Replace("位置", "<strong style=\"color:red\">位置</strong>");
? ? ? ? ? ? logerror.Error(errorMsg);
? ? ? ? }
? ? ? ? #endregion
5、有了以上的log格式,這樣我就開始定義一下全局異常處理吧
我這邊先創建一個全局異常處理類?GlobalExceptions.cs 然后需要在startup.cs中注入
在ConfigureServices 方法中注入。
//注入全局異常捕獲services.AddMvc(o =>{ o.Filters.Add(typeof(GlobalExceptions)); });?6、GlobalExceptions類中添加處理,當然異常需要繼承IExceptionFilter。
代碼如下:
GlobalExceptionspublic class GlobalExceptions : IExceptionFilter
? ? {
? ? ? ? private readonly IHostingEnvironment _env;
? ? ? ? public GlobalExceptions(IHostingEnvironment env)
? ? ? ? {
? ? ? ? ? ? _env = env;
? ? ? ? }
? ? ? ? public void OnException(ExceptionContext context)
? ? ? ? {
? ? ? ? ? ? var json = new JsonErrorResponse();
? ? ? ? ? ? //這里面是自定義的操作記錄日志
? ? ? ? ? ? if (context.Exception.GetType() == typeof(UserOperationException))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? json.Message = context.Exception.Message;
? ? ? ? ? ? ? ? if (_env.IsDevelopment())
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? json.DevelopmentMessage = context.Exception.StackTrace;//堆棧信息
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? context.Result = new BadRequestObjectResult(json);//返回異常數據
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? json.Message = "發生了未知內部錯誤";
? ? ? ? ? ? ? ? if (_env.IsDevelopment())
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? json.DevelopmentMessage = context.Exception.StackTrace;//堆棧信息
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? context.Result = new InternalServerErrorObjectResult(json);
? ? ? ? ? ? }
? ? ? ? ? ? //采用log4net 進行錯誤日志記錄
? ? ? ? ? ? LogHelper.ErrorLog(json.Message, context.Exception);
? ? ? ? }
? ? }
? ? public class InternalServerErrorObjectResult : ObjectResult
? ? {
? ? ? ? public InternalServerErrorObjectResult(object value) : base(value)
? ? ? ? {
? ? ? ? ? ? StatusCode = StatusCodes.Status500InternalServerError;
? ? ? ? }
? ? }
JsonErrorResponse.cs?
public class JsonErrorResponse
? ? {
? ? ? ? /// <summary>
? ? ? ? /// 生產環境的消息
? ? ? ? /// </summary>
? ? ? ? public string Message { get; set; }
? ? ? ? /// <summary>
? ? ? ? /// 開發環境的消息
? ? ? ? /// </summary>
? ? ? ? public string DevelopmentMessage { get; set; }
? ? }
/// <summary>
? ? /// 操作日志
? ? /// </summary>
? ? public class UserOperationException : Exception
? ? {
? ? ? ? public UserOperationException() { }
? ? ? ? public UserOperationException(string message) : base(message) { }
? ? ? ? public UserOperationException(string message, Exception innerException) : base(message, innerException) { }
? ? }
自此,全局異常配置完成,然后我們可以測試一下,隨便寫一個除以0的代碼在日志記錄中就會出現如下的展示:
哇,發現我的錯誤日志的格式非常的清楚,當然這個跟我的做事態度以及性格有很大的關系的啦,畢竟樓主還是很帥的。哈哈哈。
?三、NLog使用
?
1、在項目中添加nlog的nuget包引入,“NLog.Web.AspNetCore”
2、創建nlog.config文件,大家會發現我的log格式跟上面的格式操作,而且我的分層層次也很清楚。哈哈
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
? ? ? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
? ? ? autoReload="true">
? <!-- the targets to write to -->
? <targets>
? ? <!-- 輸出到文件,這個文件記錄所有的日志 -->
? ? <target xsi:type="File" name="allfile" fileName="Log\LogAll\${shortdate}.htm"
? ? ? ? ? ? ? ? layout="<HR COLOR=red>${longdate}<BR>${logger}<BR>${uppercase:${level}}<BR>${message} ${exception}<HR Size=1>" />
? ? <!-- 輸出到文件,這個文件記錄錯誤日志 -->
? ? <target xsi:type="File" name="logError" fileName="Log\LogError\${shortdate}.htm"
? ? ? ? ? ? layout="<HR COLOR=red>【異常時間】:${date} <BR>【異常級別】:${level:uppercase=true} <BR>${message}<HR Size=1>" />
? ? <!-- 輸出到文件,這個文件記錄操作日志 -->
? ? <target xsi:type="File" name="logInfo" fileName="Log\LogInfo\${shortdate}.htm"
? ? ? ? ? ? ? ? ?layout="<HR COLOR=red>【操作時間】:${date} <BR>【操作級別】:${level:uppercase=true} <BR>${message}<HR Size=1>" />
? </targets>
? <!-- rules to map from logger name to target -->
? <rules>
? ? <!--All logs, including from Microsoft-->
? ? <logger name="*" minlevel="Trace" writeTo="allfile" />
? ? <logger name="*" minlevel="Error" writeTo="logError" />
? ? <logger name="*" minlevel="Info" writeTo="logInfo" />
? ? <logger name="Microsoft.*" maxLevel="Info" final="true" />
? </rules>
</nlog>
3、在startup.cs中的? Configure方法注入
//ILoggerFactory loggerFactoryloggerFactory.AddNLog(); NLog.LogManager.LoadConfiguration("nlog.config"); //填入上面創建的文件的名稱
?
4、創建NLogHelp.cs類
public class NLogHelp
? ? {
? ? ? ? public static Logger logger = LogManager.GetCurrentClassLogger();
? ? ? ? public static void ErrorLog(string throwMsg, Exception ex)
? ? ? ? {
? ? ? ? ? ? string errorMsg = string.Format("【異常信息】:{0} <br>【異常類型】:{1} <br>【堆棧調用】:{2}",
? ? ? ? ? ? ? ? new object[] { throwMsg, ex.GetType().Name, ex.StackTrace });
? ? ? ? ? ? errorMsg = errorMsg.Replace("\r\n", "<br>");
? ? ? ? ? ? errorMsg = errorMsg.Replace("位置", "<strong style=\"color:red\">位置</strong>");
? ? ? ? ? ? logger.Error(errorMsg);
? ? ? ? }
? ? ? ? public static void InfoLog(string operateMsg)
? ? ? ? {
? ? ? ? ? ? string errorMsg = string.Format("【操作信息】:{0} <br>",
? ? ? ? ? ? ? ? new object[] { operateMsg });
? ? ? ? ? ? errorMsg = errorMsg.Replace("\r\n", "<br>");
? ? ? ? ? ? logger.Info(errorMsg);
? ? ? ? }
? ? }
5、在上面log4net中的GlobalExceptions類把
LogHelper.ErrorLog(json.Message, context.Exception)替換成如下:NLogHelp.ErrorLog(json.Message,context.Exception)即可。運行測試如下:
【異常時間】:2018/09/03 14:41:36.786?
【異常級別】:ERROR?
【異常信息】:錯誤消息:Failed to create instance of type
at AspectCore.Injector.ServiceCallSiteResolver.ResolvePropertyInject(ServiceDefinition service)
【異常類型】:InvalidOperationException?
【堆棧調用】: at AspectCore.Injector.ServiceCallSiteResolver.ResolveTypeService(TypeServiceDefinition typeServiceDefinition)
at AspectCore.Injector.ServiceCallSiteResolver.ResolvePropertyInject(ServiceDefinition service)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at AspectCore.Injector.ServiceResolver.b
自此,完美搞定,等后期我將會介紹采用ELK+NLog進行數據采集及展示,請大家拭目以待吧。
原文鏈接:https://www.cnblogs.com/guolianyu/p/9580626.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的asp.net core添加全局异常处理及log4net、Nlog应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET Core 跨平台物联网框架 S
- 下一篇: ASP.NET Core 2.0利用Ma