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

System.Diagnostics.Debug namespace vs Другие решения для ведения журнала (log4net, MS Enterprise Library и т.д.)

В настоящее время я изучаю различные возможности ведения журнала для проектов .net, и я не могу решить между функциями System.Diagnostics.Debug/Trace и сторонними библиотеками, такими как log4net, MS Enterprise Library, NLog и т.д.
На данный момент я это выяснил:

  • System.Diagnostics довольно сложно настроить и использовать, поскольку вам нужно явно настроить все слушатели, фильтры, источники и т.д. Кажется, что ему также не хватает массовой вставки в БД (подумайте о написании 100 000 журналов записи, каждая со своей Вставкой, ужасающая, не так ли?). Но некоторые люди считают "здоровыми" не использовать дополнительные библиотеки для такой "рудиментарной" вещи, как ведение журнала (конечно, в какой-то момент имеет смысл уменьшить количество сторонних библиотек, на которые опирается ваш проект, но не в этот раз, я полагаю)
  • Третьи стороны намного эффективнее, часто быстрее, гораздо проще в использовании, но конфигурация иногда может быть также болезненной, и зачастую эти библиотеки менее надежны (например, таинственная внезапная остановка ведения журнала EntLib и т.д.).
  • как насчет Common.Logging? стоит ли пытаться (поскольку, как я слышал, он предлагает подключать различные фреймворки регистрации и действовать как интерфейс между приложением и желаемой библиотекой)?


Я был бы очень благодарен, если бы кто-нибудь мог указать мне в правильном направлении или исправить (или добавить что-то) на мое сравнение, данное выше! Может быть, если вы побудите меня использовать третьи стороны, вы можете посоветовать какой-то конкретный (учитывая, что нашим приложениям, скорее всего, не понадобятся какие-либо причудливые вещи, такие как UDP, скользящие файлы и т.д. - простой файл, электронная почта, DB и Журнал событий)?
Спасибо заранее!

4b9b3361

Ответ 1

Вы можете найти много информации о log4net и NLog, либо здесь, в StackOverflow, в более общем виде в Google.

Вы также можете найти много информации о System.Diagnostics. Одно дело отметить System.Diagnostics, я думаю, что вы найдете здесь много ссылок на StackOverflow об использовании Debug.Write/WriteLine и Trace.Write/WriteLine. Вероятно, "лучший" способ - использовать TraceSources. TraceSources аналогичны регистраторам в log4net и NLog. TraceSources позволяет вам иметь более высокую степень детализации для ваших сообщений о протоколировании, что упрощает включение некоторых протоколов и некоторых отключений (по классу или категории, в дополнение к уровню). У TraceSources есть недостаток, по сравнению с log4net и NLog, в том, что каждый TraceSource, который вы создаете в своем коде, должен быть явно настроен в app.config(если вы хотите, чтобы он действительно регистрировался).

log4net и NLog имеют иерархическую концепцию, где, если точный регистратор, который вы просили, явно не настроен, его "предка" проверяется, чтобы проверить, настроены ли какие-либо "предки", и если да, то запрашиваемый регистратор "наследует" те настройки. Предки - это просто части имени регистратора, разделенные символом ".". (Итак, если вы запросите логгер под названием "ABC.DEF.GHI", предки будут "ABC.DEF" и "ABC"). Также возможно (требуется?) Иметь "корневую" конфигурацию регистратора в app.config, что ВСЕ запросы регистратора будут возвращаться, если они явно не настроены и не настроены никакие предки. Таким образом, вы можете настроить только "корневой" регистратор для входа на определенный уровень, и все ваши регистраторы в вашем коде будут регистрироваться на этом уровне. Кроме того, вы можете настроить "корневой" регистратор "выключен", а затем включить одного или нескольких регистраторов явно (или путем настройки предка). Таким образом, NO loggers будут записывать EXCEPT для настроенных.

Если вы посмотрите здесь, вы найдете интересную оболочку вокруг System.Diagnostics TraceSources, которая обеспечивает возможность наследования, очень похожую на log4net и NLog.

Чтобы проиллюстрировать:

Общий шаблон использования для журналов в log4net и NLog - это получение регистратора следующим образом:

