Logger.LogDebug与Debug.WriteLine的区别

4

我有这个程序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace debuglogtest
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                });
    }
}

使用这个 worker

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace debuglogtest
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;

        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _logger.LogDebug("_logger.LogDebug");
            _logger.LogTrace("_logger.LogTrace");
            Debug.WriteLine("Debug.WriteLine");
        }
    }
}

以及这个配置。

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

当我在调试模式下运行dotnet run -c Debug时,控制台会输出以下内容:

dbug: debuglogtest.Worker[0] _logger.LogDebug

同时,在DebugView中也可以看到如下内容: DebugView of debug output 这是预期的结果,因为我们编译程序时会得到调试日志。但是,当我用dotnet run -c Release在发布模式下编译时,控制台仍然会输出以下信息:

dbug: debuglogtest.Worker[0] _logger.LogDebug

但是在DebugView中没有任何内容: DebugView of release output 我的期望是:
  1. 在编译调试模式时,_logger.LogDebug会同时在控制台和DebugView中输出,而在编译发布模式时不会输出。
  2. 在编译调试模式时,Debug.WriteLine要输出到DebugView中。
实际情况是:
  1. 在调试模式下,_logger.LogDebug只输出到控制台,而不会在DebugView中显示。
Debug.WriteLine在调试模式下正确地输出到DebugView。
我认为LogDebug在幕后调用了Debug.WriteLine,但也许Debug.WriteLineLogger.LogDebug是两个不同的东西?这看起来确实令人困惑,因为我们需要在两个不同的地方(编译和过滤时)控制调试日志。如果我阅读文档:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-3.1#debug,它说它调用相同的Debug.WriteLine

调试提供程序使用System.Diagnostics.Debug类编写日志输出。对System.Diagnostics.Debug.WriteLine的调用将写入调试提供程序。

我是否做错了什么?我一定有什么误解。我希望能够在调试模式下编译时控制Logger.Debug。这不可能吗?
如果我查看源代码(虽然它有点旧了(有人知道更新的参考资料请指明)):https://github.com/aspnet/Logging/blob/master/src/Microsoft.Extensions.Logging.Debug/DebugLogger.debug.cs,我可以看到它定义了#define DEBUG并调用了Debug.WriteLine,但是这在我的脑海中不成立。它应该出现在DebugView中,但无论是在调试模式还是发布模式下都没有出现。
1个回答

2

ILogger.LogDebugILogger.LogTrace等都是关于消息的LogLevel,而不是关于消息写在哪里的,基本上相当于使用相应的logLevel参数值调用Log(..)。日志消息的写入目的地由您使用的记录器(控制台、文件、ETW,我相信您甚至可以创建一个将消息写入调试视图的记录器,请参见文档中的日志提供程序部分)来确定。LogLevel允许您过滤实际写入日志目标的日志级别,并由appsettings进行调节,而不是直接由构建配置进行调节(尽管您可以为不同的配置设置不同的设置)。


这是有道理的,但是 CreateDefaultHost 仍然会添加 .AddDebug()。这与日志记录有什么关系呢?我不能使用 Logger 来写入能在 DebugView 中显示的源吗? - mslot
实际上,在我的脑海中这没有意义。它通过.AddDebug()添加了DebugProvider,应该在DebugView中显示出来。它出现在控制台中,因为应用了.AddConsole,并且使用#define DEBUG,理论上它应该在发布模式下显示(理论上)。只有当应用某种过滤器时(我猜是这样),才会出现这种情况。我认为这是奇怪的行为。 - mslot
1
请查看日志记录文档DebugLogger,其中描述为“仅在调试器附加时将消息写入调试输出窗口的记录器。” - Guru Stron
1
我完全错过了那一行 :) 我已经仔细阅读了这些文档(请查看我的更新,我已添加了相同的链接)。你是对的。我不知道怎么会错过 https://github.com/aspnet/Logging/blob/master/src/Microsoft.Extensions.Logging.Debug/DebugLogger.cs#L44。代码永远不会说谎。谢谢!现在一切都有意义了。DebugLogger 通过 release 模式中的 #define DEBUG 激活写入调试信息,但是它停止的地方是第 44 行。再次感谢! - mslot
@mslot很高兴能够帮忙! - Guru Stron

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