Использование объекта System.Exception в EventSource

Я пытаюсь использовать источник события (Microsoft.Diagnostics.EventFlow.Inputs.EventSource) для создания события, которое обрабатывается потоком событий (Microsoft.Diagnostic.EventFlow) и чей вывод передается в Application Insights (Microsoft.Diagnostics.EventFlow)..Outputs.ApplicationInsights) для анализа.

Библиотека потока событий, кажется, требует, чтобы я передал весь объект System.Exception потоку событий, чтобы он был успешно классифицирован как событие исключения в Application Insights.

Вот фильтр, который я использую в потоке событий для моего исключения:

    {
      "type": "metadata",
      "metadata": "exception",
      "include": "EventId == 21",
      "exceptionProperty": "shark"
    }

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

Параметры метода Event не соответствуют параметрам метода WriteEvent. Это может привести к неправильному отображению события.

    private const int TestExceptionEventId = 21;
    [NonEvent]
    public void TestException(string operationType, Exception ex)
    {
        string shark = ex.ToString();
        TestException(operationType, shark);
        WriteEvent(TestExceptionEventId, operationType, ex);
    }

    [Event(TestExceptionEventId, Level = EventLevel.Error, Message = "{0} - {1}, {2}", Keywords = Keywords.Exception)]
    public void TestException(string operationType, string shark)
    {

    }

Вот метод, где происходит событие регистрации:

 //EXCEPTION
 //id = 21
 try
 {
     int value = 1 / int.Parse("0");
 }
 catch (DivideByZeroException exception)
 {
     //id = 21
     _eventSource.TestException("hello", exception);
 }`

Может ли кто-нибудь дать некоторую ясность о правильном способе реализации этого и о том, как правильно передать объект System.Exception через Поток событий и Onto Application Insights.

Большое спасибо.

1 ответ

Здесь есть два отдельных вопроса. Одна - это ошибка, которую вы получаете, а другая - конфигурация EventFlow для метаданных исключения. Я буду обращаться к обоим.

Ошибка

Метод, который украшен [Event] атрибут должен вызывать WriteEvent, Например:

private const int TestExceptionEventId = 21;

[NonEvent]
public void TestException(string operationType, Exception ex)
{
    string shark = ex.ToString();
    TestException(operationType, shark);
}

[Event(TestExceptionEventId, Level = EventLevel.Error, Message = "{0} - {1}", Keywords = Keywords.Exception)]
public void TestException(string operationType, string shark)
{
    WriteEvent(TestExceptionEventId, operationType, shark);
}

Примечание: ваше первоначальное свойство Message имело значение Message = "{0} - {1}, {2}", тем не менее, вы предоставляете только 2 параметра для метода (string operationType и string shark). Отсюда и ошибка. Вот почему я изменил его на Message = "{0} - {1}"

Есть некоторые конкретные правила, чтобы это работало. Из документов:

При реализации метода, который определяется как событие ETW в классе, производном от EventSource. Вы должны вызвать метод WriteEvent базового класса, передавая EventId и те же аргументы, что и реализованный метод

Конфигурация EventFlow

Здесь кроется самая большая проблема. EventSource класс не позволяет писать не примитивы, используя WriteEvent, Это включает в себя Exception, Из документов:

Если у события есть дополнительные данные, они должны быть переданы в качестве аргументов. В настоящее время только примитивные типы, DateTime и строка могут быть зарегистрированы с событием.

В репозитории GitHub есть проблема, которая описывает ваши возможности:

Я думаю, у вас есть несколько вариантов.

Одним из них является использование метода EventSource.Write https://msdn.microsoft.com/en-us/library/system.diagnostics.tracing.eventsource.write(v=vs.110).aspx Это должно хорошо работать, если вы используете.NET Core, хотя, честно говоря, я его не проверял. К сожалению, в полной среде есть ошибка, которая не позволяет EventFlow правильно читать уровень событий, поэтому это не рекомендуется, если вы используете полную (настольную) среду.

Второй вариант - использовать другую библиотеку журналов (например, Serilog), которая позволяет передавать произвольные объекты в EventFlow.

Еще один вариант - использовать пользовательский ввод EventFlow. Это должно быть не так хлопотно, как пользовательский вывод для ИИ. Я думаю, что вы могли бы даже интегрировать его с вашим EventSource, например, заставив EventSource реализовать IObservable и используя методы [NonEvent], чтобы вызывать события, которые переносят объекты исключений. Таким образом, у вас будет только один API журналирования, ваш EventSource, для использования приложением.

Мои 2 цента

Мой совет (я так и сделал): забудьте о EventSource и используйте другую библиотеку журналов. Лучшая часть об использовании EventSource - факт, что это показывает структурированную регистрацию. Я закончил тем, что использовал SeriLog, который показывает это также. Он поддерживает не примитивные типы для записи в журнал. EventFlow также поддерживает SeriLog в качестве входных данных или вы можете настроить приемник Application Insights (AI) для SeriLog, который отправляет данные в Application Insights.

Если вы решите пойти на этот вариант, вы можете взглянуть на мою реализацию

Другие вопросы по тегам