Подтвердить что ты не робот

Опасность пропущенных событий из регистрации ETW с помощью EventSource

Я использую приложения .NET 4.5 для генерации событий ETW с использованием класса EventSource. Цель состоит в том, чтобы зафиксировать некоторые из этих событий (события уровня ошибки) для регистрации ошибок.

После некоторого чтения и тестирования я обеспокоен надежностью такого подхода к регистрации ошибок, особенно в отношении возможности сброса или отсутствия событий. Если мой журнал ошибок не работает, мне нужно, чтобы приложение закрылось (в моем случае для него небезопасно работать с неподтвержденными ошибками). При использовании ETW и EventSource, как я могу быть уверенным, что мои ошибки правильно записываются?

Очевидно, что часть ответа будет зависеть от того, что слушает события. В моем случае я планирую использовать "Блок приложений семантического журнала" из последней библиотеки MS Enterprise.

Вот один из источников, где Microsoft говорит о возможных причинах пропущенных событий: О трассировке событий

Там перечислены эти возможные причины пропущенных событий

  • Общий размер события больше 64K. Это включает в себя заголовок ETW, а также данные или полезную нагрузку. Пользователь не имеет контроля над этими отсутствующими событиями, так как размер события сконфигурирован приложением.

  • Размер буфера ETW меньше, чем общий размер события. Пользователь не имеет контроля над этими отсутствующими событиями, так как размер события настраивается приложением, регистрирующим события.

  • Для ведения журнала в реальном времени потребитель в режиме реального времени не потребляет события достаточно быстро или вообще не присутствует, а затем заполняется файл резервной копии. Это может произойти, если служба журнала событий остановлена ​​и запущена при регистрации событий. Пользователь не имеет контроля над этими отсутствующими событиями.

  • При входе в файл диск слишком медленный, чтобы не отставать от скорости ведения журнала.

Чтобы убедиться, что эти проблемы были каким-то образом смягчены с помощью класса EventSource (например, он каким-то образом обрезает большие полезные нагрузки), я провел некоторое тестирование. Я пытался записывать длинные строки, и мне не удалось от 30 000 до 35 000 символов (прямо в соответствии с максимальной нагрузкой на 64 КБ). Он просто ничего не делает из того, что я могу сказать для слишком больших строк, никаких событий в моем блоке Block Application Application Semantic Logging. События до и после были написаны, как обычно.

Итак, в любое время, когда у меня есть строка в моей полезной нагрузке, я должен передать ее через какой-нибудь truncator? Нужно ли мне вручную избегать генерации событий "слишком быстро" (и как это возможно)?

Microsoft Patterns and Practices должны привести нас к хорошим... образцам и практикам... поэтому, возможно, я просто что-то пропустил здесь.

Update:

По-видимому, в приложении-потребителе есть какое-то уведомление о состоянии "События слишком быстро". Я получил это сегодня в первый раз:

Уровень: предупреждение, сообщение: некоторые события будут потеряны из-за переполнения буфера или задержки синхронизации схемы в сеансе трассировки: Microsoft-SemanticLogging-Etw-svcRuntime

И затем, закрывая сеанс:

Уровень: предупреждение, сообщение: потеря 1 события была обнаружена в сеансе трассировки "Microsoft-SemanticLogging-Etw-svcRuntime".

Update2:

Руководство разработчика корпоративных библиотек описывает поведение, о котором я только что упомянул.

Вы должны отслеживать сообщения журнала, сгенерированные блоком приложений семантического журнала, для любой индикации, что буферы переполнены и что вы потеряли сообщения. Например, сообщения журнала с идентификаторами событий 900 и 901 показывают, что внутренние буферы стоков переполнены; в сценарии вне процесса, идентификаторы 806 и 807 событий показывают, что буферы ETW переполнены. Вы можете изменить параметры настройки буферизации для приемников, чтобы уменьшить вероятность переполнения буферов типичными рабочими нагрузками.

Остается мой вопрос, могу ли я использовать семантическую регистрацию, пока мое приложение не запускается, если ошибки отбрасываются? Обычные события трассировки можно отбросить...

Моя текущая мысль состоит в том, чтобы записывать критические ошибки с отдельным классом с использованием старомодных методов ведения журнала и сохранять менее критические ошибки (а также события типа отладки), проходящие через конвейер ETW. Это было бы не так уж плохо... Я мог бы опубликовать это как решение, если не могу найти лучшего предложения.

Обновление 3:

