Риск пропущенных событий при ведении журнала ETW с EventSource

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

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

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

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

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

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

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

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

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

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

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

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

Обновить:

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

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

А потом при закрытии сессии:

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

Update2:

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

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

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

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

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

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

3 ответа

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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