Is there a way to log the values from the Data dictionary of an exception in .net core ILogger interface?

一世执手 提交于 2020-06-28 05:38:06

问题


If I log an exception with some key/value pairs added to Data, those values do not get logged. They would be really helpful for diagnosis of the issue in some cases but I can't see any way to configure that.

For example, the following console app:

<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();
    }
}

Results in this being logged to the console:

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

No sign of the values in the Data dictionary.

The same is true if I log to Azure Application Insight in an ASP.NET Core app.

Is there any way I can get that data to output in the logs?


回答1:


If I log an exception with some key/value pairs added to Data, those values do not get logged.

Is there any way I can get that data to output in the logs?

In source code of ConsoleLogger, we can find that it does not extract user-defined key/value pairs from Exception.Data property and display them as output.

To achieve your requirement, you can try to implement and use a custom Console logger, like below.

MyCustomConsoleLoggerProvider class

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

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

CustomConsoleLogger class

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;
}

In Console app

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();
    }
}

Test Result



来源:https://stackoverflow.com/questions/60778831/is-there-a-way-to-log-the-values-from-the-data-dictionary-of-an-exception-in-ne

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!