从 .NET Core 3.1 (Docker) 迁移后,.NET 6 应用程序日志采用 JSON 格式

Wat*_*ont 6 .net docker .net-core asp.net-core .net-6.0

我最近将.NET Core REST API 从3.1 更新到 6.0。当我在开发或发布配置中没有 Docker 的情况下在本地运行应用程序时,日志的格式一如既往:

在此输入图像描述

当将应用程序作为Docker 容器运行时,日志将转换为 JSON。这只是在迁移到 .Net 6 之后出现的。

在此输入图像描述

如何恢复 Docker 环境中的标准日志格式?

Pan*_*vos 6

该更改是在 .NET 5 中进行的,而不是在 6 中进行的。在 .NET Core 3.1 中,控制台日志格式已修复。在 .NET 5 中,现在可以使用 3 个预定义的格式化程序进行自定义:Simple(旧的)、Systemd 和 Json(默认)。可以创建自定义格式化程序。

正如文档所示,可以通过使用AddSimpleConsole以下方法来使用简单格式化程序AddConsole

    using ILoggerFactory loggerFactory =
        LoggerFactory.Create(builder =>
            builder.AddSimpleConsole(options =>
            {
                options.IncludeScopes = true;
                options.SingleLine = true;
                options.TimestampFormat = "hh:mm:ss ";
            }));
Run Code Online (Sandbox Code Playgroud)

其他两个格式化程序也有类似的方法:AddSystemdConsoleAddJsonConsole

可以通过配置设置格式化程序

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        },
        "Console": {
            "LogLevel": {
                "Default": "Information",
                "Microsoft": "Warning",
                "Microsoft.Hosting.Lifetime": "Information"
            },
            "FormatterName": "json",
            "FormatterOptions": {
                "SingleLine": true,
                "IncludeScopes": true,
                "TimestampFormat": "HH:mm:ss ",
                "UseUtcTimestamp": true,
                "JsonWriterOptions": {
                    "Indented": true
                }
            }
        }
    },
    "AllowedHosts": "*"
}
Run Code Online (Sandbox Code Playgroud)

最后,可以通过继承ConsoleFormatter并重写该Write方法来创建一个全新的格式化程序:

public sealed class CustomFormatter : ConsoleFormatter, IDisposable
{
   ...

    public override void Write<TState>(
        in LogEntry<TState> logEntry,
        IExternalScopeProvider scopeProvider,
        TextWriter textWriter)
    {
        string? message =
            logEntry.Formatter?.Invoke(
                logEntry.State, logEntry.Exception);

        if (message is null)
        {
            return;
        }

        CustomLogicGoesHere(textWriter);
        textWriter.WriteLine(message);
    }

   ...
}


Run Code Online (Sandbox Code Playgroud)