提纲:

  1. 日志系统依赖注入流程
    主要依靠 LoggerFactory 的一个静态方法
  2. 日志过滤

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 的实例中;

  1. using Microsoft.Extensions.DependencyInjection;
  2. namespace Microsoft.Extensions.Logging
  3. {
  4. // 摘要:
  5. public interface ILoggingBuilder
  6. {
  7. // Gets the Microsoft.Extensions.DependencyInjection.IServiceCollection where Logging
  8. // services are configured.
  9. IServiceCollection Services { get; }
  10. }
  11. }

IServiceCollection 是一个很复杂的接口,暂时不介绍先;
简单来说,我们就认为当如下代码时,会走一遍上述流程

  1. public static readonly ILoggerFactory MyLoggerFactory
  2. = LoggerFactory.Create(builder => { builder.AddConsole();
  3. });

于是我们来验证一下,随便找一个日志文件记录包..
Karambolo.Extensions.Logging.File.
然后根据 https://github.com/adams85/filelogger 构建代码

  1. builder = builder.AddConsole();
  2. var fileoption = new FileLoggerOptions
  3. {
  4. BasePath = ".",
  5. FileAccessMode = LogFileAccessMode.KeepOpenAndAutoFlush,
  6. FileEncoding = System.Text.Encoding.UTF8,
  7. DateFormat = "yyyyMMdd",
  8. CounterFormat = "000",
  9. MaxFileSize = 10485760,
  10. // TextBuilderType = "MyApp.CustomLogEntryTextBuilder, MyApp",
  11. IncludeScopes = true,
  12. MaxQueueSize = 100,
  13. Files = new LogFileOptions[]
  14. {
  15. new LogFileOptions { Path = @"default-<counter>.log", },
  16. new LogFileOptions { Path = @"<date:yyyy>/<date:MM>/other-<counter>.log",
  17. MinLevel = new System.Collections.Generic.Dictionary<string, LogLevel>
  18. {
  19. {
  20. "Default", LogLevel.Trace
  21. }
  22. },
  23. CounterFormat ="00"
  24. }
  25. }
  26. };
  27. var option = Microsoft.Extensions.Options.Options.Create(fileoption);
  28. var logfileProvider = new FileLoggerProvider(option);
  29. 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 的过滤设置..
类似如下代码,

  1. builder.AddFilter((category, level) =>
  2. category == DbLoggerCategory.Database.Command.Name
  3. && level >= LogLevel.Trace).AddConsole();
  4. builder.AddFilter((category, level) =>
  5. category == DbLoggerCategory.Database.Command.Name
  6. && level == LogLevel.Information).AddProvider(logfileProvider);

Console中只会输出 Infomation的日志,而不会输出所有的日志