.Net日志系统Logging-五

日志概念

        日志级别

      NET (Microsoft.Extensions.Logging) 中定义的 6 个标准日志级别,按严重性从低到高排列:

日志级别数值描述典型使用场景
Trace0最详细的信息,包含敏感数据(如请求体、密码哈希等)。仅在开发或深度故障排除时启用。记录方法入口/出口、详细变量值、低级别通信细节。
Debug1开发调试信息。比 Trace 略少细节,但仍包含对开发者有用的内部信息。记录关键变量状态、流程步骤、非性能关键操作的耗时、配置加载值。
Information2应用程序流信息。描述应用程序正常、预期内的操作。服务启动/停止、重要操作完成(如“用户登录成功”、“订单创建”)、主要里程碑事件。
Warning3异常或意外事件,但应用程序仍能继续运行。表明可能需要调查的潜在问题。重试操作、降级功能使用、预期内的外部服务错误、接近资源限制(如磁盘空间不足)。
Error4无法处理的错误。表示当前操作或请求失败,但应用程序整体仍可运行。捕获的异常、数据库连接失败、关键操作失败(如支付处理失败)、外部API调用关键错误。
Critical5最严重的故障,可能导致应用程序崩溃或不可恢复的损坏。需要立即处理。系统崩溃、数据丢失、磁盘空间耗尽、启动失败、灾难性未处理异常。

        日志提供者:需要把日志输出那个地方文件,数据库,控制台等。

        

输出日志到控制台

1.安装Nuget日志所需要的包:

        Microsoft.Extensions.Logging.Console

2.DI注入:

//创建DI容器对象
ServiceCollection services = new ServiceCollection();

       
 services.AddLogging(logBuilder => {
     //容器注入控制台输出
     logBuilder.AddConsole();

详细步骤:

1.创建一个类,使用构造方法注入ILogger<一般填写当前类名> 

 class TestLog
{
    //定义一个ILogger类型私有变量,泛型中类型填写本类
    private readonly ILogger<TestLog> logger;


    //使用构造方法进行注入
    public TestLog(ILogger<TestLog> logger) { 

        this.logger = logger;

    }

    public void Log()
    {
        logger.LogDebug("调试记录信息");
        logger.LogWarning("警告记录信息");
        logger.LogError("错误记录信息");
    }

}

2.在主程序中创建DI容器,注册服务、添加控制器输出

 public class Program
 {
     static void Main(string[] args)
     {
        //创建DI容器对象
        ServiceCollection services = new ServiceCollection();

    
         services.AddLogging(logBuilder => {
             //-----------------------------------
          
             //容器注入控制台输出
             logBuilder.AddConsole();

           //--------------------------------------

             //设置输出级别为最低
             logBuilder.SetMinimumLevel(LogLevel.Trace);  
         });

         //容器注册服务对象
         services.AddScoped<TestLog>();

         //构建一个服务提供者(Service Provider)对象
         //创建一个 `ServiceProvider` 实例。
         //-这个 `ServiceProvider` 对象就是依赖注入容器,它负责管理服务的生命周期和解析服务
         using (var sp = services.BuildServiceProvider())
         {
             //获取服务对象
          TestLog tlog =   sp.GetRequiredService<TestLog>();
             tlog.Log();
             Console.ReadKey();
         }
     }
 }

3.输出结果

输出日志到Windows的事件查看器中

1.创建一个类,使用构造方法注入ILogger<一般填写当前类名> 

 class TestLog
{
    //定义一个ILogger类型私有变量,泛型中类型填写本类
    private readonly ILogger<TestLog> logger;


    //使用构造方法进行注入
    public TestLog(ILogger<TestLog> logger) { 

        this.logger = logger;

    }

    public void Log()
    {
        logger.LogDebug("调试记录信息");
        logger.LogWarning("警告记录信息");
        logger.LogError("错误记录信息");
    }

}

2.在主程序中创建DI容器,注册服务、添加事件查看器输出

 public class Program
 {
     static void Main(string[] args)
     {
        //创建DI容器对象
        ServiceCollection services = new ServiceCollection();

    
         services.AddLogging(logBuilder => {
          //---------------------------------------

             //注入windows事件查看器中输出
             logBuilder.AddEventLog();
          //---------------------------------------

             //设置输出级别为最低
             logBuilder.SetMinimumLevel(LogLevel.Trace);  
         });

         //容器注册服务对象
         services.AddScoped<TestLog>();

         //构建一个服务提供者(Service Provider)对象
         //创建一个 `ServiceProvider` 实例。
         //-这个 `ServiceProvider` 对象就是依赖注入容器,它负责管理服务的生命周期和解析服务
         using (var sp = services.BuildServiceProvider())
         {
             //获取服务对象
          TestLog tlog =   sp.GetRequiredService<TestLog>();
             tlog.Log();
             Console.ReadKey();
         }
     }
 }

3.输出结果

NLog文本日志输出

1.安装Nuget包:NLog.Extensions.Logging

控制台输入:Install-Package  NLog.Extensions.Logging

2..创建配置文件
添加 nlog.config 配置文件(右键项目 → 新建项 → NLog 配置文件),nlog.config 位于项目根目录

内容示例如下:

<?xml version="1.0" encoding="utf-8"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      autoReload="true"
      internalLogLevel="info"
      internalLogFile="interal_NLog.log"
      throwExceptions="false" 
      encoding="utf-8">
  <targets>
    <!-- 控制台输出 ,layout输出布局格式-->
    <target name="console" xsi:type="Console" layout="${longdate}|${level}|${message}" />
    <!-- 文件输出(按日期分目录) -->
    <target name="file" xsi:type="File" 
            fileName="Logs/${date:format=yyyy}/${date:format=MM}/${shortdate}.log"
            layout="${longdate}|${level}|${logger}|${message} ${exception}" />
  </targets>
  <rules>
    <!--输出日志的匹配规则 ,以name名称进行匹配,输入日志的等级,输出到哪里-->
     <logger name="*" minlevel="Info" writeTo="console,file" />
     <logger name="*" minlevel="Debug" writeTo="file" />
  </rules>
</nlog>

关键设置:将文件属性设为 复制到输出目录:【始终复制

3.创建一个类,使用构造方法注入ILogger<一般填写当前类名> 

 class TestLog
{
    //定义一个ILogger类型私有变量,泛型中类型填写本类
    private readonly ILogger<TestLog> logger;


    //使用构造方法进行注入
    public TestLog(ILogger<TestLog> logger) { 

        this.logger = logger;

    }

    public void Log()
    {
        logger.LogDebug("调试记录信息");
        logger.LogWarning("警告记录信息");
        logger.LogError("错误记录信息");
    }

}

4.在主程序中创建DI容器,注册服务、添加Nlog文本输出

 public class Program
 {
     static void Main(string[] args)
     {
        //创建DI容器对象
        ServiceCollection services = new ServiceCollection();

    
         services.AddLogging(logBuilder => {

    //========================NLog日志========================
             //注入NLog日志
             logBuilder.AddNLog();
    //========================================================


             //设置输出级别为最低
             logBuilder.SetMinimumLevel(LogLevel.Trace);  
         });

         //容器注册服务对象
         services.AddScoped<TestLog>();

         //构建一个服务提供者(Service Provider)对象
         //创建一个 `ServiceProvider` 实例。
         //-这个 `ServiceProvider` 对象就是依赖注入容器,它负责管理服务的生命周期和解析服务
         using (var sp = services.BuildServiceProvider())
         {
             //获取服务对象
          TestLog tlog =   sp.GetRequiredService<TestLog>();
             tlog.Log();
             Console.ReadKey();
         }
     }
 }

配置高级设置

  1. 异步日志提升性能

    <!-- AsyncWrapper 时会自动启用批量写入-->
    <target name="asyncFile" xsi:type="AsyncWrapper">
      <target xsi:type="File" fileName="logs/async.log" KeepFileOpen=false async="true"/>
    </target>
    • 避免阻塞主线程,适合高并发场景。

  2. 全局诊断上下文(GDC)

    • 设置全局变量(如应用版本):

      NLog.GlobalDiagnosticsContext.Set("AppVersion", "2.0.0");
    • 配置中引用:

      ${gdc:item=AppVersion}

  3. 日志轮转与压缩

    <target xsi:type="File" 
            fileName="logs/app.log"
            maxArchiveFiles="30"          <!-- 保留30个文件 -->
            archiveAboveSize="10485760"   <!-- 单个文件 >10MB 时分割 -->
            enableArchiveFileCompression="true" /> <!--启用文档压缩 -->


⚡ 五、性能优化建议

  • 缓冲写入:减少 I/O 操作

    <target xsi:type="BufferingWrapper" bufferSize="1000">
      <target xsi:type="File" fileName="logs/buffered.log" />
    </target>
  • 按环境调整日志级别

    • 开发环境:Debug

    • 生产环境:Warn 或 Error

  • 条件日志记录:避免不必要的计算

    if (logger.IsEnabled(LogLevel.Debug)) 
    {
        var data = ExpensiveOperation();
        logger.Debug(data);
    }

    目标标签配置选项:

  • File target · NLog/NLog 数据库https://github.com/NLog/NLog/wiki/Database-target

  • File target · NLog/NLog Wiki · GitHubhttps://github.com/NLog/NLog/wiki/File-target

  • NLog 和 SQL Server 示例配置

    <target name="database" xsi:type="Database">
      <connectionString>server=localhost;Database=*****;user id=****;password=*****</connectionString>
    
      <!--
        数据库中创建日志表
      Script for creating the dbo.Log table.
          
      SET ANSI_NULLS ON
      SET QUOTED_IDENTIFIER ON
      CREATE TABLE [dbo].[Log] (
    	  [Id] [int] IDENTITY(1,1) NOT NULL,
    	  [MachineName] [nvarchar](50) NOT NULL,
    	  [Logged] [datetime] NOT NULL,
    	  [Level] [nvarchar](50) NOT NULL,
    	  [Message] [nvarchar](max) NOT NULL,
    	  [Logger] [nvarchar](250) NULL,
    	  [Exception] [nvarchar](max) NULL,
        CONSTRAINT [PK_dbo.Log] PRIMARY KEY CLUSTERED ([Id] ASC)
          WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
      ) ON [PRIMARY]
      -->
          
      <commandText>
        insert into dbo.Log (
          MachineName, Logged, Level, Message,
          Logger, Exception
        ) values (
          @MachineName, @Logged, @Level, @Message,
          @Logger, @Exception
        );
      </commandText>
    
      <parameter name="@MachineName" layout="${machinename}" />
      <parameter name="@Logged" layout="${date}" />
      <parameter name="@Level" layout="${level}" />
      <parameter name="@Message" layout="${message}" />
      <parameter name="@Logger" layout="${logger}" />
      <parameter name="@Exception" layout="${exception:tostring}" />
    </target>

    Serilog结构化日志输出

  • 官方文档:NuGet 库 |Serilog.AspNetCore 9.0.0https://www.nuget.org/packages/Serilog.AspNetCore/9.0.0
  • 安装Nuget包:
    • Serilog.AspNetCore

日志设置:

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
    .Enrich.FromLogContext()
    .WriteTo.Console()
    // Add this line:
    .WriteTo.File(
        //连接路径 存放位置:C:\Users\xxxxxx\LogFiles\Application\diagnostics.txt
       System.IO.Path.Combine(Environment.GetEnvironmentVariable("HOME"), "LogFiles", "Application", "diagnostics.txt"),
       rollingInterval: RollingInterval.Day,
       fileSizeLimitBytes: 10 * 1024 * 1024,
       retainedFileCountLimit: 2,
       rollOnFileSizeLimit: true,
       shared: true,
       flushToDiskInterval: TimeSpan.FromSeconds(1))
    .CreateLogger();

 //添加serilog日志对象
 services.AddSerilog();

完整代码:

1.安装serilog包:

       

 Install-Package  Serilog.AspNetCore

2.创建一个类,使用构造方法注入ILogger<一般填写当前类名> 

 class TestLog
{
    //定义一个ILogger类型私有变量,泛型中类型填写本类
    private readonly ILogger<TestLog> logger;


    //使用构造方法进行注入
    public TestLog(ILogger<TestLog> logger) { 

        this.logger = logger;

    }

    public void Log()
    {
        logger.LogDebug("调试记录信息");
        logger.LogWarning("警告记录信息");
        logger.LogError("错误记录信息");
    }

}

3.在主程序中创建DI容器,注册服务、添加serilog文本输出

public class Program
{
    static void Main(string[] args)
    {
       //创建DI容器对象
       ServiceCollection services = new ServiceCollection();

   
        services.AddLogging(logBuilder => {
   
            //存放日志路径
            string path = System.IO.Path.Combine(Environment.GetEnvironmentVariable("HOME"), "LogFiles", "Application", "diagnostics.txt");

            //serilog日志的设置
            Log.Logger = new LoggerConfiguration()
                            .MinimumLevel.Debug()
                            .Enrich.FromLogContext()
                             .WriteTo.Console(new JsonFormatter())
                             .WriteTo.File(path,
                               rollingInterval: RollingInterval.Day,
                               fileSizeLimitBytes: 10 * 1024 * 1024,
                               retainedFileCountLimit: 2,
                               rollOnFileSizeLimit: true,
                               shared: true,
                               flushToDiskInterval: TimeSpan.FromSeconds(1))
                             .CreateLogger();

            //添加serilog日志对象
            logBuilder.AddSerilog();

            //设置输出级别为最低
            logBuilder.SetMinimumLevel(LogLevel.Trace);  
        });


        //容器注册服务对象
        services.AddScoped<TestLog>();

        //构建一个服务提供者(Service Provider)对象
        //创建一个 `ServiceProvider` 实例。
        //-这个 `ServiceProvider` 对象就是依赖注入容器,它负责管理服务的生命周期和解析服务
        using (var sp = services.BuildServiceProvider())
        {
            //获取服务对象
         TestLog tlog =   sp.GetRequiredService<TestLog>();
            tlog.Log();
            Console.ReadKey();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值