Обновление: Расширения System.Diagnostics, в которых указаны некоторые отсутствующие прослушиватели, см. В Essential.Diagnostics на CodePlex ( http://essentialdiagnostics.codeplex.com/ ).
Каркасы
Q: Какие фреймворки вы используете?
A: System.Diagnostics.TraceSource, встроенный в .NET 2.0.
Он обеспечивает мощную, гибкую и высокопроизводительную регистрацию приложений, однако многие разработчики не знают о ее возможностях и не используют их в полной мере.
В некоторых областях дополнительная функциональность полезна, или иногда функциональность существует, но недостаточно хорошо документирована, однако это не означает, что вся структура ведения журналов (которая предназначена для расширения) должна быть выброшена и полностью заменена, как некоторые популярные альтернативы. (NLog, log4net, Common.Logging и даже EntLib Logging).
Вместо того, чтобы менять способ добавления операторов регистрации в свое приложение и заново изобретать колесо, просто расширите среду System.Diagnostics в тех немногих местах, где она вам нужна.
Мне кажется, что другие фреймворки, даже EntLib, просто страдают от синдрома «Не изобретено здесь», и я думаю, что они потратили время на то, чтобы заново изобрести основы, которые уже отлично работают в System.Diagnostics (например, как вы пишете операторы журнала), вместо того, чтобы заполнить несколько пробелов, которые существуют. Короче говоря, не используйте их - они не нужны.
Особенности, которые вы, возможно, не знали:
- Использование перегрузок TraceEvent, которые принимают строку формата и аргументы, может повысить производительность, так как параметры хранятся в виде отдельных ссылок до тех пор, пока не будет выполнен Filter.ShouldTrace (). Это означает, что дорогие вызовы ToString () для значений параметров не будут выполняться до тех пор, пока система не подтвердит, что сообщение действительно будет зарегистрировано.
- Trace.CorrelationManager позволяет сопоставлять операторы журнала для одной и той же логической операции (см. Ниже).
- VisualBasic.Logging.FileLogTraceListener хорошо подходит для записи в файлы журналов и поддерживает ротацию файлов. Хотя в пространстве имен VisualBasic его можно так же легко использовать в проекте на C # (или на другом языке), просто включив DLL.
- При использовании EventLogTraceListener, если вы вызываете TraceEvent с несколькими аргументами и с пустой или пустой строкой формата, тогда аргументы передаются непосредственно в EventLog.WriteEntry (), если вы используете локализованные ресурсы сообщений.
- Инструмент Service Trace Viewer (из WCF) полезен для просмотра графиков файлов журналов, связанных с активностью (даже если вы не используете WCF). Это действительно может помочь отладить сложные проблемы, связанные с несколькими потоками / активностями.
- Избегайте накладных расходов путем очистки всех слушателей (или удаления Default); в противном случае Default будет передавать все в систему трассировки (и нести все эти накладные расходы ToString ()).
Области, на которые вы, возможно, захотите посмотреть расширение (при необходимости):
- Слушатель трассировки базы данных
- Цветная консольная трассировка слушателя
- Прослушиватели трассировки MSMQ / Email / WMI (при необходимости)
- Реализуйте FileSystemWatcher для вызова Trace.Refresh для динамических изменений конфигурации
Другие рекомендации:
Используйте идентификаторы структурированных событий и сохраняйте список ссылок (например, документируйте их в перечислении).
Наличие уникальных идентификаторов событий для каждого (значимого) события в вашей системе очень полезно для корреляции и поиска конкретных проблем. Легко отследить конкретный код, который регистрирует / использует идентификаторы событий, и может упростить предоставление рекомендаций по распространенным ошибкам, например, ошибка 5178 означает, что строка подключения к вашей базе данных неверна и т. Д.
Идентификаторы событий должны следовать некоторой структуре (аналогично теории кодов ответов, используемой в электронной почте и HTTP), что позволяет обрабатывать их по категориям, не зная конкретных кодов.
Например, первая цифра может детализировать общий класс: 1xxx может использоваться для операций «Пуск», 2xxx для нормального поведения, 3xxx для отслеживания активности, 4xxx для предупреждений, 5xxx для ошибок, 8xxx для операций «Стоп», 9xxx для фатальных ошибок, и т.п.
Вторая цифра может детализировать область, например, 21xx для информации базы данных (41xx для предупреждений базы данных, 51xx для ошибок базы данных), 22xx для режима расчета (42xx для предупреждений расчета и т. Д.), 23xx для другого модуля и т. Д.
Назначенные структурированные идентификаторы событий также позволяют использовать их в фильтрах.
Q: Если вы используете трассировку, вы используете Trace.Correlation.StartLogicalOperation?
A: Trace.CorrelationManager очень полезен для корреляции операторов журналов в любой многопоточной среде (которая в наши дни практически ничем не отличается).
Вам необходимо как минимум установить ActivityId один раз для каждой логической операции, чтобы коррелировать.
Start / Stop и LogicalOperationStack могут затем использоваться для простого стекового контекста. Для более сложных контекстов (например, асинхронных операций) использование TraceTransfer для нового ActivityId (до его изменения) позволяет корреляцию.
Инструмент Service Trace Viewer может быть полезен для просмотра графиков активности (даже если вы не используете WCF).
Q: Вы пишете этот код вручную, или вы используете какую-то форму аспектно-ориентированного программирования для этого? Хотите поделиться фрагментом кода?
A: Вы можете создать класс области видимости, например, LogicalOperationScope, который (а) устанавливает контекст при создании и (б) сбрасывает контекст при удалении.
Это позволяет вам писать код, подобный следующему, для автоматического переноса операций:
using( LogicalOperationScope operation = new LogicalOperationScope("Operation") )
{
// .. do work here
}
При создании область может сначала установить ActivityId, если необходимо, вызвать StartLogicalOperation, а затем записать сообщение TraceEventType.Start. При утилизации он может записать сообщение Stop, а затем вызвать StopLogicalOperation.
Вопрос: Предоставляете ли вы какую-либо форму детализации по источникам трассировки? Например, WPF TraceSources позволяет настраивать их на разных уровнях.
A: Да, несколько источников трассировки полезны / важны, так как системы становятся больше.
Хотя вы, вероятно, хотите последовательно регистрировать все предупреждения и выше или все сообщения информации и выше, для любой системы разумного размера объем отслеживания активности (Start, Stop и т. Д.) И подробного ведения журнала просто становится слишком большим.
Вместо того, чтобы иметь только один переключатель, который включает или выключает все это, полезно иметь возможность включать эту информацию для одного раздела вашей системы за раз.
Таким образом, вы можете обнаружить значительные проблемы из обычно регистрируемого журнала (все предупреждения, ошибки и т. Д.), А затем «увеличить» нужные разделы и установить для них «Отслеживание активности» или даже уровни отладки.
Количество необходимых источников трассировки зависит от вашего приложения, например, вам может потребоваться один источник трассировки на сборку или основной раздел вашего приложения.
Если вам нужно еще более точно настроенное управление, добавьте отдельные логические переключатели для включения / выключения определенной трассировки большого объема, например, необработанных дампов сообщений. (Или можно использовать отдельный источник трассировки, аналогичный WCF / WPF).
Возможно, вы также захотите рассмотреть отдельные источники трассировки для трассировки активности по сравнению с общими (другими) журналами, поскольку это может немного упростить настройку фильтров именно так, как вы хотите.
Обратите внимание, что сообщения все еще могут коррелироваться через ActivityId, даже если используются разные источники, поэтому используйте столько, сколько вам нужно.
Слушатели
Q: Какие выходы журнала вы используете?
Это может зависеть от того, какой тип приложения вы пишете, и какие вещи регистрируются. Обычно разные вещи идут в разных местах (например, несколько выходов).
Я обычно делю результаты на три группы:
(1) События - журнал событий Windows (и файлы трассировки)
Например, если вы пишете сервер / службу, то в Windows рекомендуется использовать журнал событий Windows (у вас нет пользовательского интерфейса для отправки отчетов).
В этом случае все фатальные события, ошибки, предупреждения и (на уровне службы) информационные события должны попадать в журнал событий Windows. Информационный уровень должен быть зарезервирован для этого типа высокоуровневых событий, которые вы хотите включить в журнал событий, например, «Служба запущена», «Служба остановлена», «Подключено к Xyz» и, возможно, даже «Запланировано инициировано» , "Пользователь вошел в систему" и т. Д.
В некоторых случаях вы можете захотеть сделать запись в журнал событий встроенной частью вашего приложения, а не через систему трассировки (т.е. записывать записи в журнал событий напрямую). Это означает, что его нельзя случайно отключить. (Обратите внимание, что вы все еще хотите отметить то же событие в вашей системе трассировки, чтобы вы могли коррелировать).
Напротив, приложение с графическим интерфейсом Windows обычно сообщает об этом пользователю (хотя они также могут регистрироваться в журнале событий Windows).
События могут также иметь связанные счетчики производительности (например, количество ошибок / сек), и может быть важно координировать любую прямую запись в журнал событий, счетчики производительности, запись в систему трассировки и отчетность для пользователя, чтобы они происходили в в то же время.
То есть, если пользователь видит сообщение об ошибке в определенное время, вы должны быть в состоянии найти то же сообщение об ошибке в журнале событий Windows, а затем то же событие с той же отметкой времени в журнале трассировки (вместе с другими деталями трассировки).
(2) Действия - файлы журнала приложений или таблица базы данных (и файлы трассировки)
Это обычное действие, выполняемое системой, например, обслуживание веб-страницы, размещение на бирже, получение ордеров, выполнение расчетов и т. Д.
Отслеживание активности (начало, остановка и т. Д.) Полезно здесь (при правильной детализации).
Кроме того, очень часто используется определенный журнал приложений (иногда называемый журналом аудита). Обычно это таблица базы данных или файл журнала приложения и содержит структурированные данные (то есть набор полей).
Здесь все может немного размыться в зависимости от вашего приложения. Хорошим примером может служить веб-сервер, который записывает каждый запрос в веб-журнал; аналогичными примерами могут быть система обмена сообщениями или система вычислений, в которой каждая операция регистрируется вместе с деталями приложения.
Не очень хорошим примером являются сделки на фондовом рынке или система заказов. В этих системах вы, вероятно, уже регистрируете действия, так как они имеют важное значение для бизнеса, однако принцип соотношения их с другими действиями все еще важен.
Помимо пользовательских журналов приложений, действия также часто имеют связанные счетчики производительности, например количество транзакций в секунду.
Как правило, вы должны координировать ведение журналов действий в разных системах, то есть записывать в журнал приложений одновременно с увеличением счетчика производительности и входом в систему трассировки. Если вы делаете все одновременно (или сразу после кода в коде), тогда проблемы отладки проще (чем если бы они все возникали в разное время / в разных местах кода).
(3) Debug Trace - текстовый файл или, возможно, XML или база данных.
Это информация на уровне Verbose и ниже (например, пользовательские логические переключатели для включения / выключения дампов необработанных данных). Это дает информацию о том, что система делает на уровне подопераций.
Это уровень, который вы хотите иметь возможность включать / выключать для отдельных разделов вашего приложения (отсюда несколько источников). Вы не хотите, чтобы эти вещи загромождали журнал событий Windows. Иногда используется база данных, но, скорее всего, это скользящие файлы журналов, которые очищаются через определенное время.
Большая разница между этой информацией и файлом журнала приложений заключается в том, что он неструктурирован. В то время как в журнале приложений могут быть поля для «Кому», «От», «Сумма» и т. Д., «Подробные трассировки отладки» могут быть такими, какие вставляет программист, например «проверка значений X = {значение}, Y = ложь» или случайные комментарии / маркеры, например « Сделано, пытаясь снова ".
Один из важных способов - убедиться, что вещи, которые вы помещаете в файлы журналов приложений или журнал событий Windows, также регистрируются в системе трассировки с такими же подробностями (например, отметка времени). Это позволяет затем сопоставлять различные журналы при расследовании.
Если вы планируете использовать определенную программу просмотра журналов из-за сложной корреляции, например, с помощью средства просмотра трассировки служб, вам необходимо использовать соответствующий формат, например XML. В противном случае простой текстовый файл обычно достаточно хорош - на нижних уровнях информация в основном неструктурирована, поэтому вы можете найти дампы массивов, дампы стека и т. Д. При условии, что вы можете сопоставить более структурированные журналы на более высоких уровнях, быть в порядке.
Q: Если вы используете файлы, вы используете скользящий журнал или только один файл? Как сделать журналы доступными для людей?
A: Для файлов, как правило, вы хотите, чтобы скользящие файлы журнала с точки зрения управляемости (с System.Diagnostics просто используйте VisualBasic.Logging.FileLogTraceListener).
Доступность снова зависит от системы. Если вы говорите только о файлах, то для сервера / службы доступ к файлам может быть получен при необходимости. (Журнал событий Windows или журналы приложений базы данных будут иметь свои собственные механизмы доступа).
Если у вас нет простого доступа к файловой системе, отладка трассировки к базе данных может быть проще. т.е. реализовать базу данных TraceListener.
Одним интересным решением, которое я увидел для приложения с графическим интерфейсом Windows, было то, что оно записывало очень подробную информацию о трассировке в «регистратор полетов» во время работы, а затем, когда вы выключали его, если у него не было проблем, он просто удалял файл.
Однако если произошел сбой или возникла проблема, файл не был удален. Либо, если он обнаружит ошибку, либо при следующем запуске он заметит файл, а затем он может предпринять действия, например сжать его (например, 7zip) и отправить по электронной почте или иным образом сделать доступным.
Многие системы в наши дни включают автоматическое сообщение о сбоях на центральный сервер (после проверки у пользователей, например, по соображениям конфиденциальности).
Просмотр
Q: Какие инструменты вы используете для просмотра журналов?
A: Если у вас есть несколько журналов по разным причинам, вы будете использовать несколько зрителей.
Notepad / vi / Notepad ++ или любой другой текстовый редактор является базовым для журналов простого текста.
Если у вас есть сложные операции, например, операции с переносами, то вы, очевидно, будете использовать специализированный инструмент, такой как Service Trace Viewer. (Но если вам это не нужно, тогда текстовый редактор проще).
Поскольку я обычно записываю информацию высокого уровня в журнал событий Windows, она обеспечивает быстрый способ структурированного обзора (ищите красивые значки ошибок / предупреждений). Вам нужно только начать поиск текстовых файлов, если в журнале недостаточно, хотя, по крайней мере, журнал дает вам отправную точку. (На этом этапе проверка того, что ваши журналы имеют скоординированные записи, становится полезной).
Обычно журнал событий Windows также делает эти важные события доступными для инструментов мониторинга, таких как MOM или OpenView.
Другие -
Если вы войдете в базу данных, может быть легко отфильтровать и отсортировать информацию (например, увеличить конкретный идентификатор активности. (С текстовыми файлами вы можете использовать Grep / PowerShell или аналогичный для фильтрации по желаемому GUID частиц)
MS Excel (или другая программа для работы с электронными таблицами). Это может быть полезно для анализа структурированной или полуструктурированной информации, если вы можете импортировать ее с правильными разделителями, чтобы разные значения помещались в разные столбцы.
Когда сервис запускается в режиме отладки / тестирования, я обычно для простоты размещаю его в консольном приложении. Мне кажется, что полезен цветной консольный регистратор (например, красный для ошибок, желтый для предупреждений и т. Д.). Вам необходимо реализовать пользовательский слушатель трассировки.
Обратите внимание, что платформа не включает в себя цветной консольный регистратор или регистратор базы данных, поэтому сейчас вам нужно написать их, если они вам нужны (это не так уж сложно).
Меня действительно раздражает, что несколько фреймворков (log4net, EntLib и т. Д.) Потратили впустую время, заново изобретая колесо и заново реализовав базовую регистрацию, фильтрацию и запись в текстовые файлы, журнал событий Windows и файлы XML, каждая в своем собственном другой способ (операторы журнала различны в каждом); затем каждый из них реализовал свою собственную версию, например, регистратора базы данных, когда большая часть этого уже существовала и все, что требовалось, - это еще пара прослушивателей трассировки для System.Diagnostics. Разговор о большой трате двойного усилия.
В: Если вы создаете решение ASP.NET, вы также используете мониторинг работоспособности ASP.NET? Включаете ли вы вывод трассировки в события монитора работоспособности? Как насчет Trace.axd?
Эти вещи могут быть включены / выключены по мере необходимости. Я нахожу Trace.axd весьма полезным для отладки того, как сервер реагирует на определенные вещи, но обычно он не полезен в интенсивно используемой среде или для долгосрочной трассировки.
Q: А как насчет пользовательских счетчиков производительности?
Для профессионального приложения, особенно сервера / службы, я ожидаю увидеть его полностью оснащенным счетчиками Performance Monitor и регистрацией в журнале событий Windows. Это стандартные инструменты в Windows, и их следует использовать.
Необходимо убедиться, что вы включили установщики для счетчиков производительности и журналов событий, которые вы используете; они должны быть созданы во время установки (при установке от имени администратора). Когда ваше приложение работает нормально, оно не должно иметь прав администратора (и поэтому не сможет создавать отсутствующие журналы).
Это хорошая причина для практики разработки без прав администратора (иметь отдельную учетную запись администратора для установки служб и т. Д.). При записи в журнал событий .NET автоматически создает отсутствующий журнал при первой записи в него; если вы развиваетесь как не администратор, вы поймете это рано и избежите неприятного удивления, когда клиент устанавливает вашу систему, а затем не может использовать ее, потому что он не работает от имени администратора.