Настройка записи логов Serilog с помощью методов расширения - PullRequest
0 голосов
/ 17 января 2019

Я разрабатываю сервис asp.net core web api. Мне нужно писать логи в консоль и Logstash. Я добился этого с помощью следующего кода:

public class Program
{
    private static IConfiguration Configuration { get; } = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())                              
        .AddJsonFile("appsettings.json")
        .AddEnvironmentVariables()
        .Build();

    public static void Main(string[] args)
    {
        var uri = Configuration.GetSection("Serilog").GetSection("uri").Value;

        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Override("Microsoft", LogEventLevel.Error)
            .ReadFrom.Configuration(Configuration)
            .WriteTo.Console()
            .WriteTo.TCPSink(uri)
            .CreateLogger();

        try
        {
            Log.Information("Starting web host");
            CreateWebHostBuilder(args).Build().Run();
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host terminated unexpectedly");
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {   
        return WebHost
            .CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseSerilog();  
    }
}

Проблема в том, что у меня есть требование использовать нашу корпоративную dll, в которой есть два метода расширения - один для входа в консоль, другой - для входа по tcp.

Вот пример этих методов:

    public static IWebHostBuilder UseTCPLogging(
        this IWebHostBuilder builder,
        IConfiguration configuration, string uri)
    {
        return builder
            .UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
                .MinimumLevel.Override("Microsoft", LogEventLevel.Error)
                .ReadFrom.Configuration(configuration)
                .WriteTo.TCPSink(uri));
    }

    public static IWebHostBuilder UseConsoleLogging(
        this IWebHostBuilder builder)
    {
        return builder
            .UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
                .MinimumLevel.Override("Microsoft", LogEventLevel.Error)
                .ReadFrom.Configuration(configuration)
                .WriteTo.Console());
    }

Тогда мы можем использовать их следующим образом:

public class Program
{
    private static IConfiguration Configuration { get; } = new ConfigurationBuilder()
        // . . . the same as above

    public static void Main(string[] args)
    {
        try
        {
            CreateWebHostBuilder(args).Build().Run();
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host terminated unexpectedly");
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var uri = Configuration.GetSection("Serilog").GetSection("uri").Value;

        return WebHost
            .CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseConsoleLogging()
            .UseTCPLogging(Configuration, uri);  
    }
}

Но проблема в том, что с этим кодом логи пишутся только tcp, а не в консоли . Похоже, UseTCPLogging() переопределяет LoggerConfiguration.

Я хотел бы знать, есть ли способ сделать то, что мне нужно, с помощью этих двух методов расширения. Создание только одного метода, который будет писать в консоль и с помощью tcp, не кажется хорошим обходным путем.

ОБНОВЛЕНИЕ 25-01-19:

Я пытался сделать это с помощью шаблона оформления Decorator вот так но это не работает.

...