代码改变世界

serilog-asp.net 源码解析

2022-08-28 19:12  qgbo  阅读(83)  评论(0编辑  收藏  举报

 这是 serilog-asp.net 的demo:   https://github.com/serilog/serilog-aspnetcore/blob/dev/samples/Sample/Program.cs

开始是这一句话

// The initial "bootstrap" logger is able to log errors during start-up. It's completely replaced by the
// logger configured in `UseSerilog()` below, once configuration and dependency-injection have both been
// set up successfully.
            Log.Logger = new LoggerConfiguration()
                .WriteTo.Console()
                .CreateBootstrapLogger();

这个 UseSerilog()  里面有个参数  bool preserveStaticLogger =false, 如果不传(默认false), 最终将会被替换。

而如果替换,上面的代码,就要写成 CreateBootstrapLogger(), 而不是 CreateLogger()

这关系到  UseSerilog() 这里面这句话的转换结果。

var reloadable = Log.Logger as ReloadableLogger;

在这个demo中,之所以替换,一个原因是他们的Configration 不一样。第一句话没有配置,直接WriteTo.Console()

UseSerilog() ,读取了配置。

这个demo, reloadable 为true, 最后会执行下面代码

reloadable.Reload(delegate (LoggerConfiguration cfg)
                        {
                            if (loggerProviders != null)
                            {
                                cfg.WriteTo.Providers(loggerProviders);
                            }

                            configureLogger(context, services, cfg);
                            return cfg;
                        });

这个结果,是new LoggerConfiguration()),然后把progam.cs  里UseSerilog() 的委托执行了,再CreateLogger(),赋值给logger3。

logger3 实现的是RegisteredLogger,最后赋值给Log.Logger

 

UseSerilog() 的后面  依赖注入了  ILoggerFactory,实现的是 new SerilogLoggerFactory(logger, dispose, providers);

SerilogLoggerFactory 中 new SerilogLoggerProvider(logger, dispose); 后者又new SerilogLogger(this, _logger, name),这样定义  SerilogLogger : Microsoft.Extensions.Logging.ILogger

在这些new 方法中,_logger 是null, 传了一路,最后赋给默认值 Serilog.Log.Logger

 这会让 ILogger 最终使用到Serilog.Log.Logger

 

如果 UseSerilog()  的参数 preserveStaticLogger 赋值为true, 最后, ILogger 和 会不是同一个。

ILogger logger = services.GetRequiredService<RegisteredLogger>().Logger;
ILogger logger2 = null;
if (preserveStaticLogger)
{
      logger2 = logger;
}
else
{
      Log.Logger = logger;
}

SerilogLoggerFactory serilogLoggerFactory = new SerilogLoggerFactory(logger2, !useReload, loggerProviders);

默认 UseSerilog()  的参数writeToProviders 为空,不把原来的Logprovider  带上。