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包。

640?wx_fmt=png

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&quot;.htm&quot;" />

      <!--日志根据日期滚动-->

      <param name="RollingStyle" value="Date" />

      <!--信息日志布局-->

      <layout type="log4net.Layout.PatternLayout">

        <param name="ConversionPattern" value="&lt;HR COLOR=red&gt;%n【异常时间】:%d [%t] &lt;BR&gt;%n【异常级别】:%-5p &lt;BR&gt;%n%m &lt;BR&gt;%n &lt;HR Size=1&gt;"  />

      </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&quot;.htm&quot;" />

      <!--日志根据日期滚动-->

      <param name="RollingStyle" value="Date" />

      <!--信息日志布局-->

      <layout type="log4net.Layout.PatternLayout">

        <param name="ConversionPattern" value="&lt;HR COLOR=blue&gt;%n日志时间:%d [%t] &lt;BR&gt;%n日志级别:%-5p &lt;BR&gt;%n%m &lt;BR&gt;%n &lt;HR Size=1&gt;"  />

      </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标记一个名称,这边可以随意。

640?wx_fmt=png

 

4、在项目中创建一个类用来记录log的日志格式以及数据分类存放

创建LogHelper.cs,

640?wx_fmt=png

 定义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。

代码如下:

GlobalExceptions 

public 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的代码在日志记录中就会出现如下的展示:

哇,发现我的错误日志的格式非常的清楚,当然这个跟我的做事态度以及性格有很大的关系的啦,毕竟楼主还是很帅的。哈哈哈。

640?wx_fmt=png

 三、NLog使用


 

1、在项目中添加nlog的nuget包引入,“NLog.Web.AspNetCore”

640?wx_fmt=png

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="&lt;HR COLOR=red&gt;${longdate}&lt;BR&gt;${logger}&lt;BR&gt;${uppercase:${level}}&lt;BR&gt;${message} ${exception}&lt;HR Size=1&gt;" />


    <!-- 输出到文件,这个文件记录错误日志 -->

    <target xsi:type="File" name="logError" fileName="Log\LogError\${shortdate}.htm"

            layout="&lt;HR COLOR=red&gt;【异常时间】:${date} &lt;BR&gt;【异常级别】:${level:uppercase=true} &lt;BR&gt;${message}&lt;HR Size=1&gt;" />


    <!-- 输出到文件,这个文件记录操作日志 -->

    <target xsi:type="File" name="logInfo" fileName="Log\LogInfo\${shortdate}.htm"

                 layout="&lt;HR COLOR=red&gt;【操作时间】:${date} &lt;BR&gt;【操作级别】:${level:uppercase=true} &lt;BR&gt;${message}&lt;HR Size=1&gt;" />

  </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 loggerFactory
loggerFactory.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

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/320088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客网 【每日一题】5月20日题目 简单瞎搞题

比赛链接 文章目录题目描述题解&#xff1a;代码&#xff1a;题目描述 输入描述: 第一行一个数 n。 然后 n 行&#xff0c;每行两个数表示 li,ri。 输出描述: 输出一行一个数表示答案。 示例1 输入 5 1 2 2 3 3 4 4 5 5 6输出 26备注: 1 ≤ n , li , ri ≤ 100 题解&#xf…

P6688-可重集【字符串hash,线段树】

正题 题目链接:https://www.luogu.com.cn/problem/P6688 解题思路 nnn个数&#xff0c;每次有操作 修改一个数询问两个区间是否他们中的元素分别组成的可重集合A,BA,BA,B&#xff0c;满足对于每个AiBikA_iB_ikAi​Bi​k其中kkk是一个相同的数 解题思路 先不考虑kkk的问题 我…

【贪心】畜栏预定(ybtoj 贪心-1-3)

畜栏预定 ybtoj 贪心-1-3 题目大意 有n头牛&#xff0c;每头牛会在某一连续时间段吃草&#xff0c;问你同一时间最对有多少头牛&#xff0c;最后对于每一头牛给一个吃草的位置&#xff0c;使得同一时间内吃草的牛的位置不重合 输入样例 5 1 10 2 4 3 6 5 8 4 7输出样例 4…

ASP.NET Core 2.0利用MassTransit集成RabbitMQ

在ASP.NET Core上利用MassTransit来集成使用RabbitMQ真的很简单&#xff0c;代码也很简洁。近期因为项目需要&#xff0c;我便在这基础上再次进行了封装&#xff0c;抽成了公共方法&#xff0c;使得使用RabbitMQ的调用变得更方便简洁。那么&#xff0c;就让咱们来瞧瞧其魅力所在…

简单的数据结构题(多项式、拉格朗日插值、线段树)

简单的数据结构题 首先考虑计算要求的式子&#xff0c;不妨设l1,rnl1,rnl1,rn。 ∑i1naik∏j̸i1−aiajai−aj\sum_{i1}^{n}a_i^k\prod_{j\noti}\frac{1-a_ia_j}{a_i-a_j}∑i1n​aik​∏j​i​ai​−aj​1−ai​aj​​ ∑i1naik∏j̸i1ai−aj∏j̸i(1−aiaj)\sum_{i1}^{n}a_…

牛客网 【每日一题】5月21日题目 图的遍历

链接&#xff1a; 文章目录题目描述题解代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 32768K&#xff0c;其他语言65536K 64bit IO Format: %lld题目描述 小sun最近为了应付考试&#xff0c;正在复习图论&#xff0c;他现在学…

P4306-[JSOI2010]连通数【bitset】

