• .NET Core开发实战(第18课:日志框架:聊聊记日志的最佳姿势)--学习笔记(上)


    18 | 日志框架:聊聊记日志的最佳姿势

    源码链接:
    https://github.com/witskeeper/geektime/tree/master/samples/LoggingSimpleDemo

    日志框架必要的包:

    1、Microsoft.Extensions.Logging

    2、Microsoft.Extensions.Logging.Console

    3、Microsoft.Extensions.Logging.Debug

    4、Microsoft.Extensions.Logging.TraceSource

    代码通过一个控制台程序,展示从读取配置到整个日志的记录器的构造和日志记录的过程

    首先从文件读取配置

    IConfigurationBuilder configBuilder = new ConfigurationBuilder();
    configBuilder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
    var config = configBuilder.Build();
    

    接着构造容器,注入对象

    IServiceCollection serviceCollection = new ServiceCollection();// 构造容器
    // 用工厂模式将配置对象注册到容器管理
    // 注入的时候使用了一个委托,意味着容器可以帮我们管理这个对象的生命周期
    serviceCollection.AddSingleton<IConfiguration>(p => config);
    // 如果将实例直接注入,容器不会帮我们管理
    //serviceCollection.AddSingleton<IConfiguration>(config);
    
    // AddLogging 往容器里面注册了几个关键对象:
    // ILoggerFactory,泛型模板 typeof (ILogger<>),Logger 的过滤配置 IConfigureOptions<LoggerFilterOptions>
    // 最后一行,configure((ILoggingBuilder) new LoggingBuilder(services)); 就是整个注入我们的委托
    serviceCollection.AddLogging(builder =>
    {
        builder.AddConfiguration(config.GetSection("Logging"));// 注册 Logging 配置的 Section
        builder.AddConsole();// 先使用一个 Console 的日志输出提供程序
    });
    

    AddLogging 源码

    public static IServiceCollection AddLogging(
          this IServiceCollection services,
          Action<ILoggingBuilder> configure)
    {
      if (services == null)
        throw new ArgumentNullException(nameof (services));
      services.AddOptions();
      services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());
      services.TryAdd(ServiceDescriptor.Singleton(typeof (ILogger<>), typeof (Logger<>)));
      services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<LoggerFilterOptions>>((IConfigureOptions<LoggerFilterOptions>) new DefaultLoggerLevelConfigureOptions(LogLevel.Information)));
      configure((ILoggingBuilder) new LoggingBuilder(services));
      return services;
    }
    

    配置文件,appsettings.json

    {
      "Logging": {
        "LogLevel": {
          "Default": "Debug",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        },
        "Console": {
          "LogLevel": {
            "Default": "Information",
            "Program": "Trace",
            "alogger": "Trace",
            "LoggingSimpleDemo.OrderService": "None"
          }
        }
      }
    }
    
    

    Logging 里面定义了 Log 的级别,Key 代表 Log 的名称,Value 代表 Logger 的级别

    Console 是指针对 Console 的输出提供程序配置的日志级别

    下面看一下日志级别的定义,按照严重程度从低到高

    namespace Microsoft.Extensions.Logging
    {
      public enum LogLevel
      {
        Trace,
        Debug,
        Information,
        Warning,
        Error,
        Critical,
        None,
      }
    }
    

    也就是说我们可以指定日志输出的最低级别

    接着 BuildServiceProvider,从容器里面获取 ILoggerFactory

    IServiceProvider service = serviceCollection.BuildServiceProvider();
    
    ILoggerFactory loggerFactory = service.GetService<ILoggerFactory>();
    

    ILoggerFactory 的定义

    namespace Microsoft.Extensions.Logging
    {
      public interface ILoggerFactory : IDisposable
      {
        // 输入的名称是 Logger 的名称,输出的结果是一个 ILogger 的对象,代表日志记录器
        ILogger CreateLogger(string categoryName);
    
        // 这个方法通常不会用到它,因为通常情况下注册容器提供程序会在 AddLogging 委托里面去注册,而不会用 AddProvider 方法
        void AddProvider(ILoggerProvider provider);
      }
    }
    

    获取到 ILoggerFactory 之后就可以创建日志记录器

    ILogger alogger = loggerFactory.CreateLogger("alogger");
    
    alogger.LogDebug(2001, "aiya");
    alogger.LogInformation("hello");
    
    var ex = new Exception("出错了");
    alogger.LogError(ex, "出错了");
    

    因为配置文件中 alogger 的级别是 Trace

    "alogger": "Trace",
    

    所以这三行都会被打印出来

    启动程序,输出如下:

    dbug: alogger[2001]
          aiya
    info: alogger[0]
          hello
    fail: alogger[0]
          出错了
    System.Exception: 出错了
    

    方括号的内容是 EventID,也就是针对每一个记录的位置事件,可以为它分配一个事件 ID,代码中在 LogDebug 的时候定义了一个事件 ID 是2001

    假如说把 alogger 的日志级别调整成 Information

    "alogger": "Information",
    

    那么 Debug 级别的信息没有输出的

    info: alogger[0]
          hello
    fail: alogger[0]
          出错了
    System.Exception: 出错了
    

    知识共享许可协议

    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

    欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

    如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。

  • 相关阅读:
    平方十位数
    随意组合
    显示二叉树
    四阶幻方
    方格填数
    数字排列
    青蛙跳N阶(变态跳)
    Mysql可重复读、避免幻读原理
    动态规划典型例题--连续子数组的最大和
    行列有序的二维数组查找
  • 原文地址:https://www.cnblogs.com/MingsonZheng/p/12424084.html
Copyright © 2020-2023  润新知