Регистрация лучших практик [закрыто]

323

Я хотел бы получить истории о том, как люди обрабатывают отслеживание и регистрацию в реальных приложениях. Вот несколько вопросов, которые могут помочь объяснить ваш ответ.

Каркасы

Какие рамки вы используете?

  • log4net
  • System.Diagnostics.Trace
  • System.Diagnostics.TraceSource
  • Блок регистрации приложения
  • Другой?

Если вы используете трассировку, вы используете Trace.Correlation.StartLogicalOperation?

Вы пишете этот код вручную или используете какую-то форму аспектно-ориентированного программирования для этого? Хотите поделиться фрагментом кода?

Вы предоставляете какую-либо форму гранулярности по источникам следа? Например, WPF TraceSources позволяет вам настраивать их на разных уровнях:

  • System.Windows - настройки для всех WPF
  • System.Windows.Animation - переопределить специально для анимации.

Слушатели

Какие выходы журнала вы используете?

  • Текстовые файлы
  • Файлы XML
  • Журнал событий
  • Другой?

Если вы используете файлы, вы используете скользящий журнал или только один файл? Как сделать журналы доступными для людей?

Просмотр

Какие инструменты вы используете для просмотра журналов?

  • Блокнот
  • Хвостик
  • Просмотрщик событий
  • Системный центр Operations Manager / Microsoft Operations Manger
  • WCF Service Trace Viewer
  • Другой?

Если вы создаете решение ASP.NET, вы также используете мониторинг работоспособности ASP.NET? Включаете ли вы вывод трассировки в события монитора работоспособности? Как насчет Trace.axd?

А как насчет пользовательских счетчиков производительности?

Пол Стовелл
источник
3
Было бы полезно, если бы люди, закрывающие подобные вопросы с 300 ответами, могли предложить либо вики-формат, либо публикацию на programmers.stackexchange, либо Quora, если этот тип вопросов не приветствуется. Очевидно, что вопрос на самом деле очень конструктивный, он просто не соответствует критериям, которые хочет StackOverflow. programmers.stackexchange.com/questions/57064/… имеет 24 голосов. Возможно, в StackOverflow чего-то не хватает?
Найл Коннотон
Если этот вопрос нарушает формат вопросов и ответов, значит, что-то НЕПРАВИЛЬНО с форматом вопросов и ответов, а не с этим вопросом. Иногда решение о том, должен ли вопрос быть закрыт, должно зависеть от предоставленных ответов, некоторые открытые вопросы вызывают дебаты, а другие приглашают пользователей предоставить ценный контент, такой как этот!
Матиас Вольф
1
Этот вопрос - особенно самый лучший ответ - вероятно, послужил бы отличной основой для поста в блоге, если бы кто-то хотел использовать его как таковой ... Как объективный вопрос, он не совсем подходит - он явно структурирован как соломенный опрос - но Ниже приведена полезная информация, отсюда и замок.
Shog9

Ответы:

232

Обновление: Расширения 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 автоматически создает отсутствующий журнал при первой записи в него; если вы развиваетесь как не администратор, вы поймете это рано и избежите неприятного удивления, когда клиент устанавливает вашу систему, а затем не может использовать ее, потому что он не работает от имени администратора.

