- Гибкая настройка лога.
- Широкие возможности.
- Наличие конфигурационных xml-файлов с xsd-схемами.
- Готовое стабильное решение (экономия времени на отладке).
- Наличие документации (форумов, блогов).
На вой взгляд, NLog кажется более простым в конфигурировании(log4net) и менее требователен к ресурсам(Logging Application Block) при том, что он выполняет те же задачи, поэтому именно ему я и отдаю предпочтение. Начать работу с NLog действительно очень просто, ведь для этого от Вас требуется только понимание основных принципов NLog, а именно в правильном конфигурировании двух основных частей: targets и rules и в выборе оптимального уровня логирования.
Рассмотрим подробнее, каждое сообщение имеет уровень логирования(log level), в лог заноситься только то сообщение, уровень логирования которого ниже указанного в правиле логирования. NLog поддерживает следующие уровни:
- Trace - детальное логирование (все сообщения)
- Debug - отладочное логирование, менее детально чем Trace
- Info - логирование информационных сообщений
- Warn - логирование сообщений о предупреждениях
- Error - логирование сообщений об ошибках
- Fatal - логирование сообщений о критических ошибках(только критические сообщения)
- Off - логирование сообщений не производиться
Рассмотрим простой пример, допустим, нам надо осуществлять логирование следующим образом: сообщения уровня Debug выводить на консоль, а сообщения уровня Trace (все сообщения) выводить в файл. При этом, в лог должно записываться: время сообщения (а в случае записи в файл еще текущую дату), уровень сообщения и само сообщение.
Для того чтобы начать работу с NLog необходимо скачать с сайта последний дистрибутив и установить его на жесткий диск. После чего, можно приступать к созданию нового проекта NLogExample, в котором надо добавить ссылку на библиотеку NLog.dll. Как и любая система, NLog нуждается в настройке, для этого добавим в проект файл конфигурации NLog.config, задав файлу опцию "Copy to Output Directory" (это нужно для того, чтобы файл NLog.config при спорке проекта автоматически перемещался в выходную директорию): <?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <targets> <target name="console" xsi:type="Console" layout="${date:format=HH\:mm\:ss}|${level}|${message}" /> <target name="file" xsi:type="File" fileName="${basedir}/nlog.txt" layout="${date}|${level}|${message}" /> </targets> <rules> <logger name="*" minlevel="Debug" writeTo="console" /> <logger name="*" minlevel="Trace" writeTo="file" /> </rules> </nlog> Logger logger = LogManager.GetCurrentClassLogger(); using System; using NLog; namespace NLogExample { class Program { private static Logger logger = LogManager.GetCurrentClassLogger(); static void Main(string[] args) { logger.Trace("logger.Trace"); logger.Debug("logger.Debug"); logger.Info("logger.Info"); logger.Warn("logger.Warn"); logger.Error("logger.Error"); logger.Fatal("logger.Fatal"); } } }
Наш логгер настроен, и мы можем начать его использовать, для этого необходимо получить на него ссылку, это делается следующим образом:
Полученный нами экземпляр логгера содержит все необходимые методы (Trace, Debug, Info, Warn, Error, Fatal, и другие) для записи сообщения в лог. Каждый такой метод задает уровень логирования для сообщения. Поэтому если мы хотим записать в лог сообщение типа Info, мы должны использовать одноименный метод:
В итоге, если запустить приложение, на консоли мы увидим сообщения Debug, Info, Warn, Error, Fatal, а в файле(расположенного в том же каталоге где и сборка) еще и Trace сообщения.
UPD: Смотрим логи. NLogViewer
UPD: Настройка логов на примере NLog
Проблема в том что при реализации функции записи в лог очень быстро можно получить загромождение основной логики приложения.
ОтветитьУдалить@BayburinMarat
ОтветитьУдалитьЕсли код нуждается в логе, то тут ничего не поделаешь. Разумеется, вести лог надо там, где это действительно нужно и в разумных пределах.
буквально вчера настраивал log4net и заметил удивительное сходство с NLog в плане xml настроек - если заменить "target" на "appender" и "rules" на "root" - то получится файл настроек log4net. Так в чем же тогда преимущество NLog?
ОтветитьУдалить@Артём
ОтветитьУдалитьУдобство и простота NLog.
Интеграция с Visual Studio 2002/2005/2008/2010.
Дистрибутив NLog можно скачать в виде инсталл-файла, с возможностью гибкой инсталляции. Да и конфигурация NLog будет попроще. А сайт NLog(http://nlog-project.org) мне показался удобнее, чем у log4net.
Кстати, вот еще сравнение:
http://www.dotnetlogging.com/comparison/
Да, сравнение показывает, что возможности NLog и Log4Net примерно одинаковы, но вот когда я зашел на официальный сайт NLog, залез в документацию и поглядел все доступные классы в пространстве имен
ОтветитьУдалитьNLog.Targets - был приятно удивлен разнообразием возможностей. Тут тебе и запись в базу, и в файл, и вызов сервиса, и EventLog, да что там говорить - даже вывод в MessageBox есть! Но вот telnet я не нашел, а в log4net он есть (хотя не представляю нужность этой опции). В общем, для себя я решил - опишу общий интерфейс для логирования, а экземпляр логера буду создавать через spring (ну, или через подобную библиотеку) - это позволит уменьшить связность модулей (что характерно для DI (или IoC)) и реализовать любые логеры, которые мне будет удобно использовать. В случае, если мне срочно понадобится использовать NLog вместо log4net - просто подключу библиотеку и кое что поменяю в настройках spring.
@Артём
ОтветитьУдалитьДа, как вариант можно и так. Или смотрите, например, если Вы используете log4net, вы можете для него написать собственный Appender, который будет логировать в NLog. Получается следующая схема: Вы логируете в log4net, тот используя ваш Appender, который будет перенаправлять вывод в NLog.
Дело в том, что в Вашем варианте у меня будут одновременно использоваться оба логера - что негативно скажется и на используемой памяти, и на быстродействии. К тому же, если я захочу использовать другой инструмент логирования или написать свой - то мне придется менять код системы везде, где использую log4net или снова писать аппендеры - а я слишком ленив для этого ;)
ОтветитьУдалитьА мне все ж по душе System.Diagnostics - там более чем достаточно средств для логирования, нет проблем написать обвязку для более сложного логирования, нет проблем дописать провайдер для логирования ("источник"). И не нужно ничего никуда встраивать - решение из разряда: "сел и поехал". Сначала было тяжеловато настраивать, но когда приноровился - стало даже очень удобно. И настройкки все в *.config, а не х.з. где.
ОтветитьУдалитьКстати, большенство серьезных продутов от MS использует именно эту методику логирования.
Кстати, не знаю как на счет остальных логеров, а вот методы логирования Debug не вставляются физически в код релизных сборок, что правильно. Хочешь отлаживать - отлаживай, все пишется; продакшен - там только методы Trace работают.
Я же не спорю с тобой, какой инструмент логирования лучше - я просто хочу сказать, что удобней использовать не конкретный класс логгера, а самописный интерфейс. Тогда ты можешь написать адаптер к этому интерфейсу для любого инструмента логирования, а экземпляр логгера получать через DI фреймворк - в этом случае, системе будет по барабану, какой логер - log4net, nlog, да хоть самописный и настройки для этих логгеров можешь получать как угодно - всё это не повлияет никаким макаром на основную логику системы.
ОтветитьУдалить@Артём
ОтветитьУдалитьДа идея написать собственный интерфейс и реализацию интересная.
Я помню давно делал нечто подобное, а именно возможность переключения между DI фреймворками (общий интерфейс IDependencyResolver для Unity, Ninject и прочих). Скажу честно, это не так легко как кажется. Наверное некоторые вещи надо выбирать сразу и навсегда :), например, выбор конкретного DI фреймворка или логгера. Хотя логгер не сравним с DI.
Здравствуйте Илья. Спасибо за обзор, очень кстати. С логгированием более менее ясно, а как быть с выводом содержимого лога пользователю? Есть ли готовые решения, в частности для NLog?
ОтветитьУдалить@Dmitry Ilin
ОтветитьУдалитьСпасибо.
Да есть такое, особенно среди платных :).
Ключевые слова "log viewer", "log analyzer" и прочие. Но они не зависят от системы логирования, будь это NLog или log4net и прочие, так как по логу трудно будет сказать какой системой логирования его создали.
@Dmitry Ilin
ОтветитьУдалитьМожно попробовать вот это:
http://svn.nlog-project.org/repos/nlog/trunk/NLogViewer/
Спасибо за наводку, посмотрю на досуге ;)
ОтветитьУдалитьДело вкуса. Для меня log4net не плох и не так сложен.
ОтветитьУдалитьДля тех кто использует NLog в своих проектах, я на днях написал статью про NLogViewer.
ОтветитьУдалитьhttp://www.handcode.ru/2010/04/nlogviewer.html
Подскажите, пожалуйста, как передавать свои параметры в NLog? К примеру, мне нужно занести некую информацию в "Host Name", "User Name" и т.д.
ОтветитьУдалитьhttp://nlog-project.org/wiki/Event-context_layout_renderer
ОтветитьУдалитьСпасибо, но не совсем то. Мне нужно в UserName передать данные. А если я просто item использую - не то. Кроме того, в этом способе мне придётся в каждом вызове "логгера" писать:
УдалитьLogEventInfo theEvent = new LogEventInfo(LogLevel.Debug, "", "Pass my custom value");
theEvent.Properties["MyValue"] = "My custom string";
Program.logger.Log(theEvent);
В log4net я раз указал параметры и они автоматически дописывались к каждой строке в лог-файле. А тут у меня получаются 2 разные строки:
в первой у меня выводится информация, нужная мне (хотя и не совсем то), а во второй - нет... :(
Написано не информативно.
ОтветитьУдалитьLogger.Trace("Got error:" + resp.StatusCode.ToString() + " getting from URI " + URI.ToString(), "HTTP",Logtype.Error); ошибка выходит в третьем параметре ошибка
ОтветитьУдалитькак исправить
ОтветитьУдалить