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 配置的 Sectionbuilder.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: 出错了

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

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

    18 | 日志框架:聊聊记日志的最佳姿势 除了使用 CreateLogger 指定 logger 的名称,实际上还可以借助容器来构造 logger,通常情况下我们会定义自己的类 namespace L ...

  2. .NET Core开发实战(第5课:依赖注入:良好架构的起点)--学习笔记(上)

    05 | 依赖注入:良好架构的起点 为什么要使用依赖注入框架 借助依赖注入框架,我们可以轻松管理类之间的依赖,帮助我们在构建应用时遵循设计原则,确保代码的可维护性和可扩展性 ASP.NET Core ...

  3. .NET Core开发实战(定义API的最佳实践)Source Generators版

    前言 极客时间上的<.NET Core开发实战>是一门非常好的课程,作者肖伟宇在第31课(https://time.geekbang.org/course/detail/100044601 ...

  4. 小米手环iOS开发实战(一):iOS蓝牙框架CoreBluetooth

    小米手环iOS开发实战(一):iOS蓝牙框架CoreBluetooth 本项目为对小米手环进行二次开发,利用了小米手环蓝牙连接并不安全的特性,连接后可以获取手环数据,并可修改数据. 本实例使用Swif ...

  5. gram矩阵的性质_第十七课:正交矩阵和GramSchmidt正交化——MIT线性代数课程学习笔记...

    公众号关注  "DL_NLP" 设为 "星标",重磅干货,第一时间送达! ◎ 原创 | 深度学习算法与自然语言处理 ◎ 作者 | 丁坤博 一. 知识概要 这一节 ...

  6. .NET Core开发实战(第19课:日志作用域:解决不同请求之间的日志干扰)--学习笔记...

    19 | 日志作用域:解决不同请求之间的日志干扰 开始之前先看一下上一节的代码 // 配置的框架 var configBuilder = new ConfigurationBuilder(); con ...

  7. .NET Core开发实战(第15课:选项框架:服务组件集成配置的最佳实践)--学习笔记...

    15 | 选项框架:服务组件集成配置的最佳实践 这一节讲解如何使用选项框架来处理服务和配置的关系 选项框架的特性: 1.支持单例模式读取配置 2.支持快照 3.支持配置变更通知 4.支持运行时动态修改 ...

  8. 《物联网开发实战》18 场景联动:智能电灯如何感知光线?(上)(学习笔记)

    仅作为本人学习<物联网开发实战>的学习笔记,原课程链接:极客时间<物联网开发实战>--郭朝斌 文章目录 第一步:通信技术 第二步:选择开发板 第三步:准备 MicroPytho ...

  9. ASP.NET Core分布式项目实战(业务介绍,架构设计,oAuth2,IdentityServer4)--学习笔记...

    任务4:第一章计划与目录 敏捷产品开发流程 原型预览与业务介绍 整体架构设计 API 接口设计 / swagger Identity Server 4 搭建登录 账号 API 实现 配置中心 任务5: ...

最新文章

  1. 解决SecureCRT 链接服务器 中文显示出现乱码【有图有真相】
  2. 信通院2018人工智能发展白皮书技术篇重磅发布
  3. linux查看cpu监控日志,Linux:日志,cpu,memory,mount,load等系统信息查看
  4. 调用ffmpeg库编译时出现common.h:175:47: error: 'UINT64_C' was not declared in this scope
  5. 面试问烂的 Spring MVC 过程
  6. ACL 2019 | 巧用文本语境信息:基于上下文感知的向量优化
  7. c语言程序设计的一般错误的是,《C语言程序设计》第十章 程序常见错误分析.pdf...
  8. redis学习笔记——应用场景
  9. 大话软件开发与开车的共同点
  10. AOS编排语言系列教程(二):初识AOS编排语言,创建你的第一个AOS模板
  11. linux执行使分区生效的命令,Linux硬盘分区生效命令partprobe
  12. Perl5中19个最重要的文件系统工具
  13. Microsoft Visio绘图
  14. HTML前端特效集合
  15. java资费管理模块_JAVA小区物业收费管理系统设计与实现.doc
  16. 微信小程序阻止事件冒泡【看这里】
  17. 为了研究而玩:游戏分析的方法
  18. flash 在firebox/IE中 提示安装 浏览器是否有flash插件
  19. AutoCAD关于选择的一些技巧(如何高效地框选)
  20. 渲染管线中的坐标空间和相关变换

热门文章

  1. Leetcode: Single Number
  2. 40个最好的Tumblr主题
  3. CSS边界属性的负值
  4. 用SharpZipLib来压缩和解压文件 --zt
  5. mysql table alter_MySQL-ALTER TABLE命令学习[20180503]
  6. 如何使自己的不和谐机器人
  7. Buildroot stress-ng Linux系统压力测试
  8. Mybatis-Generator(MBG)教程与Idea的MBG插件
  9. poj-1980 Unit Fraction Partition **
  10. WPF 基础控件之 GroupBox样式