Хитрый Грифон
источник
К вашему сведению: я столкнулся с проблемой, из-за которой происходит сбой трассировки файла Microsoft. Если у вас есть несколько процессов (или потоков), пишущих в один и тот же файл, и они сталкиваются, вы получаете ошибку блокировки монопольного доступа к файловой системе в файле журнала.
Джей
1
Инфраструктура System.Diagnostics является поточно-ориентированной; поведение по умолчанию для блокировки платформы, однако вы можете переопределить TraceListener.IsThreadSafe, если вы предоставляете свою собственную блокировку. См. Msdn.microsoft.com/en-us/library/… . Для нескольких процессов вы обычно пишете в отдельные файлы, но учтите, что средство просмотра трассировки служб может загружать несколько файлов трассировки (например, с нескольких компьютеров) и сопоставлять их через ActivityId.
Хитрый Грифон
1
Может быть, вы можете предложить, как использовать TraceEvent () для регистрации исключений?
Дмитрий Сосунов
1
Разве это не один из главных недостатков, System.Diagnostics.Traceкоторыми он украшен, [Conditional("TRACE")]который делает его непригодным для использования в производственных средах, где у вас редко есть код, скомпилированный с TRACEфлагом?
Асбьерн Ульсберг,
2
@asbjornu Конфигурация сборки релиза по умолчанию в Visual Studio имеет TRACE (это отключение DEBUG для сборок релиза); однако, если вы делаете сборку из командной строки, вам нужно включить ее.
Хитрый Грифон
40

Я должен присоединиться к хору, рекомендующему log4net, в моем случае исходя из гибкости платформы (настольный .Net / Compact Framework, 32/64-bit).

Тем не менее, обертывание его в API под частной маркой является серьезным препятствием . log4net.ILoggerуже является .Net-аналогом API- оболочки Commons Logging , поэтому связывание для вас уже сведено к минимуму, и, поскольку это также библиотека Apache, это обычно даже не проблема, потому что вы не отказываетесь от какого-либо контроля: раскройте его, если вы должен.

Большинство библиотек домашних оболочек, которые я видел, также допускают одну или несколько ошибок:

  1. Использование глобального одноэлементного регистратора (или, что то же самое, статической точки входа), который теряет точное разрешение рекомендованного шаблона логгер-на-класс без какого-либо другого усиления селективности.
  2. Невозможность выставить необязательный Exceptionаргумент , что приводит к множеству проблем:
    • Это делает политику регистрации исключений еще более сложной в обслуживании, поэтому ничего не делается в соответствии с исключениями.
    • Даже при согласованной политике форматирование исключения в строку приводит к преждевременной потере данных. Я написал собственный ILayoutдекоратор, который выполняет детальное изучение исключения для определения цепочки событий.
  3. Невозможность выставить свойстваIsLevelEnabled , которые не позволяют пропустить форматирование кода, когда области или уровни ведения журнала отключены.
Джеффри Хантин
источник
1
Мне было поручено перестроить (ужасную) внутреннюю обертку вокруг log4j во что-то несколько менее ужасное (это все еще довольно плохо, но это результат того, что я подчинил себе требования, выдвинутые в log4j). Я пытался устранить глобальную статическую точку входа, но был сбит. Я действительно не понимаю суть. В нашей настройке log4j настолько сильно расширен и изменен, что его просто используют как диспетчер событий; мы используем его только потому, что кто-то спросил: «Как мы можем использовать log4j для этого?» Либо используйте log4whither прямо, либо просто напишите свой собственный фреймворк. Средняя дорога болезненна.
Адам Яскевич
25
Я не согласен с вашей рекомендацией не заворачивать log4net. Свернув его с тонким API модели провайдера, пользователи ваших библиотек классов могут подключить свою любимую среду ведения журналов. Конечно, YMMV, но описывать его как «главный анти-паттерн» немного догматично. Кроме того, тот факт, что существуют библиотеки-оболочки с «перечнем ошибок», не является хорошим аргументом против хорошо написанной оболочки.
Джо
1
Называть что-то антипаттерном не означает, что это всегда на 100% плохая идея - просто это создает тенденцию загнать себя в угол, если вы не будете осторожны. Кроме того, ILog / LogManager сам по себе является хорошо написанной мини-библиотекой-оберткой в ​​образе регистрации общего достояния, которая включена в сборку log4net, но нет никаких причин, по которой ее нельзя извлечь и превратить в надлежащую запись общего достояния для CLR.
Джеффри Хантин
18

Я не часто развиваюсь на asp.net, однако, когда дело доходит до регистраторов, я думаю, что многие лучшие практики универсальны. Вот некоторые из моих случайных мыслей о регистрации, которые я узнал за эти годы:

