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日志并进行多维度分析。
目录
相关文章
|
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`,优化了内存使用和序列化速度。
|
18天前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
29 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
10天前
|
运维 监控 Cloud Native
一行代码都不改,Golang 应用链路指标日志全知道!
本文将通过阿里云开源的 Golang Agent,帮助用户实现“一行代码都不改”就能获取到应用产生的各种观测数据,同时提升运维团队和研发团队的幸福感。
|
8天前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
17 3
|
11天前
|
存储 Prometheus 监控
Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行
本文深入探讨了在Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行。
23 5
|
28天前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
|
1月前
|
存储 SQL 监控
|
1月前
|
自然语言处理 监控 数据可视化
|
1月前
|
JSON 算法 安全
JWT Bearer 认证在 .NET Core 中的应用
【10月更文挑战第30天】JWT(JSON Web Token)是一种开放标准,用于在各方之间安全传输信息。它由头部、载荷和签名三部分组成,用于在用户和服务器之间传递声明。JWT Bearer 认证是一种基于令牌的认证方式,客户端在请求头中包含 JWT 令牌,服务器验证令牌的有效性后授权用户访问资源。在 .NET Core 中,通过安装 `Microsoft.AspNetCore.Authentication.JwtBearer` 包并配置认证服务,可以实现 JWT Bearer 认证。具体步骤包括安装 NuGet 包、配置认证服务、启用认证中间件、生成 JWT 令牌以及在控制器中使用认证信息
|
2月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架