c#-创建方法以返回Serilog LoggerConfiguration(Asp.Net Core 2.0)

最初,我为Serilog使用了一个日志文件,通过完成此操作

var slc = new SerilogSubLoggerConfiguration();   
configuration.GetSection("Serilog:SubLogger").Bind(slc);

然后在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();

我现在使用的是现在在appsettings文件中定义的三个单独的日志.
这将创建具有一个属性的Serilog配置列表的类

 public class SerilogSubLoggerConfigurations
{
    public List<SerilogSubLoggerConfiguration> SubLoggers { get; set; }
}

var slcs = configuration.GetSection("Serilog").Get<SerilogSubLoggerConfigurations>();

现在我有了SubLogger配置的列表,我需要创建记录器,并添加所有这些子记录器.每个SubLogger将需要自己的

.WriteTo.Logger(logger => logger.Filter.
                ByIncludingOnly(lvl => lvl.Level == slc.Level).WriteTo.RollingFile(slc..PathFormat))

行在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;
    }

然后在Main方法中使用它

Log.Logger = GetLoggerConfiguration(configuration, slcs);

但这是错误的,

Cannot implicitly convert type ‘Serilog.LoggerConfiguration’ to ‘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();
        }
    }

解决方法:

I tried changing the method to an ILogger and returning an ILogger,
but ILogger doesn’t contain the WriteTo and ReadFrom methods, so that
was a no go.

Serilog引导程序的顺序如下:

>创建一个Serilog.LoggerConfiguration对象的实例,并通过代码调用(WriteTo.RollingFile())或从配置文件(ReadFrom.Configuration())对其进行设置.
>然后,在构建Serilog配置之后,您将通过LoggerConfiguration.CreateLogger()调用创建一个记录器.

因此,在完成配置加载之前,您无法记录任何消息(您还没有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");
}
上一篇:Serilog通过文件配置不生效


下一篇:如何从Serilog请求日志记录中排除健康检查终结点