Правильный способ использования log4net (именования журнала)
Существует два способа настройки и использования log4net. Во-первых, когда я могу настроить свой собственный appender и связанный с ним журнал:
<!-- language: xml -->
<appender name="myLogAppender" type="log4net.Appender.RollingFileAppender" >
<file value="Logs\myLog.log" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level - %message%n" />
</layout>
</appender>
<logger name="myLog">
<level value="All"></level>
<appender-ref ref="myLogAppender" />
</logger>
И затем, когда я хочу что-то написать в журнале, я могу сделать следующее:
ILog log = LogManager.GetLogger("myLog");
log.Info("message");
Другой способ использовать это - настроить root так, как я хочу:
<!-- language: xml -->
<root>
<level value="Error" />
<appender-ref ref="myLogAppender" />
</root>
И в этом случае я могу записывать такие сообщения:
ILog log = LogManager.GetLogger(typeof(Bar));
log.Info("message");
Преимущества второго подхода заключаются в том, что вы можете включать или отключать некоторые сообщения "на лету". Но проблема в том, что я развиваюсь на EPiServer CMS и у нее есть своя система ведения журнала, которая использует log4net, и если я включу ведение информации на уровне root, тогда будет записано множество системных журналов.
Как вы используете log4net? Каждая часть системы записывает в свой собственный журнал, или все записывается в регистратор по умолчанию, а конфигурация решает, что делать дальше?
Ответы
Ответ 1
Относительно того, как вы регистрируете сообщения внутри кода, я бы выбрал второй подход:
ILog log = LogManager.GetLogger(typeof(Bar));
log.Info("message");
Если сообщения, отправленные в журнал выше, будут "именоваться" с использованием полностью квалифицированного типа Bar
, например.
MyNamespace.Foo.Bar [INFO] message
Преимущество этого подхода в том, что он является де-факто стандартом для организации ведения журнала, а также позволяет фильтровать ваши сообщения журнала по пространству имен. Например, вы можете указать, что хотите регистрировать сообщение уровня INFO, но повышаете уровень ведения журнала для Bar
специально для DEBUG:
<log4net>
<!-- appenders go here -->
<root>
<level value="INFO" />
<appender-ref ref="myLogAppender" />
</root>
<logger name="MyNamespace.Foo.Bar">
<level value="DEBUG" />
</logger>
</log4net>
Возможность фильтровать ваш журнал по имени является мощной функцией log4net, если вы просто регистрируете все свои сообщения до "myLog"
, вы теряете большую часть этой мощности!
Что касается EPiServer CMS, вы можете использовать вышеупомянутый подход, чтобы указать другой уровень ведения журнала для CMS и вашего собственного кода.
Для дальнейшего чтения здесь приведена статья кодекса, которую я написал в журнале:
Ответ 2
Мой ответ может задерживаться, но я думаю, что он может помочь новичкам. Вы не должны выполнять записи, если изменения не выполняются, как показано ниже.
2 При реализации Log4net файлы должны быть изменены.
- Добавить ссылку log2net.dll в проект.
- app.config
- Файл класса, в котором будут выполняться журналы.
Внутри [app.config]:
Во-первых, в разделе "configSections" вам нужно добавить ниже фрагмент кода;
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
Затем в блоке "configuration" вы должны написать ниже фрагмент кода. (Этот фрагмент кода настроен в соответствии с моей потребностью, но он работает как шарм.)
<log4net debug="true">
<logger name="log">
<level value="All"></level>
<appender-ref ref="RollingLogFileAppender" />
</logger>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log.txt" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<maxSizeRollBackups value="1" />
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %C.%M [%line] %-5level - %message %newline %exception %newline" />
</layout>
</appender>
</log4net>
Внутренний класс вызова:
Внутри класса, в котором вы собираетесь использовать этот log4net, вам нужно объявить ниже фрагмент кода.
ILog log = LogManager.GetLogger("log");
Теперь вы готовы к журналу вызовов, где хотите, в том же классе. Ниже приведен один из методов, которые вы можете вызывать при выполнении операций.
log.Error("message");
Ответ 3
Вместо того, чтобы называть мой вызывающий класс, я начал использовать следующее:
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
Таким образом, я могу использовать одну и ту же строку кода в каждом классе, который использует log4net, не забывая изменять код при копировании и вставке.
В качестве альтернативы, я мог бы создать класс ведения журнала и унаследовать каждый класс от моего класса ведения журнала.
Ответ 4
Недостатком второго подхода является большой репозиторий с созданными регистраторами. Эти регистраторы делают то же самое, если root определен, а классификаторы классов не определены. В стандартном сценарии для производственной системы используется несколько регистраторов, предназначенных для группы классов. Извините за мой английский.