asp.net core添加全局异常处理及log4net、Nlog应用

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 文章来源于阿里云 MVP郭联钰。

 整体架构目录:ASP.NET Core分布式项目实战-目录


一、介绍


此篇文章将会介绍项目的全局异常收集以及采用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>
&lt;!-- 错误日志类--&gt;
&lt;logger name=<span style="color: #800000;">"</span><span style="color: #800000;">logerror</span><span style="color: #800000;">"</span>&gt;
  &lt;level value=<span style="color: #800000;">"</span><span style="color: #800000;">ALL</span><span style="color: #800000;">"</span> /&gt;
  &lt;appender-<span style="color: #0000ff;">ref</span> <span style="color: #0000ff;">ref</span>=<span style="color: #800000;">"</span><span style="color: #800000;">ErrorAppender</span><span style="color: #800000;">"</span> /&gt;
&lt;/logger&gt;
&lt;!-- 错误日志附加介质--&gt;
&lt;appender name=<span style="color: #800000;">"</span><span style="color: #800000;">ErrorAppender</span><span style="color: #800000;">"</span> type=<span style="color: #800000;">"</span><span style="color: #800000;">log4net.Appender.RollingFileAppender</span><span style="color: #800000;">"</span>&gt;
  &lt;!--日志文件路径--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">File</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><strong><span style="color: #ff0000;">Log\\LogError\\</span></strong><span style="color: #800000;">"</span> /&gt;
  &lt;!--是否是向文件中追加日志--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">AppendToFile</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">true</span><span style="color: #800000;">"</span> /&gt;
  &lt;!--log保留天数--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">MaxSizeRollBackups</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">1000</span><span style="color: #800000;">"</span> /&gt;
  &lt;!--最大文件大小--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">MaxFileSize</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">10240</span><span style="color: #800000;">"</span> /&gt;
  &lt;!--日志文件名是否是固定不变的--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">StaticLogFileName</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">false</span><span style="color: #800000;">"</span> /&gt;
  &lt;!--日志文件名格式为:<span style="color: #800080;">2008</span>-<span style="color: #800080;">08</span>-<span style="color: #800080;">31</span>.log--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">DatePattern</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">yyyy-MM-dd&amp;quot;.htm&amp;quot;</span><span style="color: #800000;">"</span> /&gt;
  &lt;!--日志根据日期滚动--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">RollingStyle</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">Date</span><span style="color: #800000;">"</span> /&gt;
  &lt;!--信息日志布局--&gt;
  &lt;layout type=<span style="color: #800000;">"</span><span style="color: #800000;">log4net.Layout.PatternLayout</span><span style="color: #800000;">"</span>&gt;
    &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">ConversionPattern</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">&amp;lt;HR COLOR=red&amp;gt;%n【异常时间】:%d [%t] &amp;lt;BR&amp;gt;%n【异常级别】:%-5p &amp;lt;BR&amp;gt;%n%m &amp;lt;BR&amp;gt;%n &amp;lt;HR Size=1&amp;gt;</span><span style="color: #800000;">"</span>  /&gt;
  &lt;/layout&gt;
&lt;/appender&gt;

&lt;!-- 信息日志类 --&gt;
&lt;logger name=<span style="color: #800000;">"</span><span style="color: #800000;">loginfo</span><span style="color: #800000;">"</span>&gt;
  &lt;level value=<span style="color: #800000;">"</span><span style="color: #800000;">ALL</span><span style="color: #800000;">"</span> /&gt;
  &lt;appender-<span style="color: #0000ff;">ref</span> <span style="color: #0000ff;">ref</span>=<span style="color: #800000;">"</span><span style="color: #800000;">InfoAppender</span><span style="color: #800000;">"</span> /&gt;
