din*_*tom 4 c# logging serilog
我最初使用 Serilog 的一个日志文件,这是我通过这样做完成的
var slc = new SerilogSubLoggerConfiguration();
configuration.GetSection("Serilog:SubLogger").Bind(slc);
Run Code Online (Sandbox Code Playgroud)
然后在Program.cs的Main方法中配置SubLogger
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.WriteTo.Logger(logger => logger.Filter.
ByIncludingOnly(lvl => lvl.Level == slc.Level).WriteTo.RollingFile(slc..PathFormat))
.CreateLogger();
Run Code Online (Sandbox Code Playgroud)
我已转而使用现在在 appsettings 文件中定义的三个单独的日志。这将创建具有一个属性的类,即一系列 Serilog 配置
public class SerilogSubLoggerConfigurations
{
public List<SerilogSubLoggerConfiguration> SubLoggers { get; set; }
}
var slcs = configuration.GetSection("Serilog").Get<SerilogSubLoggerConfigurations>();
Run Code Online (Sandbox Code Playgroud)
现在我有了 SubLogger 配置列表,我需要创建记录器并添加所有这些子记录器。每个 SubLogger 都需要自己的
.WriteTo.Logger(logger => logger.Filter.
ByIncludingOnly(lvl => lvl.Level == slc.Level).WriteTo.RollingFile(slc..PathFormat))
Run Code Online (Sandbox Code Playgroud)
Log.Logger 调用中的行,因此我需要迭代 SubLoggers。我的目的是写一个方法来做到这一点。
public static LoggerConfiguration GetLoggerConfiguration(IConfiguration config, SerilogSubLoggerConfigurations slcs)
{
var lc = new LoggerConfiguration();
lc.ReadFrom.Configuration(config);
foreach (var cfg in slcs.SubLoggers)
{
lc.WriteTo.Logger(logger => logger.Filter
.ByIncludingOnly(lvl => lvl.Level == cfg.Level).WriteTo
.RollingFile(cfg.PathFormat));
}
lc.CreateLogger();
return lc;
}
Run Code Online (Sandbox Code Playgroud)
然后在 Main 方法中使用它
Log.Logger = GetLoggerConfiguration(configuration, slcs);
Run Code Online (Sandbox Code Playgroud)
但这是错误的,
无法将类型“Serilog.LoggerConfiguration”隐式转换为“Serilog.ILogger”
我尝试将方法更改为 ILogger 并返回 ILogger,但 ILogger 不包含 WriteTo 和 ReadFrom 方法,因此这是不行的。我尝试将返回的 LoggerConfiguration 转换为 ILogger,但这也不起作用,并且许多其他迭代也失败了。
必须有一种方法来实现这一点。任何帮助表示赞赏。
更新:
public static int Main(string[] args)
{
var currentEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{currentEnv}.json", optional: true)
.AddEnvironmentVariables()
.Build();
var slcs = configuration.GetSection("Serilog").Get<SerilogSubLoggerConfigurations>();
Log.Logger = BuildLogger(configuration, slcs);
Log.Information(Appname != null ? $"{Appname}{LogDelimeter}Logger created." : "Logger created.");
try
{
Log.Information(Appname != null ? $"{Appname}{LogDelimeter}Starting web host" : "Starting web host.");
BuildWebHost(args).Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex,
Appname != null
? $"{Appname}{LogDelimeter}Web Host terminated unexpectedly"
: "Web Host terminated unexpectedly");
return 1;
}
finally
{
Log.Information(Appname != null ? $"{Appname}{LogDelimeter}Flushing log and closing it." : "Flushing log and closing it.");
Log.CloseAndFlush();
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试将方法更改为 ILogger 并返回 ILogger,但 ILogger 不包含 WriteTo 和 ReadFrom 方法,因此这是不行的。
Serilog 引导的顺序如下:
Serilog.LoggerConfiguration来设置它。WriteTo.RollingFile()ReadFrom.Configuration()LoggerConfiguration.CreateLogger()call 创建一个记录器。因此,在完成加载配置之前,您无法记录任何消息(您还没有Logger实例)。但是在构建了记录器之后,就没有必要调用WriteTo或ReadFrom方法了,因为记录器已经构建并且对源配置的更改不会影响任何内容。
所以你可以将你的GetLoggerConfiguration()方法更改为:
public static Serilog.ILogger BuildLogger(IConfiguration config, SerilogSubLoggerConfigurations slcs)
{
var lc = new LoggerConfiguration();
lc.ReadFrom.Configuration(config);
foreach (var cfg in slcs.SubLoggers)
{
lc.WriteTo.Logger(logger => logger.Filter
.ByIncludingOnly(lvl => lvl.Level == cfg.Level).WriteTo
.RollingFile(cfg.PathFormat));
}
// Apply any additional changes to lc configuration here
// Finally build a logger
return lc.CreateLogger();
}
static void Main(string[] args)
{
// ...
var logger = BuildLogger(configuration, subLoggerConfigurations);
// No any changes could be made to logging configuration at this point.
// Just log what you need.
logger.Information("Test info message");
}
Run Code Online (Sandbox Code Playgroud)