是否可以为serilog包装的ILoggerProvider设置特定的格式化程序?

问题描述 投票:1回答:1

我已经按照https://github.com/serilog/serilog-aspnetcore的说明进行操作,并具有以下代码:

public class Program
{
    static readonly LoggerProviderCollection Providers = new LoggerProviderCollection();

    public static int Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
            .Enrich.FromLogContext()
            .WriteTo.Console(new CompactJsonFormatter())
            .WriteTo.Providers(Providers)
            .CreateLogger();

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.ClearProviders();
                logging.AddAzureWebAppDiagnostics();
            })
            .UseSerilog(providers: Providers)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

[logging.AddAzureWebAppDiagnostics()将日志记录配置为使用BlobLoggerProvider到天蓝色的Blob存储,serilog能够使用此提供程序并写入Blob存储。

我想将BlobLoggerProvider的格式化程序更改为CompactJsonFormatter,但我不知道如何。是否可以为serilog包装的ILoggerProvider设置特定的格式化程序?

asp.net-core serilog
1个回答
0
投票

简短的回答是,这不可能为serilog包装的ILoggerProvider设置特定的格式程序,也没有多大意义。

Serilog具有接收器,可将日志调用转发到ILoggerProvider集合中的每个Providers实例。在此接收器中无法配置输出格式。

class LoggerProviderCollectionSink : ILogEventSink, IDisposable
    {
        // ...

        public void Emit(LogEvent logEvent)
        {
            string categoryName = null;

            if (logEvent.Properties.TryGetValue("SourceContext", out var sourceContextProperty) &&
                sourceContextProperty is ScalarValue sourceContextValue &&
                sourceContextValue.Value is string sourceContext)
            {
                categoryName = sourceContext;
            }

            var level = LevelConvert.ToExtensionsLevel(logEvent.Level);
            var slv = new SerilogLogValues(logEvent.MessageTemplate, logEvent.Properties);

            foreach (var provider in _providers.Providers)
            {
                var logger = provider.CreateLogger(categoryName);

                logger.Log(
                    level,
                    default, 
                    slv,
                    logEvent.Exception,
                    (s, e) => s.ToString());
            }
        }
        // ...      
    }

LoggerProviderCollectionSink.cs

ILoggerProvider实现BlobLoggerProvider继承自BatchingLoggerProvider,由BlobLoggerProvider创建的记录器是BatchingLogger。该记录器在将日志消息写入队列之前对其进行了自己的格式化,因此,如果serilog为记录器提供json字符串,将不会有太大帮助。

internal class BatchingLogger : ILogger
    {
        // ... 

        public void Log<TState>(DateTimeOffset timestamp, LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            var builder = new StringBuilder();
            builder.Append(timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff zzz"));
            builder.Append(" [");
            builder.Append(logLevel.ToString());
            builder.Append("] ");
            builder.Append(_category);

            var scopeProvider = _provider.ScopeProvider;
            if (scopeProvider != null)
            {
                scopeProvider.ForEachScope((scope, stringBuilder) =>
                {
                    stringBuilder.Append(" => ").Append(scope);
                }, builder);

                builder.AppendLine(":");
            }
            else
            {
                builder.Append(": ");
            }

            builder.AppendLine(formatter(state, exception));

            if (exception != null)
            {
                builder.AppendLine(exception.ToString());
            }

            _provider.AddMessage(timestamp, builder.ToString());
        }
        // ...
    }

BatchingLogger

© www.soinside.com 2019 - 2024. All rights reserved.