System.Diagnostics - источник событий с пустым сообщением
Я использую System.Diagnostics для получения некоторых сообщений с помощью EventSource, чтобы отслеживать их как журнал. Похоже, что некоторые данные отсутствуют, например, EventMessage и Сообщение (они пусты), в то время как EventId и Уровень установлены правильно. Метод WriteEvent является правильным (количество и типы аргументов, передаваемых каждому методу события, в точности соответствуют данным, передаваемым в WriteEvent()). В частности, я использую WAD в кластере ServiceFabric для сбора трассировок в хранилище таблиц Azure. Любая идея?
Спасибо!
2 ответа
У меня была эта проблема с тех пор, как мы обновили до любой версии.NET Framework больше, чем 4.5.2. Я наконец понял свою проблему и, надеюсь, это тоже поможет вам. Я знаю, что это старый пост, но, возможно, он поможет кому-то еще.
Кажется, что Event Tracing for Windows (ETW) обрабатывает ошибки, и единственное, что вы получаете, это то, что вы видите, когда записанное в журнал сообщение является нулевым. Я использую пользовательский форматер, полученный из IEventTextFormatter. (EventData.FormattedMessage является нулевым). Установка точки останова в этом методе показала, что EventData.FormattedMessage было нулевым. Я также заметил следующие сообщения в окне "Вывод / отладка" в Visual Studio:
The parameters to the Event method do not match the parameters to the WriteEvent method. This may cause the event to be displayed incorrectly.
EventSourceException while processing event "WriteLogDefault": System.IndexOutOfRangeException:Index was outside the bounds of the array.
A first chance exception of type 'System.NullReferenceException' occurred in NEAM.App.ProfileDataMart.BL.dll
Я проследил свою проблему до следующего метода:
[Event(1, Message = "{2}", Level = EventLevel.Informational, Keywords = Keywords.Informational)]
private void WriteLogDefault(int p_EventId, string p_AssemblyName, int p_Key, string p_Message)
{
WriteEvent(p_EventId, p_AssemblyName, p_Key, p_Message);
}
Исходя из замечаний в документации по MSDN, вызов WriteEvent должен включать EventId, за которым следуют все аргументы, передаваемые вашему методу. Очевидно, что в приведенном выше коде не было никаких исключений в.NET Framework 4.5.2 или более ранней версии.
При реализации метода, который определяется как событие ETW в классе, производном от EventSource. Вы должны вызвать метод WriteEvent базового класса, передавая EventId и те же аргументы, что и реализованный метод.
Мой код теперь выглядит так и работает, как ожидалось. Удачи!
[Event(1, Message = "{2}", Level = EventLevel.Informational, Keywords = Keywords.Informational)]
public void WriteLogDefault(string p_AssemblyName, int p_Key, string p_Message)
{
WriteEvent(1, p_AssemblyName, p_Key, p_Message);
}
Параметры события должны соответствовать параметрам метода, который вы вызываете. Eventsource создает манифест на основе параметров метода.
Методы события должны точно соответствовать типам перегрузки WriteEvent, которую он вызывает, в частности, вам следует избегать неявных скалярных преобразований; они опасны, потому что манифест генерируется на основе сигнатуры метода события ETW, но значения, передаваемые в ETW, основаны на сигнатуре перегрузки WriteEvent.