System.Diagnostics.Debug namespace vs Другие решения для ведения журналов (log4net, MS Enterprise Library и т. Д.) - PullRequest
18 голосов
/ 09 июля 2010

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

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


Я был быочень благодарен, если кто-то может указать мне правильное направление или исправить (или добавить что-то) мое сравнение, данное выше!Возможно, если вы порекомендуете мне использовать сторонние организации, вы можете посоветовать какую-то конкретную (принимая во внимание, что нашим приложениям, скорее всего, не потребуются какие-то модные вещи, такие как UDP, переходящие файлы и т. Д. - просто обычный файл, электронная почта, БД иЖурнал событий)?
Заранее спасибо!

Ответы [ 4 ]

23 голосов
/ 01 октября 2010

Вы можете найти много информации о 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, к которой будут обращены ВСЕ запросы логгера, если они явно не сконфигурированы и не настроены предки. Таким образом, вы можете настроить только «корневой» регистратор для регистрации на определенном уровне, и все ваши регистраторы в вашем коде будут регистрировать на этом уровне. В качестве альтернативы, вы можете настроить «корневой» регистратор как «выключенный», а затем явно включить один или несколько регистраторов (или путем настройки предка). Таким образом, никакие регистраторы не будут регистрировать, КРОМЕ для настроенных.

Если вы посмотрите здесь , вы найдете интересную оболочку вокруг 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 вы можете, если хотите, настроить только «корневой» регистратор, и оба регистратора будут наследовать настройки корневого регистратора (уровень, appenders / target и т. Д.). В качестве альтернативы вы можете настроить регистратор для некоторого пространства имен. Любые регистраторы, тип которых определен в этом пространстве имен, наследуют эти настройки регистратора.

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

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

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

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

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

Обратите внимание, что вы не ограничены (с любой из этих платформ журналирования) использованием типа класса или имени типа для получения регистратора. Вы можете определить собственную схему именования регистратора, возможно, на основе функциональных областей («Связь», «Связь. Отправка», «Связь. Получение» и т. Д.). Опять же, вы можете запросить регистратор / 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" будут отключены.Если вы сконфигурируете и «Связь», и «Связь. Получение», то регистраторы «Связь. Получение» будут регистрироваться с настройками «Связь. Получение», а регистраторы «Связь. Отправитель» будут регистрироваться с настройками «Связь».В log4net и NLog наследование может быть чем-то большим, но я не знаю достаточно, чтобы углубиться в него.

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

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

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

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

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

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

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

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

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

0 голосов
/ 11 июня 2015

Я знаю, что это старый, но 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>
0 голосов
/ 21 февраля 2011

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

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

0 голосов
/ 09 июля 2010

С точки зрения разработчика, такие вопросы, как ведение журнала, аналогично orm, не должны быть написаны от руки. Есть много хороших сторонних библиотек. Конечно, иногда нужно немного поработать над настройкой, но сравните это с тем, что ручное развертывание - это ваши собственные решения, это просто капля в воду.

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

...