Использование объекта 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.
Если вы решите пойти на этот вариант, вы можете взглянуть на мою реализацию