.NET Core 2.0的日志记录是否有问题?

39

我升级到.NET Core 2.0(+ASP.NET Core 2.0)后,似乎无法输出Trace级别的日志信息。

事实上,如果我在Startup的Configure方法中添加下面的代码,我将无法获得任何Trace或Debug日志消息,但我会获得Information和Error消息两次。注释掉.AddConsole()调用将仅输出这些(Information和Error)一次 - 这表明它默认情况下已使用控制台提供程序进行配置。请记住,这是一个“新建项目”体验,对于此项目而言,在Program.cs中没有为日志记录或配置设置 - 除了我添加的内容。有人看到过这种情况吗?还是我应该在GitHub上注册一个问题。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Microsoft.Extensions.Logging.LogLevel.Trace);

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.Run(async (context) =>
    {
        var logger = loggerFactory.CreateLogger("Blah");
        logger.LogTrace("Hello world : Trace");
        logger.LogDebug("Hello world : Debug");
        logger.LogInformation("Hello world : Information");
        logger.LogError("Hello world : Error");

        await context.Response.WriteAsync("Hello World!");
    });
}

你的意思是什么?“will give me them once” - mjwills
编辑后,我会收到两次信息和错误提示 - 但是如果我删除AddConsole()行 - 我只会收到一次信息和错误提示 - 但是无论是否有我的显式行来指定控制台和Trace级别,都不会收到Trace或Debug消息。 - EinarI
3
你正在开发模式下运行吗?默认环境现在是生产环境。你可以尝试使用 set ASPNETCORE_ENVIRONMENT=Development; dotnet run 命令来切换到开发环境并运行应用程序。 - Martin Ullrich
我遇到了类似的问题。在日志语句后添加 await Task.Delay(1) 可以使控制台显示日志。如果不加,控制台上只会显示部分日志。被接受的答案实际上没有起到任何作用。这似乎是一个线程问题。 - bloudraak
4个回答

44
配置日志的方式有些变化...现在建议的方式(详见这个GitHub问题/公告)是在AddLogging方法上配置记录器。
services.AddLogging(builder =>
{
    builder.AddConfiguration(Configuration.GetSection("Logging"))
        .AddConsole()
        .AddDebug();
});

并且有一个像 appsettings.json 这样的配置文件

注意

似乎有些人感到困惑,因为示例仅演示了如何配置Console提供程序,而不是所有记录器。

LogLevel 部分配置了所有命名空间(Default 键)或特定命名空间(System 覆盖所有以 System.* 开头的类的默认值。这适用于在 ILogger<T> 中使用的类。这允许为来自此命名空间的记录器设置比默认日志记录级别更高或更低的级别。

{
  "ApplicationInsights": {
    "InstrumentationKey": ""
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Information",
      "System": "Warning",
      "Microsoft": "Information"
    },
    "Console": {
      "LogLevel": {
        "Default": "Warning",
        "System": "Information",
        "Microsoft": "Information"
      }
    }
  }
}
请注意,appsettings.json的结构已经与.NET Core 1.x时期不同,而且现在在appsettings.json中的Logging条目中含有记录器提供程序名称,这使您可以根据记录器提供程序配置记录级别。
以前,在appsettings.json中的条目只适用于控制台记录器。
或者,现在可以将日志移动到WebHostBuilder中。
public static void Main()
{
    var host = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            var env = hostingContext.HostingEnvironment;

            config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddJsonFile("hosting.json", optional: false)
                .AddEnvironmentVariables();
        })
        .ConfigureLogging((webhostContext, builder) => {
            builder.AddConfiguration(webhostContext.Configuration.GetSection("Logging"))
            .AddConsole()
            .AddDebug();
        })
        .UseIISIntegration()
        .UseStartup<Startup>()
        .UseApplicationInsights()
        .Build();

    host.Run();
}

更新

如果不想使用appsettings.json,也可以在代码中注册筛选器。

services.AddLogging(builder =>
{
    builder.AddConfiguration(Configuration.GetSection("Logging"))
        // filter for all providers
        .AddFilter("System", LogLevel.Debug)
        // Only for Debug logger, using the provider type or it's alias
        .AddFilter("Debug", "System", LogLevel.Information)
        // Only for Console logger by provider type
        .AddFilter<DebugLoggerProvider>("System", LogLevel.Error)
        .AddConsole()
        .AddDebug();
});

谢谢。实际上,只需添加一个带有日志配置的 appsettings.json 文件,而不需要任何日志设置,似乎就可以满足我的需求。 - EinarI
2
builder.SetMinimumLevel(LogLevel.Trace); - Dave Thieben
2
请注意,使用AddConfiguration需要安装Microsoft.Extensions.Configuration包。 - Elan Hasson
这些内容是否允许实际的调试消息写入日志?也就是说,如果使用“LogLevel Default: Debug”,那么Debug.WriteLine的输出结果最终会出现在日志中。因为如果没有这样的功能,它就没有什么用处,因为:1)我不想将Microsoft的日志类注入到每个应用程序中的低级组件,并将每个WriteLine替换为_log.LogDebug;2)如果我正在使用第三方组件,我可能无法将Microsoft的日志类注入到这些组件中。 - Neutrino
1
我发现你的 appsettings.json 示例在 .NET Core 2.1 中是不正确的,这个链接中的示例对我有效:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1 - Art
显示剩余6条评论

9

我花了将近二十分钟才意识到,Startup.cs文件中的Configuration.GetSection("Logging")appsettings.json配置文件中读取"Logging"部分,并且该部分被配置为"Error"。将其更改为"Information"或更低级别即可解决问题。

以下是现在的appsettings.json文件的内容:

{
  "Logging": {
    "IncludeScopes": true,
    "Debug": {
      "LogLevel": {
        "Default": "Information"
      }
    },
    "Console": {
      "LogLevel": {
        "Default": "Information"
      }
    }
  }
}

如果想了解更多日志级别(例如“Information”),请查看此链接,它还提供了有关ASP.NET Core日志记录的一般信息。

如果在使用日志记录时遇到任何问题,请确保已查看 JSON 文件。


6

以上的方法都对我无效,唯一的解决办法是编写一个方法。

private void ConfigLogging( ILoggingBuilder builder ) {
    builder.SetMinimumLevel( LogLevel.Trace );
    //... additional configuration...
}

当使用AddLogging扩展方法时,请按以下方式编写:

services.AddLogging( ConfigLogging );

你确定你的appsettings.json格式正确吗?或者这个值被其他配置源(例如开发设置、环境变量等)覆盖了吗? - Tseng
我通过添加以下代码行解决了这个问题: .ConfigureLogging((hostingContext, logging) => { ... logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); ... }) - nan
好像“Trace”被特殊处理,只有在声明的代码中才会被视为日志级别,而不是配置文件。但我没有看到任何相关文档。 - AndyClaw

0

下面这个appsettings.json的结构似乎可以正常工作:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "System": "Information",
      "Microsoft": "Information"
    },
    "Console":
    {
      "IncludeScopes": true
    }
  }
}

摘自https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1

此外,看看你的启动调用是什么,我发现以下内容对我有用:

public class Startup
{
    public Startup(IHostingEnvironment env)
    {

        var logger = new LoggerConfiguration()
                .MinimumLevel.Information()
                .WriteTo.Sink(jsonSink)
                .Enrich.WithExceptionDetails()
                .CreateLogger();

        Log.Logger = logger;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接