&lt;/logger&gt;
&lt;!-- 信息日志附加介质--&gt;
&lt;appender name=<span style="color: #800000;">"</span><span style="color: #800000;">InfoAppender</span><span style="color: #800000;">"</span> type=<span style="color: #800000;">"</span><span style="color: #800000;">log4net.Appender.RollingFileAppender</span><span style="color: #800000;">"</span>&gt;
  &lt;!--日志文件路径--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">File</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><strong><span style="color: #ff0000;">Log\\LogInfo\\</span></strong><span style="color: #800000;">"</span> /&gt;
  &lt;!--是否是向文件中追加日志--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">AppendToFile</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">true</span><span style="color: #800000;">"</span> /&gt;
  &lt;!--log保留天数--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">MaxSizeRollBackups</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">100</span><span style="color: #800000;">"</span> /&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">MaxFileSize</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span> /&gt;
  &lt;!--日志文件名是否是固定不变的--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">StaticLogFileName</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">false</span><span style="color: #800000;">"</span> /&gt;
  &lt;!--日志文件名格式为:<span style="color: #800080;">2008</span>-<span style="color: #800080;">08</span>-<span style="color: #800080;">31</span>.log--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">DatePattern</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">yyyy-MM-dd&amp;quot;.htm&amp;quot;</span><span style="color: #800000;">"</span> /&gt;
  &lt;!--日志根据日期滚动--&gt;
  &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">RollingStyle</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">Date</span><span style="color: #800000;">"</span> /&gt;
  &lt;!--信息日志布局--&gt;
  &lt;layout type=<span style="color: #800000;">"</span><span style="color: #800000;">log4net.Layout.PatternLayout</span><span style="color: #800000;">"</span>&gt;
    &lt;param name=<span style="color: #800000;">"</span><span style="color: #800000;">ConversionPattern</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">&amp;lt;HR COLOR=blue&amp;gt;%n日志时间:%d [%t] &amp;lt;BR&amp;gt;%n日志级别:%-5p &amp;lt;BR&amp;gt;%n%m &amp;lt;BR&amp;gt;%n &amp;lt;HR Size=1&amp;gt;</span><span style="color: #800000;">"</span>  /&gt;
  &lt;/layout&gt;
&lt;/appender&gt;

</log4net>

<!-- To customize the asp.net core module uncomment and edit the following section.
For more info see https:
style="color: #008000;">//go.microsoft.com/fwlink/?linkid=838655 -->
<!--
<system.webServer>

&lt;handlers&gt;
  &lt;remove name=<span style="color: #800000;">"</span><span style="color: #800000;">aspNetCore</span><span style="color: #800000;">"</span>/&gt;
  &lt;add name=<span style="color: #800000;">"</span><span style="color: #800000;">aspNetCore</span><span style="color: #800000;">"</span> path=<span style="color: #800000;">"</span><span style="color: #800000;">*</span><span style="color: #800000;">"</span> verb=<span style="color: #800000;">"</span><span style="color: #800000;">*</span><span style="color: #800000;">"</span> modules=<span style="color: #800000;">"</span><span style="color: #800000;">AspNetCoreModule</span><span style="color: #800000;">"</span> resourceType=<span style="color: #800000;">"</span><span style="color: #800000;">Unspecified</span><span style="color: #800000;">"</span>/&gt;
&lt;/handlers&gt;
&lt;aspNetCore processPath=<span style="color: #800000;">"</span><span style="color: #800000;">%LAUNCHER_PATH%</span><span style="color: #800000;">"</span> arguments=<span style="color: #800000;">"</span><span style="color: #800000;">%LAUNCHER_ARGS%</span><span style="color: #800000;">"</span> stdoutLogEnabled=<span style="color: #800000;">"</span><span style="color: #800000;">false</span><span style="color: #800000;">"</span> stdoutLogFile=<span style="color: #800000;">"</span><span style="color: #800000;">.\logs\stdout</span><span style="color: #800000;">"</span> /&gt;

</system.webServer>
-->

</configuration>


复制代码

3、在asp.net core项目中 Startup.cs 中需要添加初始化log4net的仓储名,主要是用来给log4net标记一个名称,这边可以随意。


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

创建LogHelper.cs,



定义log格式,当然自己可以随意定义哈。



