提纲:
- 日志系统依赖注入流程
主要依靠 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的日志,而不会输出所有的日志