正题 题目链接:https://www.luogu.com.cn/problem/P4306 题目大意 nnn个点的有向图&#xff0c;求图上可以相互到达点数。 解题思路 就是bitsetbitsetbitset这个黑科技的模板&#xff0c;首先是传递闭包 fi,jfi,k∣fk,jf_{i,j}f_{i,k}|f_{k,j}fi,j​fi,k​∣fk,j​也就是如果…

【贪心】国王游戏(ybtoj 贪心-1-4)

国王游戏 ybtoj 贪心-1-4 题目大意 有一个国王和n个大臣 每人左右手分别有一个数&#xff0c;现在然你对大臣们排列&#xff08;国王在第一个&#xff09; 每个大臣所得金币是前面的人左手上的数的积除以他右手上的数 现在问你获得金币最多的大臣最少得多少金币 样例输入 …

《通过C#学Proto.Actor模型》之 HelloWorld

在微服务中&#xff0c;数据最终一致性的一个解决方案是通过有状态的Actor模型来达到&#xff0c;那什么是Actor模型呢&#xff1f;Actor是并行的计算模型&#xff0c;包含状态&#xff0c;行为&#xff0c;并且包含一个邮箱&#xff0c;来异步处理消息。关于Actor的介绍可参考…

牛客网【每日一题】5月22日 [CQOI2009]中位数图

链接&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 给出1~n的一个排列&#xff0c;统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有…

[XSY] 计数(DP,NTT,分治)

计数 考虑转化题目&#xff0c;变为网格上有若干个点&#xff0c;要从(0,0)(0,0)(0,0)走到(n,an1)(n,a_{n1})(n,an1​) &#xff0c;每一步只能往右走一步或往上走一步&#xff0c;且若当前在(i,j)(i,j)(i,j) &#xff0c;必须满足0≤j≤ai10\leq j\leq a_{i1}0≤j≤ai1​&…

P3700-[CQOI2017]小Q的表格【分块,欧拉函数】

正题 题目链接:https://www.luogu.com.cn/problem/P3700 题目大意 一个n∗nn*nn∗n个数的数字表格&#xff0c;开始位置(a,b)(a,b)(a,b)上的是a∗ba*ba∗b。数字表格需满足以下条件 对于任意(a,b)(a,b)(a,b)有f(a,b)f(b,a)f(a,b)f(b,a)f(a,b)f(b,a)对于任意(a,b)(a,b)(a,b)有…

.Net Core应用框架Util介绍(一)

距离上次发文&#xff0c;已经过去了三年半&#xff0c;这几年技术更新节奏异常迅猛&#xff0c;.Net进入了跨平台时代&#xff0c;前端也被革命性的颠覆。回顾2015年&#xff0c;正当我还沉迷于JQuery EasyUi的封装时&#xff0c;突然意识到技术已经过时。JQuery在面对更加复…

牛客网 【每日一题】5月26日题目精讲 [JSOI2007]建筑抢修

链接&#xff1a; 文章目录题目描述题意&#xff1a;题解&#xff1a;题目描述 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏&#xff1a;经过了一场激烈的战斗&#xff0c;T部落消灭了所有z部落的入侵者。但是T部落的基地里已经有N个建筑设施受到了严重的损伤&#xf…

【二分】数列分段(ybtoj 二分-1-1)

数列分段 ybtoj 二分-1-1 题目大意 给出一个序列A&#xff0c;让你把它分成m段&#xff0c;使每段和最大值最小 输入样例 5 3 4 2 4 5 1输出样例 6数据范围 1⩽M⩽N⩽1051\leqslant M\leqslant N\leqslant 10^51⩽M⩽N⩽105 sum{Ai}⩽109sum\begin{Bmatrix}A_i\end{Bmatr…

CF878E-Numbers on the blackboard【并查集,贪心】

正题 题目链接:https://www.luogu.com.cn/problem/CF878E 题目大意 nnn个数字&#xff0c;每次可以把两个相邻的数字x,yx,yx,y变为x2yx2yx2y。 mmm次询问一个区间合成一个数字后最大是多少。 解题思路 答案可以把每个数字变成xicix_i^{c_i}xici​​&#xff0c;其中ci≤ci−1…

2021-03-24

非空G个数G的大小n的奇偶性答案>4\\D3\奇数D3至少一个大小>2\D3均为1偶数D-12大小均>2\D2至少一个大小>2奇数D2一个大小1&#xff0c;一个大小>1偶数D-12均为1奇数D-12均为1偶数

牛客网【每日一题】5月27日题目精讲 货币系统

链接&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;题目描述 在网友的国度中共有n种不同面额的货币&#xff0c;第i种货币的面额为a[i]&#xff0c;你可以假设每一种货币都有无穷多张。为了方便&#xff0c;我们把货币种数为n、面额数组为a[1…n]的货币系统记…

使用.NET Core+Docker 开发微服务

.NET Core发布很久了,因为近几年主要使用java&#xff0c;所以还没使用过.NET Core&#xff0c;今天正好有一个c#写的demo&#xff0c;需要做成服务&#xff0c;不想再转成java来实现&#xff0c;考虑使用.NET CORE来尝下鲜&#xff0c;目标是开发一个微服务&#xff0c;然后部…

【二分】防具布置/秦腾与教学评估(ybtoj 二分-1-2/jzoj 1253/luogu 4403)

正题 ybtoj 二分-1-2 jzoj 1253 luogu 4403 题目大意 给出n组数&#xff1a;si,ei,dis_i,e_i,d_isi​,ei​,di​ 对于每组数据&#xff0c;表示在sis_isi​加1&#xff0c;然后每隔did_idi​就加1&#xff0c;当位置大于eie_iei​时结束 题目保证数字是奇数的位置最多只有1个…