首页 文章

创建返回Serilog LoggerConfiguration的方法(Asp.Net Core 2.0)

提问于
浏览
2

我最初使用一个日志文件用于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配置列表,我需要创建 Logger ,并添加所有这些子 Logger . 每个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);

但这个错误,

无法将类型'Serilog.LoggerConfiguration'隐式转换为'Serilog.ILogger'

我尝试将方法更改为ILogger并返回ILogger,但ILogger不包含WriteTo和ReadFrom方法,所以这是不行的 . 我尝试将返回的LoggerConfiguration转换为ILogger,但这也不起作用,并且许多其他迭代也失败了 .

必须有办法实现这一目标 . 任何帮助赞赏 .

Update:

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();
        }
    }

1 回答

  • 2

    我尝试将方法更改为ILogger并返回ILogger,但ILogger不包含WriteTo和ReadFrom方法,因此这是不行的 .

    Serilog bootstraping的顺序如下:

    • 您创建 Serilog.LoggerConfiguration 对象的实例,并使用代码调用( WriteTo.RollingFile() )或配置文件( ReadFrom.Configuration() )进行设置 .

    • 然后在构建Serilog配置后,使用 LoggerConfiguration.CreateLogger() 调用创建一个 Logger .

    因此,在您完成加载配置之前,您可以't log any messages (you don'尚未拥有 Logger 实例 . 但是在构建 Logger 之后,没有必要调用 WriteToReadFrom 方法,因为已经构建了logger,并且对源配置的更改不会影响任何内容 .

    因此,您可以将 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");
    }
    

相关问题