Каркасы

  • Используйте каркас абстракции регистратора - например, slf4j (или сверните свой собственный), чтобы отделить реализацию регистратора от своего API. Я видел, как приходят и уходят несколько каркасов логгеров, и вам лучше принять новую без особых хлопот.
  • Попытайтесь найти структуру, которая поддерживает множество выходных форматов.
  • Попробуйте найти структуру, которая поддерживает плагины / пользовательские фильтры.
  • Используйте структуру, которая может быть настроена с помощью внешних файлов, чтобы ваши клиенты / потребители могли легко настроить вывод журнала, чтобы его можно было легко прочитать в приложениях управления коммерческим журналом.
  • Не допускайте чрезмерных затрат на пользовательских уровнях ведения журнала, в противном случае вы не сможете перейти к другим средам ведения журнала.

Logger Output

  • Старайтесь избегать журналов в стиле XML / RSS для ведения журналов, которые могут привести к катастрофическим сбоям. Это важно, потому что если выключатель питания отключен, а регистратор не записывает закрывающий </xxx>тег, ваш журнал будет поврежден.
  • Журнал темы. В противном случае может быть очень сложно отследить поток вашей программы.
  • Если вам нужно интернационализировать ваши журналы, вы можете захотеть, чтобы разработчик входил только на английском языке (или на ваш язык по вашему выбору).
  • Иногда возможность вставлять операторы регистрации в запросы SQL может быть спасением в ситуациях отладки. Такие как:
    - Класс вызова: com.foocorp.foopackage.FooClass: 9021
    SELECT * FROM foo;
  • Вы хотите ведение журнала на уровне класса. Обычно вам также не нужны статические экземпляры регистраторов - это не стоит микрооптимизации.
  • Пометка и классификация зарегистрированных исключений иногда полезна, потому что не все исключения созданы равными. Таким образом, знание подмножества важных исключений полезно, если у вас есть монитор журналов, который должен отправлять уведомления о критических состояниях.
  • Фильтры дублирования сохранят ваше зрение и жесткий диск. Вы действительно хотите, чтобы один и тот же оператор журналирования повторялся 10 ^ 10000000 раз? Разве не было бы лучше просто получить сообщение как: This is my logging statement - Repeated 100 times

Также см. Этот мой вопрос .

Илия
источник
5
Фильтры дублирования - отличная идея
Пол Стовелл
Раньше я соглашался с проблемой сломанного тега, но большинство хороших авторов XML все равно не используют полный XML (т. е. не имеют корневого элемента), поэтому они могут регистрироваться без загрузки XML DOM. в редких случаях проблема возникает из частично записанной записи, вы можете исправить ее вручную
Пол Стовелл
Я годами возвращался к ведению журналов XML. Теперь это кажется чрезмерным для меня. Если мне нужен RSS-канал о состоянии приложения, я думаю, что это лучше реализовать с помощью утилиты мониторинга журнала.
Илия
Я согласен на RSS. Я больше думаю об инструментах визуализации, которые позволят вам лучше понять запись. с текстовыми файлами вы обычно хотите сохранить запись в одну строку; но иногда вы хотите включить следы стека или сериализованные объекты. вот где пригодится XML-журнал (используемый WCF)
Пол Стовелл
+1 за упоминание инструментария SQL-запросов. Это действительно очень полезно для корреляции трассировки базы данных и трассировки приложения. Я делаю это вручную в моем DAL, но мне интересно, какая поддержка инструмента есть для этой техники?
Константин
17

Я не обладаю достаточной квалификацией для того, чтобы комментировать ведение журнала для .Net, так как мой хлеб и масло - это Java, но за последние 8 лет мы провели миграцию в нашем ведении журнала, и вы можете найти полезную аналогию с вашим вопросом.

