提纲:
- 日志系统依赖注入流程
主要依靠 LoggerFactory 的一个静态方法- 日志过滤
public static ILoggerFactory Create(Action<ILoggingBuilder> configure);
- ILoggerFactory.Create 会创建一个 ILoggerFactory的实例 (假设为 a )
- a 中会创建一个 ILoggerBuilder实例 ( 假设为 b )
- 将 b 传入到 LoggerFactory.Create 的 Action 参数中
- ConsoleLoggerExtensions 的扩展方法 AddConsole , 会创建一个
Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider的实例 ( 假设为 c) ,- 将 c 添加到 b的 Services 属性中 中;
- a 遍历 b 的 Services , 把所有 ILogProvider接口的实例通过 ILoggerFactory.AddProvider(Microsoft.Extensions.Logging.ILoggerProvider) 添加到 a 中
ILoggingBuilder 接口
注意, Services 属性和 日志系统无关, ILogFactory 需要遍历此 Services 属性,并将 ILogProvier 接口的实例添加到 ILogFactory 的实例中;
using Microsoft.Extensions.DependencyInjection;namespace Microsoft.Extensions.Logging{// 摘要:public interface ILoggingBuilder{// Gets the Microsoft.Extensions.DependencyInjection.IServiceCollection where Logging// services are configured.IServiceCollection Services { get; }}}
IServiceCollection 是一个很复杂的接口,暂时不介绍先;
简单来说,我们就认为当如下代码时,会走一遍上述流程
public static readonly ILoggerFactory MyLoggerFactory= LoggerFactory.Create(builder => { builder.AddConsole();});
于是我们来验证一下,随便找一个日志文件记录包..
Karambolo.Extensions.Logging.File.
然后根据 https://github.com/adams85/filelogger 构建代码
builder = builder.AddConsole();var fileoption = new FileLoggerOptions{BasePath = ".",FileAccessMode = LogFileAccessMode.KeepOpenAndAutoFlush,FileEncoding = System.Text.Encoding.UTF8,DateFormat = "yyyyMMdd",CounterFormat = "000",MaxFileSize = 10485760,// TextBuilderType = "MyApp.CustomLogEntryTextBuilder, MyApp",IncludeScopes = true,MaxQueueSize = 100,Files = new LogFileOptions[]{new LogFileOptions { Path = @"default-<counter>.log", },new LogFileOptions { Path = @"<date:yyyy>/<date:MM>/other-<counter>.log",MinLevel = new System.Collections.Generic.Dictionary<string, LogLevel>{{"Default", LogLevel.Trace}},CounterFormat ="00"}}};var option = Microsoft.Extensions.Options.Options.Create(fileoption);var logfileProvider = new FileLoggerProvider(option);builder.AddProvider(logfileProvider);
在 build 中添加另外一个 ILoggerProvider, 看看能否记录到日志, 果然能.
给 ILoggerBuilder 添加过滤.
注意, 只会使用最后一个添加的 Filter 来对日志进行过滤
这个过滤对于所有的 ILoggerBuilder下的所有的 ILogger 的实例都会产生过滤条件;
只需要记住一点,一个 ILoggerBuilder的实例,只会使用最后一个添加的 Filter 来对日志进行过滤,
并将过滤后的日志发给所有的日志进行处理.
而类似这样的流程, AddFilter(xFilter).AddConsole().AddFilter(yFilter).AddProvider(yProvider).AddFilter(zFilter).AddProvider(zProvider)
无法实现目标,因为 zFilter 将覆盖 xFilter \ yFilter 的过滤设置..
类似如下代码,
builder.AddFilter((category, level) =>category == DbLoggerCategory.Database.Command.Name&& level >= LogLevel.Trace).AddConsole();builder.AddFilter((category, level) =>category == DbLoggerCategory.Database.Command.Name&& level == LogLevel.Information).AddProvider(logfileProvider);
Console中只会输出 Infomation的日志,而不会输出所有的日志
