Есть ли способ записать значения из словаря данных исключения в. net основной интерфейс ILogger? - PullRequest
1 голос
/ 20 марта 2020

Если я регистрирую исключение с некоторыми парами ключ / значение, добавленными в Данные, эти значения не регистрируются. В некоторых случаях они были бы действительно полезны для диагностики проблемы, но я не вижу никакого способа настроить это.

Например, следующее консольное приложение:

<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!

Нет признаков значений в словаре данных.

То же самое верно, если я регистрируюсь в Azure Application Insight в ASP. NET Базовое приложение.

Можно ли как-нибудь получить эти данные для вывода в журналы?

1 Ответ

1 голос
/ 23 марта 2020

Если я регистрирую исключение с некоторыми парами ключ / значение, добавленными в Данные, эти значения не регистрируются.

Можно ли как-нибудь получить эти данные для вывода в журналах?

В исходном коде ConsoleLogger мы можем обнаружить, что он не извлекает пользовательские пары ключ / значение из свойства Exception.Data и отображает их как выходные данные.

Чтобы удовлетворить ваши требования, вы можете попытаться внедрить и использовать собственный консольный регистратор, как показано ниже.

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

В консольном приложении

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

Результат теста

enter image description here

...