跟着杨中科学习(二)日志

日志系统

日志级别

Trace<Debug<Information<Warning<Error<Critical

输出到控制台

Nuget

Microsoft.Extensions.Logging
Microsoft.Extensions.Logging.Console

DI注入

services.AddLogging(logBuilder=>{
	logBuilder.AddConsole();//可多个Procider
    logBuilder.SetMinimumLevel(LogLevel.Trace);//设置级别打印等级
})
services.AddScoped<Test>();
using(var sp=services.BuildServiceProvider())
{
    var test=sp.GetRequiredService<Test>();
    test.TestDemo();
}

使用

class Test
{
    private readonly ILogger<Test> logger;
    public Test(ILogger<Test> logger)
    {
        this logger=logger;
    }
    public void TestDemo()
    {
        logger.LogDebug("开始执行数据库");
        logger.LogWarning("查找数据失败,开始重试");
    }
}

其他日志提供者

Event Log

Windows Only。只在windows下运行

在Windows下部署的
程序、网站运行出错、不正常,先去EventLog看看。

在EventViewer中找

NuGet安装:

Microsoft.Extensions.Logging.EventLog
然后在DI
logBuilder.AddEventLog();

Nlog

文本日志

NLog.Extensions.Logging

约定大于配置

项目根目录建nlog.config,需要注意文件名的大小写(考虑linux)。

.net6.0下的nlog.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"
      autoReload="true"
      internalLogLevel="Info"
      internalLogFile="c:\temp\internal-nlog-AspNetCore.txt">

  <!-- enable asp.net core layout renderers -->
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>

  <!-- the targets to write to -->
  <targets>
    <!-- File Target for all log messages with basic details -->
    <target xsi:type="File" name="allfile" fileName="c:\temp\nlog-AspNetCore-all-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}" />

    <!-- File Target for own log messages with extra web details using some ASP.NET core renderers -->
    <target xsi:type="File" name="ownFile-web" fileName="c:\temp\nlog-AspNetCore-own-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />

    <!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection -->
    <target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <!--All logs, including from Microsoft-->
    <logger name="*" minlevel="Trace" writeTo="allfile" />

    <!--Output hosting lifetime messages to console target for faster startup detection -->
    <logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole, ownFile-web" final="true" />

    <!--Skip non-critical Microsoft logs and so log only own logs (BlackHole) -->
    <logger name="Microsoft.*" maxlevel="Info" final="true" />
    <logger name="System.Net.Http.*" maxlevel="Info" final="true" />
    
    <logger name="*" minlevel="Trace" writeTo="ownFile-web" />
  </rules>
</nlog>
services.AddLogging(logBuilder=>{
	logBuilder.AddConsole();//可多个Procider
    logBuilder.SetMinimumLevel(LogLevel.Trace);//设置级别打印等级
    logBuilder.AddNlog();
})
services.AddScoped<Test>();
using(var sp=services.BuildServiceProvider())
{
    var test=sp.GetRequiredService<Test>();
    test.TestDemo();
}

日志的分类和过滤

创建一个新的类,但是namespace的名字要改成SystemServices

namespace SystemServices
{
    class Test
	{
        private readonly ILogger<Test> logger;
        public Test(ILogger<Test> logger)
        {
            this logger=logger;
        }
        public void TestDemo()
        {
            logger.LogDebug("开始执行FTP");
            logger.LogWarning("查找数据失败,开始重试");
        }
	}
}
services.AddLogging(logBuilder=>{
	logBuilder.AddConsole();//可多个Procider
    logBuilder.SetMinimumLevel(LogLevel.Trace);//设置级别打印等级
})
services.AddScoped<Test>();
using(var sp=services.BuildServiceProvider())
{
    var test=sp.GetRequiredService<Test>();
    test.TestDemo();
}

修改nlog.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" autoReload="true"
<targets>
<target xsi:type="File" name="defaultFile" fileName="logs/log-${shortdate}. 1og"
layout="${date} |${1eve1:uppercase=true} |$ {1ogger} |$ {message} |$ {exception:format=ToString}" />
<target xsi:type="File name="sysServicesFile" archiveAboveSize="10000
fileName="logs/sysServices-${shortdate}. log
layout="${date} |${1eve1:uppercase=true} |${1ogger} | $ {message} |
$ {exception:format=ToString}" />
<target xsi:type="ColoredConsole" name="targetConsole
layout="${date} | $ {1eve1:uppercase=true} |${1ogger} |$ {message} |
$ {exception:format=ToString}" />

maxArchiveFiles="3"

</targets>
<rules>
<logger name="*" minleve1="Warn" maxleve1="Fatal" writeTo="targetConsole" />
<logger name="SystemServices. *" minleve1="Trace" writeTo="sysServicesFile" final="true" />
<logger name="*"minleve1="Trace" writeTo="defaultFile" />
</rules>
</nlog>
archiveAboveSize为“单个日志文件超过多少字节就把日志存档”,

单位为字节,这样可以避免单个文件太大.

如果不设定maxArchiveFiles参数,则文件日志存档文件的数量会一直增加,

而如果设定maxArchiveFiles参数后,则最多保存maxArchiveFiles指定数量个数的存档文件,旧的会被删掉

当然也可以不设置maxArchiveFiles参数,而设置maxArchiveDays参数,这样可以设定保存若干天的日志存档。


关于nlog.config中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了,推荐按使用Serilog

NuGet安装:Serilog.AspNetCore

配置

Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.Enrich.FromLogContext()
.WriteTo.Console(new JsonFormatter())
.CreateLogger();
builder.AddSerilog();
  private static void Main(string[] args)
    {
        ServiceCollection services = new ServiceCollection();
      	 services.AddLogging(logBuilder=>{
               		Log.Logger = new LoggerConfiguration()
                	.MinimumLevel.Debug()
               		.Enrich.FromLogContext()
                	.WriteTo.Console(new JsonFormatter())
                	.CreateLogger();
               	 	 builder.AddSerilog();
              });
       
        using (var sp = services.BuildServiceProvider())
        {
             
        };
        Console.ReadKey();
	}

使用占位符

class User{

    public string Name { get; set; }
    public string Email { get; set; }
}


User user = new User { Name="admin", Email="fadfads@qq.com"};
logger.LogDebug(“注册一个用户{@person}",user);

输出信息会输出user的信息

写入集中化的日志服务,这也是使用Serilog的目的之一

posted @   想要来杯咖啡吗  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示