Мы начали с регистратора Singleton, который использовался каждым потоком в JVM, и установили уровень ведения журнала для всего процесса. Это привело к огромным журналам, если нам пришлось отлаживать даже очень специфическую часть системы, поэтому урок номер один - сегментировать ваши журналы.

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

Мы используем библиотеку Apache-Commons-Logging, обернутую вокруг Log4J.

Надеюсь это поможет!

* Редактировать *

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

Стив Мойер
источник
Спасибо за ответ. Вы создаете дочерние регистраторы вручную в коде (то есть, они жестко запрограммированы) или с помощью какой-то автоматической / неявной вещи?
Пол Стовелл
Нет ... если мы добавим конфигурацию регистрации в файлы logging.properties для пакета или класса, они будут зарегистрированы в соответствии с этой конфигурацией, но любой пакет или класс, не настроенный специально, будет зарегистрирован на уровнях по умолчанию.
Стив Мойер
9

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

Мы выбрали его по следующим причинам:

  • Простая настройка / реконфигурация в различных средах
  • Хорошее количество готовых приложений
  • Одна из используемых нами CMS уже была встроена
  • Хорошее количество уровней журнала и конфигурации вокруг них

Я должен отметить, что это говорит с точки зрения разработки ASP.NET

Я вижу некоторые преимущества в использовании Trace, который находится в .NET Framework, но я не полностью продан на нем, в основном потому, что компоненты, с которыми я работаю, на самом деле не выполняют никаких вызовов Trace. Единственное, что я часто использую, этоSystem.Net.Mail то, что я могу сказать.

Итак, у нас есть библиотека, которая оборачивает log4net, и в нашем коде нам просто нужны такие вещи:

Logger.Instance.Warn("Something to warn about");
Logger.Instance.Fatal("Something went bad!", new Exception());

try {
  var i = int.Parse("Hello World");
} catch(FormatException, ex) {
  Logger.Instance.Error(ex);
}

В методах мы проверяем, включен ли уровень ведения журнала, чтобы у вас не было избыточных вызовов API log4net (поэтому, если Debug не включен, операторы отладки игнорируются), но когда я получаю некоторое время Я буду обновлять его, чтобы разоблачить тех, чтобы вы могли сделать проверки самостоятельно. Это предотвратит проведение оценок, когда они не должны, например:

Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

Это станет:

if(Logger.DebugEnabled) Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

(Сэкономить немного времени исполнения)

По умолчанию мы регистрируем в двух местах:

  1. Файловая система сайта (в необслуживаемом расширении)
  2. Отправка электронной почты для ошибок и фатальных

Файлы делаются по дням или 10 МБ (IIRC). Мы не используем EventLog, поскольку он может требовать более высокой безопасности, чем мы часто хотим предоставить сайту.

Я считаю, что Блокнот прекрасно работает для чтения журналов.

Аарон Пауэлл
источник
Каркасы журналирования являются одним из немногих случаев, когда синглтон не является злоупотреблением.
mmcdole
Это может быть, если вы хотите предоставить контекст вокруг вашего регистратора. Но это помогает бороться с параллелизмом
Аарон Пауэлл
7
Я бы определенно вырвал синглтон. Вы, конечно, можете иметь один экземпляр, который будет передан (предпочтительно в контейнере IOC / DI). Я также попытался бы переместить вход в перехватчик ....
yfeldblum
2
Не фанат ни одного экземпляра. Я предпочитаю присваивать каждому классу уникальное имя для ведения журнала, поэтому переключение регистрации вверх или вниз для каждого модуля является простым делом.
Джеффри Хантин
8

Какие рамки вы используете?

Мы используем сочетание блока приложения ведения журнала и специального помощника по ведению журнала, который работает на основе элементов .Net. LAB настроен на вывод довольно обширных файлов журналов, включая отдельные общие файлы трассировки для входа / выхода из метода обслуживания и конкретные файлы ошибок для непредвиденных проблем. Конфигурация включает дату / время, поток, pId и т. Д. Для помощи при отладке, а также полную информацию об исключении и стек (в случае непредвиденного исключения).

