Microsoft.Extensions.Logging - LogError没有记录异常信息

24

我正在使用通过依赖注入获取的简单ASP.NET提供的日志记录器:Microsoft.Extensions.Logging.ILogger<T>。 实际上,动态类型是Microsoft.Extensions.Logging.Logger<T>

在捕获异常时,我尝试使用以下方式记录它们:_logger.LogError(exception, "message"),但只有消息被打印出来。

namespace App
{
    public class App : IApp
    {
        private readonly ILogger<App> _logger;

        public PomParser(ILogger<App> logger)
            => _logger = logger;

        public void DoStuff()
        {
            try
            {
                DoStuffUnsafe();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex,"Failed to do stuff");
            }
        }
    }
}

如何配置日志记录:

var host = new HostBuilder().ConfigureLogging(ConfigureLogging)...
...
await host.RunAsync();
        private static void ConfigureLogging(HostBuilderContext hostContext, ILoggingBuilder configLogging)
        {
            configLogging.ClearProviders();
            configLogging.AddConfiguration(hostContext.Configuration.GetSection("Logging"));
            configLogging.AddFile(
                options =>
                {
                    hostContext.Configuration.GetSection("FileLoggingOptions")
                        .Bind(options);
                }
            );
            configLogging.AddConsoleLogger();
        }

应用程序设置:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "FileLoggingOptions": {
    "FileName": "app-",
    "LogDirectory": "logs",
    "FileSizeLimit": 10485760,
    "Extension": "log"
  }
}

1
@Fildor 添加了配置。 - Mugen
configLogging.AddFile() - 这是什么?没有内置的文件记录器。因此,如果您没有看到异常,则显然不支持记录它们的那个记录器。 - poke
@poke 你说得对,这是来自一个外部包:https://github.com/andrewlock/NetEscapades.Extensions.Logging 但我也没有看到它被记录到控制台中,而那是一个内置的日志记录器。 - Mugen
该记录器不会记录到文件。 - user12053089
你调用了 configLogging.ClearProviders();,所以除非你再次显式添加它们,否则所有内置的日志记录器都将消失。因此,你看不到控制台日志,因为没有控制台记录器。 - poke
你提供的那个滚动文件日志记录器确实会写出异常,因此它应该可以工作。 - poke
2个回答

27

你使用的是哪个日志提供者? - silkfire
1
啊,我追溯到我们自己的实现了。我的错。我已经删除了我的评论。 - Grant Birchmeier

7
请查看默认的MessageFormatterhttps://github.com/aspnet/Logging/blob/master/src/Microsoft.Extensions.Logging.Abstractions/LoggerExtensions.cs
        private static string MessageFormatter(FormattedLogValues state, Exception error)
        {
            return state.ToString();
        }

它只是忽略了异常... 我实现了一个自定义的控制台日志记录器:

public class ConsoleLoggerProvider : ILoggerProvider
{
    public void Dispose()
    {
    }

    public ILogger CreateLogger(string categoryName)
        => new ConsoleLogger(categoryName);

    private class ConsoleLogger : ILogger
    {
        private readonly string _categoryName;

        public ConsoleLogger(string categoryName)
            => _categoryName = categoryName;

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

            Console.WriteLine(
                $"{DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} [{logLevel}] {_categoryName}: {state}{(exception != null ? "\n" : string.Empty)}{exception}"
            );
        }

        public bool IsEnabled(LogLevel logLevel)
            => true;

        public IDisposable BeginScope<TState>(TState state)
            => null;
    }
}

并且使用它:

public static Task Main(string[] args)
    => WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration(...)
        .ConfigureServices(...)
        .ConfigureLogging((hostContext, loggingBuilder) => loggingBuilder.AddProvider(new ConsoleLoggerProvider()))
        .UseStartup<Startup>()
        .Build()
        .RunAsyncSafe();

那么,如果您绕过扩展方法并使用类似以下的内容,这样会起作用吗? this.theLogger.Log(LogLevel.Error, ex, "My Extra" + ex.Message); - granadaCoder
4
是的,但这需要始终记住添加+ ex.Message,而且不会打印堆栈跟踪。 - Mugen
IsEnabled 返回 true,这是否意味着对 IsEnabled 的检查是多余的? - NotoriousPyro
确实,但它是接口的一部分。您还可以实现自己的逻辑,允许在某些条件下禁用记录器。 - Mugen

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