.NET 日志系统2

上一篇文章是将日志打印到控制台,这篇文章将日志写入到文本文件中。

文本日志一般按照日期区分

  1. 如何避免文本日志把磁盘撑爆?

    限制日志总个数或者总大小

  2. 如何避免一个日志文件太大?

    限制单个文件大小

使用NLOG

  1. NuGet安装:NLog.Extensions.Logging
  2. 在项目根目录下创建nlog.config
  3. 增加logBuilder.AddNLog()

nlog.config

nlog.config直接去GitHub复制官方的就行了,根据自己的项目版本去选择

https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-6

需要注意的是文件位置需要更改,可以放D盘或者项目根目录如"internal-nlog-AspNetCore.txt"

Snipaste_2023-08-28_16-15-51

  • type="File" 指明为文件
  • fileName 生成的文件名
  • layout 指文件的输出格式

AddNLog

与上一篇文章用的同一个列子,添加logBuilder.AddNLog();

services.AddLogging(logBuilder =>
{
    logBuilder.AddConsole(); //如果使用NLog建议只保留logBuilder.AddNLog();
    logBuilder.AddNLog();
    logBuilder.SetMinimumLevel(LogLevel.Trace);
});

效果展示

Snipaste_2023-08-28_16-19-43

Snipaste_2023-08-28_16-19-56

深入NLOG

日志过滤

按照不同级别输出,通过不同的命名空间实现不同的日志文件的输出。

首先新增一个Test2类,并将命名空间设置为SystemServices

namespace SystemServices;
public class Test2
{
    private readonly ILogger<Test2> _logger;

    public Test2(ILogger<Test2> logger)
    {
        _logger = logger;
    }
    ......
}

同样需要使用这个类的方法,我们循环1万次

services.AddScoped<Test2>();

var test2 = sp.GetRequiredService<Test2>();
for (int i = 0; i < 10000; i++)
{
    test1.Test();
    test2.Test();
}

修改config配置文件

<?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">=
    <targets>
        <target name="defaultFile" xsi:type="File" fileName="logs/log-${shortdate}.log"
     layout="${date}|${level:uppercase=true}|${looger}|${message}|${exception:format=ToString}"/>
        <target name="sysServicesFile" xsi:type="File" archiveAboveSize="1000000" maxArchiveFiles="3"
                fileName="logs/sysServices-${shortdate}.log"
                layout="${date}|${level:uppercase=true}|${looger}|${message}|${exception:format=ToString}"/>
        <target name="targetConsole" xsi:type="ColoredConsole"
                layout="${date}|${level:uppercase=true}|${looger}|${message}|${exception:format=ToString}"/>
    </targets>
    <rules>
        <logger name="*" minlevel="Warn" maxlevel="Fatal" writeTo="targetConsole" />
        <logger name="SystemServices.*" minlevel="Trace" writeTo="sysServicesFile" final="true"/>
        <logger name="*" minlevel="Trace" writeTo="defaultFile" />
    </rules>
</nlog>

通过设置rules的name通过不同的命名空间去输出不同的日志文件

<logger name="SystemServices.*" minlevel="Trace" writeTo="sysServicesFile" final="true"/>

匹配它的输出到sysServicesFile中,不匹配的则往下走匹配到defaultFile中。

生成了如下几个日志文件

Snipaste_2023-08-28_16-57-02

Snipaste_2023-08-28_16-58-57

参数解释

  1. archiveAboveSize为单个日志文件超过多少直接就把日志存档,单位为字节。
  2. maxArchiveFiles,指定文件存档的数量,如果不设定这个参数,则文件数量会一直增加。
  3. maxArchiveDays参数设定保存若干天的日志存档。

rules

  1. rules节点下可以添加多个logger,每个logger都有名字(name属性),name是通配符格式的。
  2. logger节点的minlevel属性和Maxlevel属性,表示这个logger接受日志的最低级别和最高级别。
  3. 日志输出时,会从上往下匹配rules节点下所有的logger,若发现当前日志的分类和level符合这个logger的name通配符,就会把日志输出给这个logger。如果匹配多个logger,就把这条日志输出给多个logger,但是如果一个logger设置了final="true",那么如果匹配到这个logger,就不会继续向下匹配其他logger了。

NLog其他

  1. NLog部分功能和.NET的Loggin重复,比如分类、分级、各种Provider。
  2. 为了避免冲突,如果用NLog,建议不要再配置.NET的分级等(具体用法见微软文档)

参考资料

每日一道面试题

C#中的委托是什么?事件是不是一种委托?

答 : 委托可以把一个方法作为参数代入另一个方法,委托可以理解为指向一个函数的引用。事件是一种特殊的委托。