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

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

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

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

    {
      "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 через поток событий и в Application Insights.

Огромное спасибо.


person Brian Delaney    schedule 08.06.2017    source источник


Ответы (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 и string могут быть зарегистрированы вместе с событием.

В репозитории 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.

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

person Peter Bons    schedule 08.06.2017