#region 全局异常错误记录持久化
    <span style="color: #808080;">///</span> <span style="color: #808080;">&lt;summary&gt;</span>
    <span style="color: #808080;">///</span><span style="color: #008000;"> 全局异常错误记录持久化
    </span><span style="color: #808080;">///</span> <span style="color: #808080;">&lt;/summary&gt;</span>
    <span style="color: #808080;">///</span> <span style="color: #808080;">&lt;param name="throwMsg"&gt;&lt;/param&gt;</span>
    <span style="color: #808080;">///</span> <span style="color: #808080;">&lt;param name="ex"&gt;&lt;/param&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> ErrorLog(<span style="color: #0000ff;">string</span><span style="color: #000000;"> throwMsg, Exception ex)
    {
        </span><span style="color: #0000ff;">string</span> errorMsg = <span style="color: #0000ff;">string</span>.Format(<span style="color: #800000;">"</span><span style="color: #800000;">【抛出信息】:{0} &lt;br&gt;【异常类型】:{1} &lt;br&gt;【异常信息】:{2} &lt;br&gt;【堆栈调用】:{3}</span><span style="color: #800000;">"</span>, <span style="color: #0000ff;">new</span> <span style="color: #0000ff;">object</span><span style="color: #000000;">[] { throwMsg,
            ex.GetType().Name, ex.Message, ex.StackTrace });
        errorMsg </span>= errorMsg.Replace(<span style="color: #800000;">"</span><span style="color: #800000;">\r\n</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">&lt;br&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">);
        errorMsg </span>= errorMsg.Replace(<span style="color: #800000;">"</span><span style="color: #800000;">位置</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">&lt;strong style=\"color:red\"&gt;位置&lt;/strong&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">);
        logerror.Error(errorMsg);
    }
    </span><span style="color: #0000ff;">#endregion</span></pre>



#region 自定义操作记录
    <span style="color: #808080;">///</span> <span style="color: #808080;">&lt;summary&gt;</span>
    <span style="color: #808080;">///</span><span style="color: #008000;"> 自定义操作记录,与仓储中的增删改的日志是记录同一张表
    </span><span style="color: #808080;">///</span> <span style="color: #808080;">&lt;/summary&gt;</span>
    <span style="color: #808080;">///</span> <span style="color: #808080;">&lt;param name="throwMsg"&gt;&lt;/param&gt;</span>
    <span style="color: #808080;">///</span> <span style="color: #808080;">&lt;param name="ex"&gt;&lt;/param&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> WriteLog(<span style="color: #0000ff;">string</span><span style="color: #000000;"> throwMsg, Exception ex)
    {
        </span><span style="color: #0000ff;">string</span> errorMsg = <span style="color: #0000ff;">string</span>.Format(<span style="color: #800000;">"</span><span style="color: #800000;">【抛出信息】:{0} &lt;br&gt;【异常类型】:{1} &lt;br&gt;【异常信息】:{2} &lt;br&gt;【堆栈调用】:{3}</span><span style="color: #800000;">"</span>, <span style="color: #0000ff;">new</span> <span style="color: #0000ff;">object</span><span style="color: #000000;">[] { throwMsg,
            ex.GetType().Name, ex.Message, ex.StackTrace });
        errorMsg </span>= errorMsg.Replace(<span style="color: #800000;">"</span><span style="color: #800000;">\r\n</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">&lt;br&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">);
        errorMsg </span>= errorMsg.Replace(<span style="color: #800000;">"</span><span style="color: #800000;">位置</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">&lt;strong style=\"color:red\"&gt;位置&lt;/strong&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">);
        logerror.Error(errorMsg);
    }
    </span><span style="color: #0000ff;">#endregion</span></pre>


 5、有了以上的log格式,这样我就开始定义一下全局异常处理吧

我这边先创建一个全局异常处理类 GlobalExceptions.cs 然后需要在startup.cs中注入


在ConfigureServices 方法中注入。



//注入全局异常捕获
services.AddMvc(o =>
{
o.Filters.Add(
typeof(GlobalExceptions));
});


6、GlobalExceptions类中添加处理,当然异常需要继承IExceptionFilter。

代码如下:


GlobalExceptions 


public class GlobalExceptions : IExceptionFilter
{
    </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">readonly</span><span style="color: #000000;"> IHostingEnvironment _env;
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> GlobalExceptions(IHostingEnvironment env)
    {
        _env </span>=<span style="color: #000000;"> env;
    }
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> OnException(ExceptionContext context)
    {
        </span><span style="color: #0000ff;">var</span> json = <span style="color: #0000ff;">new</span><span style="color: #000000;"> JsonErrorResponse();
        </span><span style="color: #008000;">//</span><span style="color: #008000;">这里面是自定义的操作记录日志</span>
        <span style="color: #0000ff;">if</span> (context.Exception.GetType() == <span style="color: #0000ff;">typeof</span><span style="color: #000000;">(UserOperationException))
        {
            json.Message </span>=<span style="color: #000000;"> context.Exception.Message;
            </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (_env.IsDevelopment())
            {
                json.DevelopmentMessage </span>= context.Exception.StackTrace;<span style="color: #008000;">//</span><span style="color: #008000;">堆栈信息</span>

}

            context.Result </span>= <span style="color: #0000ff;">new</span> BadRequestObjectResult(json);<span style="color: #008000;">//</span><span style="color: #008000;">返回异常数据</span>

}

        </span><span style="color: #0000ff;">else</span><span style="color: #000000;">
        {
            json.Message </span>= <span style="color: #800000;">"</span><span style="color: #800000;">发生了未知内部错误</span><span style="color: #800000;">"</span><span style="color: #000000;">;
            </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (_env.IsDevelopment())
            {
                json.DevelopmentMessage </span>= context.Exception.StackTrace;<span style="color: #008000;">//</span><span style="color: #008000;">堆栈信息</span>

}

            context.Result </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> InternalServerErrorObjectResult(json);
        }

        </span><span style="color: #008000;">//</span><span style="color: #008000;">采用log4net 进行错误日志记录</span>

LogHelper.ErrorLog(json.Message, context.Exception);

    }
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> InternalServerErrorObjectResult : ObjectResult
{
    </span><span style="color: #0000ff;">public</span> InternalServerErrorObjectResult(<span style="color: #0000ff;">object</span> value) : <span style="color: #0000ff;">base</span><span style="color: #000000;">(value)
    {
        StatusCode </span>=<span style="color: #000000;"> StatusCodes.Status500InternalServerError;
    }
}</span></pre>


JsonErrorResponse.cs 



public class JsonErrorResponse
{
    </span><span style="color: #808080;">///</span> <span style="color: #808080;">&lt;summary&gt;</span>
    <span style="color: #808080;">///</span><span style="color: #008000;"> 生产环境的消息
    </span><span style="color: #808080;">///</span> <span style="color: #808080;">&lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Message { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }
    </span><span style="color: #808080;">///</span> <span style="color: #808080;">&lt;summary&gt;</span>
    <span style="color: #808080;">///</span><span style="color: #008000;"> 开发环境的消息
    </span><span style="color: #808080;">///</span> <span style="color: #808080;">&lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> DevelopmentMessage { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }
}</span></pre>


UserOperationException.cs



/// <summary>
<span style="color: #808080;">///</span><span style="color: #008000;"> 操作日志
</span><span style="color: #808080;">///</span> <span style="color: #808080;">&lt;/summary&gt;</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> UserOperationException : Exception
{
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> UserOperationException() { }
    </span><span style="color: #0000ff;">public</span> UserOperationException(<span style="color: #0000ff;">string</span> message) : <span style="color: #0000ff;">base</span><span style="color: #000000;">(message) { }
    </span><span style="color: #0000ff;">public</span> UserOperationException(<span style="color: #0000ff;">string</span> message, Exception innerException) : <span style="color: #0000ff;">base</span><span style="color: #000000;">(message, innerException) { }
}</span></pre>


 自此,全局异常配置完成,然后我们可以测试一下,随便写一个除以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 style="color: #800000;">"
  xmlns:xsi</span>=<span style="color: #800000;">"</span><span style="color: #800000;">http://www.w3.org/2001/XMLSchema-instance</span><span style="color: #800000;">"</span><span style="color: #000000;">
  autoReload</span>=<span style="color: #800000;">"</span><span style="color: #800000;">true</span><span style="color: #800000;">"</span>&gt;

<!-- the targets to write to -->
<targets>

&lt;!-- 输出到文件,这个文件记录所有的日志 --&gt;
&lt;target xsi:type=<span style="color: #800000;">"</span><span style="color: #800000;">File</span><span style="color: #800000;">"</span> name=<span style="color: #800000;">"</span><span style="color: #800000;">allfile</span><span style="color: #800000;">"</span> fileName=<span style="color: #800000;">"</span><span style="color: #800000;">Log\LogAll\${shortdate}.htm</span><span style="color: #800000;">"</span><span style="color: #000000;">
            layout</span>=<span style="color: #800000;">"</span><span style="color: #800000;">&amp;lt;HR COLOR=red&amp;gt;${longdate}&amp;lt;BR&amp;gt;${logger}&amp;lt;BR&amp;gt;${uppercase:${level}}&amp;lt;BR&amp;gt;${message} ${exception}&amp;lt;HR Size=1&amp;gt;</span><span style="color: #800000;">"</span> /&gt;

&lt;!-- 输出到文件,这个文件记录错误日志 --&gt;
&lt;target xsi:type=<span style="color: #800000;">"</span><span style="color: #800000;">File</span><span style="color: #800000;">"</span> name=<span style="color: #800000;">"</span><span style="color: #800000;">logError</span><span style="color: #800000;">"</span> fileName=<span style="color: #800000;">"</span><span style="color: #800000;">Log\LogError\${shortdate}.htm</span><span style="color: #800000;">"</span><span style="color: #000000;">
        layout</span>=<span style="color: #800000;">"</span><span style="color: #800000;">&amp;lt;HR COLOR=red&amp;gt;【异常时间】:${date} &amp;lt;BR&amp;gt;【异常级别】:${level:uppercase=true} &amp;lt;BR&amp;gt;${message}&amp;lt;HR Size=1&amp;gt;</span><span style="color: #800000;">"</span> /&gt;

&lt;!-- 输出到文件,这个文件记录操作日志 --&gt;
&lt;target xsi:type=<span style="color: #800000;">"</span><span style="color: #800000;">File</span><span style="color: #800000;">"</span> name=<span style="color: #800000;">"</span><span style="color: #800000;">logInfo</span><span style="color: #800000;">"</span> fileName=<span style="color: #800000;">"</span><span style="color: #800000;">Log\LogInfo\${shortdate}.htm</span><span style="color: #800000;">"</span><span style="color: #000000;">
             layout</span>=<span style="color: #800000;">"</span><span style="color: #800000;">&amp;lt;HR COLOR=red&amp;gt;【操作时间】:${date} &amp;lt;BR&amp;gt;【操作级别】:${level:uppercase=true} &amp;lt;BR&amp;gt;${message}&amp;lt;HR Size=1&amp;gt;</span><span style="color: #800000;">"</span> /&gt;

</targets>
<!-- rules to map from logger name to target -->
<rules>

&lt;!--All logs, including <span style="color: #0000ff;">from</span> Microsoft--&gt;
&lt;logger name=<span style="color: #800000;">"</span><span style="color: #800000;">*</span><span style="color: #800000;">"</span> minlevel=<span style="color: #800000;">"</span><span style="color: #800000;">Trace</span><span style="color: #800000;">"</span> writeTo=<span style="color: #800000;">"</span><span style="color: #800000;">allfile</span><span style="color: #800000;">"</span> /&gt;
&lt;logger name=<span style="color: #800000;">"</span><span style="color: #800000;">*</span><span style="color: #800000;">"</span> minlevel=<span style="color: #800000;">"</span><span style="color: #800000;">Error</span><span style="color: #800000;">"</span> writeTo=<span style="color: #800000;">"</span><span style="color: #800000;">logError</span><span style="color: #800000;">"</span> /&gt;
&lt;logger name=<span style="color: #800000;">"</span><span style="color: #800000;">*</span><span style="color: #800000;">"</span> minlevel=<span style="color: #800000;">"</span><span style="color: #800000;">Info</span><span style="color: #800000;">"</span> writeTo=<span style="color: #800000;">"</span><span style="color: #800000;">logInfo</span><span style="color: #800000;">"</span> /&gt;
&lt;logger name=<span style="color: #800000;">"</span><span style="color: #800000;">Microsoft.*</span><span style="color: #800000;">"</span> maxLevel=<span style="color: #800000;">"</span><span style="color: #800000;">Info</span><span style="color: #800000;">"</span> final=<span style="color: #800000;">"</span><span style="color: #800000;">true</span><span style="color: #800000;">"</span> /&gt;

</rules>
</nlog>



 


注:然后将此文件点击右键,选择属性,把复制输出目录修改为“始终复制”,无法不修改,则会无法加载此文件。



3、在startup.cs中的  Configure方法注入



//ILoggerFactory loggerFactory
loggerFactory.AddNLog();
NLog.LogManager.LoadConfiguration("nlog.config"
); //填入上面创建的文件的名称


 然后运行以下即可看到在bin/debug下面生成文件夹



4、创建NLogHelp.cs类


public class NLogHelp
{
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> Logger logger =<span style="color: #000000;"> LogManager.GetCurrentClassLogger();
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> ErrorLog(<span style="color: #0000ff;">string</span><span style="color: #000000;"> throwMsg, Exception ex)
    {
        </span><span style="color: #0000ff;">string</span> errorMsg = <span style="color: #0000ff;">string</span>.Format(<span style="color: #800000;">"</span><span style="color: #800000;">【异常信息】:{0} &lt;br&gt;【异常类型】:{1} &lt;br&gt;【堆栈调用】:{2}</span><span style="color: #800000;">"</span><span style="color: #000000;">,
            </span><span style="color: #0000ff;">new</span> <span style="color: #0000ff;">object</span><span style="color: #000000;">[] { throwMsg, ex.GetType().Name, ex.StackTrace });
        errorMsg </span>= errorMsg.Replace(<span style="color: #800000;">"</span><span style="color: #800000;">\r\n</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">&lt;br&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">);
        errorMsg </span>= errorMsg.Replace(<span style="color: #800000;">"</span><span style="color: #800000;">位置</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">&lt;strong style=\"color:red\"&gt;位置&lt;/strong&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">);
        logger.Error(errorMsg);
    }
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> InfoLog(<span style="color: #0000ff;">string</span><span style="color: #000000;"> operateMsg)
    {
        </span><span style="color: #0000ff;">string</span> errorMsg = <span style="color: #0000ff;">string</span>.Format(<span style="color: #800000;">"</span><span style="color: #800000;">【操作信息】:{0} &lt;br&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">,
            </span><span style="color: #0000ff;">new</span> <span style="color: #0000ff;">object</span><span style="color: #000000;">[] { operateMsg });
        errorMsg </span>= errorMsg.Replace(<span style="color: #800000;">"</span><span style="color: #800000;">\r\n</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">&lt;br&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">);
        logger.Info(errorMsg);
    }
}</span></pre>


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</span><span style="color: #800080;">2</span>.GetOrAdd(TKey key, Func2 valueFactory)
at AspectCore.Injector.ServiceResolver.b


自此,完美搞定,等后期我将会介绍采用ELK+NLog进行数据采集及展示,请大家拭目以待吧。

文章转载自阿里云 MVP郭联钰,查看原文

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
12天前
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:&lt;https://github.com/khellang/Scrutor&gt;
35 5
|
2月前
|
存储 开发框架 JSON
ASP.NET Core OData 9 正式发布
【10月更文挑战第8天】Microsoft 在 2024 年 8 月 30 日宣布推出 ASP.NET Core OData 9,此版本与 .NET 8 的 OData 库保持一致,改进了数据编码以符合 OData 规范,并放弃了对旧版 .NET Framework 的支持,仅支持 .NET 8 及更高版本。新版本引入了更快的 JSON 编写器 `System.Text.UTF8JsonWriter`,优化了内存使用和序列化速度。
|
1月前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
40 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
20天前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
24 3
|
3月前
|
开发框架 监控 前端开发
在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作
【9月更文挑战第27天】操作筛选器是ASP.NET Core MVC和Web API中的一种过滤器,可在操作方法执行前后运行代码,适用于日志记录、性能监控和验证等场景。通过实现`IActionFilter`接口的`OnActionExecuting`和`OnActionExecuted`方法,可以统一处理日志、验证及异常。创建并注册自定义筛选器类,能提升代码的可维护性和复用性。
|
3月前
|
开发框架 .NET 中间件
ASP.NET Core Web 开发浅谈
本文介绍ASP.NET Core,一个轻量级、开源的跨平台框架,专为构建高性能Web应用设计。通过简单步骤,你将学会创建首个Web应用。文章还深入探讨了路由配置、依赖注入及安全性配置等常见问题,并提供了实用示例代码以助于理解与避免错误,帮助开发者更好地掌握ASP.NET Core的核心概念。
111 3
|
2月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
50 7
|
3月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
80 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
57 0