代码改变世界

.netcore log schema and serilog-asp.netcore schema

2022-11-07 17:02  qgbo  阅读(21)  评论(0编辑  收藏  举报

1.   asp.netcore  的 Ilogger 起源这里

            services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());
            services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>)));

我们用 ILogger<> , 实际使用的 是 Logger<>, 其构造函数里注入了 ILoggerFactory

我们用到几个Logger<>,他的构造函数就要执行几次。ILogger<HomeController> 和 ILogger<IndexController> 不是一个对象

LoggerFactory 是单例的,构造方法引入了 IEnumerable<ILoggerProvider> providers。
LoggerFactory 最重要的是 CreateLogger, 返回的类型实际上是 非泛型的Logger, 每一个返回值实际上包含了 一个 LoggerInformation 数组, 
这数组和 provider 是对应的。 这样最后这个 Logger 写的时候,会遍历这个 LoggerInformation 数组,可以根据每个 provider 的 级别决定是否输出。具体逻辑在这里
1.1 如果用 serilog. 想进行进一步的定制,可以 替换 LoggerFactory, 也就是上面代码的第一句话。
但是如果想替换 第二句话,就不行了。因为 总要生成一个 Logger<>, 在serilog 中与之对应的是SerilogLogger :
internal class SerilogLogger : Microsoft.Extensions.Logging.ILogger

2. 从 源码 可以看出: 默认是加载了 consol 等provider的。
3. asp.netcore 一般 这样引用 serilog:
 Host.CreateDefaultBuilder(args)
                .UseSerilog((context, services, configuration) => 
                .configuration.ReadFrom.Configuration(context.Configuration).....

进入UseSerilog, 发现 最终只是替换了 ILoggerFactory ,用的是 SerilogLoggerFactory, 这个不是依赖注入产生的,里面的 Provider 也是new 出来的。

这样,他就破坏了原生框架的结构。上述代码,也不能把日志打印到  Consol 上。

UseSerilog 还有2个默认参数,

bool preserveStaticLogger = false,
bool writeToProviders = false。 最后一个参数表示是否要把其他 provider 也用上。preserveStaticLogger  表示是否要保存  程序启动初始化时候的 Log.Logger

如果都为true,  并且设置了Log.Logger ,就能看到 ILogger<>  和 Log.Information("Saying hello");  到 consol 了。

如果preserveStaticLogger=false,  并且设置了Log.Logger,只有 Log.Information("Saying hello"); 能输出

4. 也可以这样用:这样就沿用了框架log,可以用logging 下的日志结拜节点配置

.ConfigureLogging((hostingContext, loggingBuilder) =>
                {
                    loggingBuilder.AddSerilog();
                })

 但是这个 package 说 推荐 上面  UseSerilog的写法。节点配置不要使用了