Пользовательский помощник по ведению журнала использует Trace.Correlation и особенно удобен в контексте регистрации в WF. Например, у нас есть конечный автомат, который вызывает серию последовательных рабочих процессов. При каждом из этих действий вызова мы регистрируем начало (используя StartLogicalOperation), а затем в конце останавливаем логическую операцию с помощью обработчика события возврата gereric.

Это оказалось полезным несколько раз при попытке отладки сбоев в сложных бизнес-последовательностях, поскольку позволяет быстрее определять такие вещи, как решения ветвления If / Else и т. Д., На основе последовательности выполнения действий.

Какие выходы журнала вы используете?

Мы используем текстовые файлы и файлы XML. Текстовые файлы настраиваются через блок приложения, но мы также получили XML-данные от нашего сервиса WF. Это позволяет нам регистрировать события времени выполнения (постоянство и т. Д.), А также общие исключения бизнес-типов. Текстовые файлы представляют собой скользящие журналы, которые свернуты по дням и размеру (я считаю, что общий размер 1 МБ является точкой пролонгации).

Какие инструменты вы используете для просмотра журналов?

Мы используем Notepad и WCF Service Trace Viewer в зависимости от того, какую группу вывода мы рассматриваем. WCF Service Trace Viewer действительно очень удобен, если вы правильно настроили вывод и можете сделать чтение вывода намного проще. Тем не менее, если я точно знаю, где ошибка в любом случае - просто чтение хорошо аннотированного текстового файла также хорошо.

Журналы отправляются в один каталог, который затем разделяется на подкаталоги на основе исходной службы. Корневой каталог открывается через веб-сайт, доступ к которому контролируется группой поддержки пользователей. Это позволяет нам просматривать производственные журналы без необходимости помещать запросы и проходить длительные волокиты для производственных данных.

Стив Годболд
источник
6

Как авторы инструмента, мы, конечно, используем SmartInspect для регистрации и отслеживания приложений .NET. Мы обычно используем протокол именованного канала для ведения журнала в реальном времени и (зашифрованные) двоичные файлы журнала для журналов конечного пользователя. Мы используем консоль SmartInspect в качестве средства просмотра и мониторинга.

На самом деле существует довольно много каркасов и инструментов для ведения журнала .NET. На DotNetLogging.com есть обзор и сравнение различных инструментов .

Деннис Г.
источник
5

В ответах много отличных рекомендаций.

Общая лучшая практика состоит в том, чтобы рассмотреть, кто будет читать журнал. В моем случае это будет администратор на клиентском сайте. Поэтому я регистрирую сообщения, которые дают им то, на что они могут действовать. Например, «Невозможно инициализировать приложение. Обычно это вызвано ......»

Мэтью Спосато
источник
1

Мы используем log4net в наших веб-приложениях.

Возможность настраивать ведение журнала во время выполнения путем изменения XML-файла конфигурации очень удобна, когда приложение работает со сбоями во время выполнения, и вам необходимо просмотреть дополнительную информацию.

Это также позволяет вам задавать определенные классы или атрибуты для входа в систему. Это очень удобно, когда у вас есть представление о том, где происходит ошибка. Классическим примером является NHibernate, где вы хотите видеть только SQL, идущий в базу данных.

Редактировать:

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

Джеффри Кэмерон
источник
Можете ли вы предоставить более подробную информацию о том, как вы используете его? Вы входите в файл или журнал событий? Это скользящий файл журнала? Что вы делаете, чтобы защитить его или сделать резервную копию? Я заинтересован в реальном использовании.
Пол Стовелл
1

Что касается аспектно-ориентированного журналирования, мне порекомендовали PostSharp на другой вопрос SO -

Аспектно-ориентированное ведение журнала с Unity \ T4 \ что-нибудь еще

Ссылка, приведенная в ответе, стоит посетить, если вы оцениваете каркасы журналов.

Унмеш Кондоликар
источник