Предупреждение "отсутствующих событий", которое я получил, не имеет ничего общего с переполнениями буфера, получается, что это сообщение вы получаете, если вы передаете null string в качестве значения полезной нагрузки.

4b9b3361

Ответ 1

EventSource класс поставляется в двух версиях, один из которых включен в .NET Framework, а другой в пакете NuGet Библиотека событий Microsoft EventSource. Я предполагаю, что вы используете пакет NuGet, потому что он содержит более новый код.

Конструктор базового класса EventSource имеет перегрузку, которая принимает логический аргумент throwOnEventWriteErrors со следующей документацией (пакет NuGet версии 1.0.26.0):

По умолчанию вызов методов WriteEvent НЕ выбрасывает ошибки (они молча отбрасывают событие). Это связано с тем, что в большинстве случаев пользователи предполагают, что регистрация не является "драгоценной" и НЕ хочет, чтобы сбои протоколирования вывалили из строя программу. Однако для тех приложений, где ведение журнала является "драгоценным", и если это не удается, вызывающий абонент хочет реагировать, установка "throwOnEventWriteErrors" приведет к тому, что исключение будет вызвано, если WriteEvent завершится с ошибкой. Обратите внимание, что успех EventWrite не обязательно означает, что событие достигло цели только в том случае, если операция записи не завершилась.

К сожалению, последнее предложение содержит предостерегающий emptor, но если вы посмотрите на исходный код для EventSource, вы увидите, что базовые коды возврата из вызовов ОС используются для того, чтобы вызывать разные исключения для NoFreeBuffers и EventTooBig (и другие ошибки).

Итак, если вы включите throwOnEventWriteErrors, вы получите исключения, если класс EventSource не сможет передать событие ETW. Однако, если сбой по ETW по другой причине вы не получите никакого исключения, но если вы убедитесь, что ваши ETW-каналы настроены правильно, что редко бывает когда-либо. Однако, поскольку вы не можете терпеть потерю каких-либо ошибок, вы должны, вероятно, проверить экстремальные ошибки, чтобы убедиться, что ETW ведет себя так, как вы ожидаете.

Ответ 2

Одна вещь, которая содержит два важных момента, которые не были ясны в обсуждении выше.

  • ВСЕ проблемы, связанные с событиями сбрасывания, связаны с ETW (трассировка событий для Windows), а не с EventSource. Это логично EventSOurces разговаривает с EventListeners, и есть встроенный слушатель, который пересылает ETW. Очевидно, что когда вы говорите о потерянных событиях, ограничение ЛЮБОЙ ссылки в цепочке будет влиять на данные, проходящие через цепочку. Таким образом, одним из способов гарантировать полную надежность является использование EventListener, который не использует ETW, но напрямую переходит туда, куда вы хотите, чтобы данные шли. Я считаю, что у этого (Semantic Logging Application Block) есть такой слушатель.

  • ETW успешно используется для надежного переадресации событий, но вам нужно жить в рамках ограничений, упомянутых выше (размер событий должен быть сохранен < 64K, и вы должны держать контроль за событиями под контролем Обратите внимание, что если скорость слишком велика, вы это узнаете, потому что WriteEvent завершится неудачно, поэтому вы можете повторить попытку (после паузы) и, таким образом, сделать что-то полностью надежное (за счет замедления работы программы). Обратите внимание, что этот вид потери данных - это просто не интересная проблема, если вы действительно говорите об ошибках (которые не должны происходить с огромной скоростью, и если они происходят с высокой скоростью, они, вероятно, будут избыточными (то же самое быстро срабатывает).

Итак, в результате EventSource по умолчанию поддерживает надежные события, ETW по умолчанию не поддерживает его, но может быть сделано для его поддержки, но часто значения ETW по умолчанию более чем точны.

Ответ 3

Попробуйте взглянуть на семантический журнал (MS Enterprise Library 6) http://msdn.microsoft.com/en-us/library/dn440729 ( v = pandp.60).aspx

Вы можете использовать источник событий и создать прослушиватель для записи вашего журнала в средство просмотра событий или файл или db (или создать собственное решение)

Обновление: я улавливаю событие с кодом 806/807 даже по сценарию IoC. В перехватчике существовала часть кода, который создает экземпляр класса EventSource: если вы пропустили ссылку первого экземпляра, все остальные провалились на конструкторе и активировали идентификаторы событий 806/807 при записи событий

Для регистрации больших данных можно применять теги разделения сообщений