2

如果我在数据中添加了一些键/值对来记录异常,则不会记录这些值。在某些情况下,它们对诊断问题非常有帮助,但我看不到任何配置方法。

例如,以下控制台应用程序:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.2" />
  </ItemGroup>

</Project>
class Program
{
    static void Main(string[] args)
    {
        var exception = new Exception("Oops!");
        exception.Data.Add("useful-data-key", "useful-data-value");

        ILogger<Program> logger = LoggerFactory.Create(builder => builder.AddConsole()).CreateLogger<Program>();

        logger.LogError(exception, "An error occurred in the console.");

        Console.WriteLine("Logged");
        Console.Read();
    }
}

结果被记录到控制台:

fail: Console.Program[0]
      An error occurred in the console.
System.Exception: Oops!

数据字典中没有值的符号。

如果我在 ASP.NET Core 应用程序中登录到 Azure Application Insight,情况也是如此。

有什么办法可以让这些数据输出到日志中?

4

1 回答 1

1

如果我在数据中添加了一些键/值对来记录异常,则不会记录这些值。

有什么办法可以让这些数据输出到日志中?

的源代码中ConsoleLogger,我们可以发现它没有从Exception.Data属性中提取用户定义的键/值对并将它们显示为输出。

为了满足您的要求,您可以尝试实现和使用自定义控制台记录器,如下所示。

MyCustomConsoleLoggerProvider 类

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

    public ILogger CreateLogger(string categoryName)
        => new CustomConsoleLogger(categoryName);
}

CustomConsoleLogger 类

internal class CustomConsoleLogger : ILogger
{
    private readonly string _categoryName;

    public CustomConsoleLogger(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;
        }

        StringBuilder logBuilder = new StringBuilder();

        logBuilder.Append($"{logLevel} {_categoryName}: {state}{(exception != null ? "\n" : string.Empty)}{exception}\n");


        if (exception.Data != null)
        {
            logBuilder.Append("Exception Data: ");

            exception.Data.Cast<DictionaryEntry>().ToList().ForEach((item) =>
            {
                string key = item.Key.ToString();
                string vl = item.Value.ToString();

                logBuilder.Append($"{key}:{vl}\n");
            });
        }

        Console.WriteLine(logBuilder.ToString());

    }

    public bool IsEnabled(LogLevel logLevel)
        => true;

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

在控制台应用程序中

class Program
{
    static void Main(string[] args)
    {
        var exception = new Exception("Oops!");

        exception.Data.Add("useful-data-key1", "useful-data-value1");
        exception.Data.Add("useful-data-key2", "useful-data-value2");

        ILogger<Program> logger = LoggerFactory.Create(builder =>
            {
                //builder.AddConsole();
                builder.AddProvider(new MyCustomConsoleLoggerProvider());
            }).CreateLogger<Program>();

        logger.LogError(exception, "An error occurred in the console.");

        Console.WriteLine("Logged");

        Console.Read();
    }
}

测试结果

在此处输入图像描述

于 2020-03-23T06:31:29.043 回答