//log4net
static ILog logger = LogManager.GetLogger(
                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

//NLog
static Logger logger = LogManager.GetCurrentClassLogger();

В обоих случаях имя регистратора будет полным именем типа.

В файле app.config вы можете, если хотите, настроить только "корневой" регистратор, и оба регистратора наследуют настройки корневого регистратора (уровень, добавление/цели и т.д.). В качестве альтернативы вы можете настроить регистратор для некоторого пространства имен. Любые регистраторы, тип которых определен в этом пространстве имен, наследуют эти настройки регистратора.

Достаточно log4net и NLog, вы, вероятно, уже знаете, как они работают.

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

static TraceSource ts = new TraceSource(
               System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

С оберткой, связанной выше, вы можете настроить TraceSource на более высоком уровне (иерархия класса/пространства имен, а не уровень) и наследовать эти настройки в регистраторах более низкого уровня.

Итак, если ваше полное имя типа похоже на это: ABC.DEF.GHI, то вы можете настроить TraceSource для ABC или ABC.DEF(уровень пространства имен), а класс "GHI" наследует настройки. Это может действительно уменьшить объем конфигурации, которую вы должны выполнить.

Обратите внимание, что вы не ограничены (с любой из этих платформ ведения журналов), чтобы использовать тип класса или имя типа, чтобы получить регистратор. Вы можете определить свою собственную схему именования логов, возможно, исходя из функциональных областей ( "Общение", "Коммуникация.Создание", "Коммуникация.Прием" и т.д.). Опять же, вы можете запросить logger/TraceSource с наивысшей степенью гранулярности (или нет), а затем настроить любой уровень детализации.

Итак, вы можете запросить регистраторы в своем коде следующим образом:

ILog logger = LogManager.GetLogger("Communication.Receive");
ILog logger = LogManager.GetLogger("Communication.Send");

Logger logger = LogManager.GetLogger("Communication.Receive");
Logger logger = LogManager.GetLogger("Communication.Send");

TraceSource ts = new TraceSource("Communication.Receive");
TraceSource ts = new TraceSource("Communication.Send");

Если вы сконфигурируете только "Связь" в вашем файле app.config, то все регистраторы наследуют эти настройки (поскольку они являются потомками "Связь" ). Если вы настроите только "Commuincation.Receive", тогда регистрируются только регистраторы "Communication.Receive" . Журналы "Communication.Send" будут отключены. Если вы настроите как "Связь", так и "Commuincation.Receive", регистраторы "Communication.Receive" будут регистрироваться в настройках "Communication.Receive" , в то время как регистраторы "Communication.Sender" будут регистрироваться в настройках "Связь". В log4net и NLog может быть больше наследования, чем это, но я недостаточно знаю, чтобы войти в него.

Одна вещь, которую вы пропустите при использовании System.Diagnostics - это гибкость в форматировании формата вывода журнала очень легко. Существует сторонняя библиотека, которая обеспечивает очень приятное настраиваемое форматирование для ведения журнала на основе TraceSource. Вы можете найти здесь здесь.

Я использовал Common.Logging some. В основном в прототипировании, но я мог бы использовать его в нашем следующем проекте. Он работает очень хорошо, и относительно легко написать собственную абстракцию регистрации, чтобы подключиться к ней (например, если вы хотите написать абстракцию TraceSource, аналогичную тому, что я связал выше). Две важные вещи, которые отсутствуют в Common.Logging прямо сейчас (хотя их веб-сайт говорит, что они запланированы для "следующей" версии) являются протоколированием контекстов (например, объекты log4net и NLog NDC/MDC/GDC и System.Diagnostics.CorrelationManger.LogicalOperationStack ) и Silverlight. Вы все еще можете взаимодействовать с объектами контекста log4net или NLog в своем коде при использовании Common.Logging, но этот вид поражает его цель, не так ли.

Я не знаю, помог ли я или нет!

Вот некоторые основные моменты, которые я хотел бы сделать о log4net, NLog и TraceSource:

log4net - очень популярный, возможно, нуждается в некоторых обновлениях - по крайней мере, он был создан на .NET 4.0, последний выпуск несколько лет назад, очень гибкий.

NLog - во многом похож на log4net, теперь появилась новая версия (только бета-версия NLog 2.0)

TraceSource - нет зависимости от третьей стороны, без каких-либо усилий с вашей стороны (или кого-то) не так сильно, как log4net или NLog (недостатки ключа - иерархия журналов, форматирование вывода - как легко адресуемые через ссылки выше), Microsoft использует множество их компонентов с System.Diagnostics, чтобы вы могли получить вывод журнала Microsoft и ваш выход в журнал с чередованием. (Как правило, достаточно легко фиксировать System.Diagnostics в других системах ведения журнала, поэтому это может не быть огромной проблемой).

Пока я не использовал ни log4net, ни NLog, между ними я склонялся к NLog, главным образом из-за новой версии, которая только что вышла (бета). Я думаю, что TraceSource также является разумным, если более рудиментарным, выбором, особенно если вы реализуете иерархию регистратора и используете Libadc.Diagnostics libary, связанную выше.

Или используйте Common.Logging, и вы можете избежать или отложить принятие решения для своей основной платформы регистрации до тех пор, пока вы не будете готовы. Один очень полезный аспект Common.Logging, во всяком случае, заключается в том, что вы можете "тестировать" логинговые платформы при разработке своего продукта, не изменяя при этом какой-либо код вашего приложения. Вам не нужно ждать, пока вы решите на определенной платформе регистрации, чтобы добавить регистрацию в свой код. Добавьте его сейчас через Common.Logging api. Когда вы приближаетесь к доставке, вы должны сузить выбор своей платформы регистрации. Доставьте с этой платформой (если вы перераспределите платформу регистрации), и все готово. Вы можете поменять позже, если хотите.

Ответ 2

Я знаю, что это устарело, но System.Diagnostics.Trace довольно легко настроить, если вы сохраните его просто. Я использую простой блок конфигурации текстового сценария в течение многих лет, скопированный прямо из документов MSDN.

Никто не упоминает об этом очень часто, но в вашем коде вы можете использовать встроенную Trace.TraceInformation, Trace.TraceWarning и Trace.TraceError, чтобы легко отделить 3 уровня вывода трассировки и затем в файле конфигурации выберите, какой уровень вывести (см. ниже). Если вы выберете "Информация" в конфиге "EventTypeFilter", вы получите все 3 в своем выходе. Если вы выберете "Ошибка", вы получите только сообщения TraceError в своем выпуске. В большинстве случаев, я просто оставляю свой на Error, поэтому, если что-то происходит в моем приложении, у меня уже будет этот вывод в файле трассировки. Внутри блоков Catch я добавлю код TraceError для вывода полезной информации. TraceInformation хорош для вывода таких вещей, как синхронизация или пятна в коде, который вы прошли, и сброс значений переменных на этом пути. TraceWarning хорош для вещей, которые обрабатываются, но не желательны - например, возможно, веб-служба занимает много времени, или количество возвращаемых записей данных превышает порог, который может вызвать будущие проблемы.

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

<system.diagnostics>
  <sharedListeners>
    <add name="MyTraceListener" traceOutputOptions="DateTime" type="System.Diagnostics.TextWriterTraceListener, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" initializeData="MyApplicationName_Trace.log">
     <!--
        Off - Does not allow any events through. 
        Error - Allows Error events through. 
        Warning - Allows Error, and Warning events through. 
        Information - Allows Error, Warning, and Information events through. 
     -->
     <filter type="System.Diagnostics.EventTypeFilter" initializeData="Error" />
    </add>
  </sharedListeners>
  <trace autoflush="true" indentsize="4">
    <listeners>
       <add name="MyTraceListener" />
    </listeners>
  </trace>
</system.diagnostics>

Ответ 3

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

Мои личные предпочтения - log4net, но это зависит от ваших потребностей. Мой лучший совет - посмотреть документацию на такие решения, как log4net или EntLib Logging Application Block, и принять решение о том, что лучше для вас.

Ответ 4

Ведение журнала и отслеживание - это разные проблемы. Ведение журнала относится к оперативной обратной связи. Трассировка (в том числе предоставляемая методами Debug) относится к разработке и тестированию. Код трассировки не должен компилироваться в сборку выпуска. Классы Trace и Debug достигают этого с помощью аннотаций компилятора (ConditionalAttribute). Такой код должен быть оптимизирован для сбора большого количества данных, а не для производительности. С другой стороны, оперативное ведение журнала должно быть оптимизировано для производительности и для более широкого круга механизмов хранения, как того требует команда sysadmin/operations.

Поэтому я рекомендую использовать как Trace/Debug для разработки, так и более надежные пакеты ведения журналов для операций.