Правильный способ использования 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 определен, а классификаторы классов не определены. В стандартном сценарии для производственной системы используется несколько регистраторов, предназначенных для группы классов. Извините за мой английский.