пятница, 6 ноября 2015 г.

Пример использования Log4Net

Для записи лога на C# очень популярна библиотека Log4Net - logging.apache.org/log4net/. В это заметке размещу пример использования и настройки данной библиотеки. Использую её практически во всех своих проектах.

Подключение библиотеки к проекту

Подключить библиотеку несколькими способами, вот 2 из них:
Для подключения через NuGet необходимо правой кнопкой нажать References проекта и выбрать Manage NuGet packages выбрать Online в нем выбрать nuget.org в окне поиска ввести log4net в результатах поиска выбрать log4net [номер версии] и нажать install. Подробнее про NuGet можно прочитать здесь: http://andrey.moveax.ru/page/using-nuget и на оф сайте http://www.nuget.org/
Для скачивания с сайта необходимо перейти по ссылке http://logging.apache.org/log4net/download_log4net.cgi скачиваем библиотеку из секции Binaries в архиве библиотеку, в архиве содержаться библиотеки для разных версий платформы Net, а также документация. В секции Source на сайте лежат исходные тексты log4net и примеры использования. После того ка скачали файл log4net-1.2.13-src.zip или более свежую версию, её необходимо разархивировать. Теперь подключим библиотеку к проекту. Для этого правой кнопкой на References проекта, там выбираем Add Reference... выбираем Browse нажимаем кнопку Browse... находим куда разархивировали скачанный файл и подключаем библиотеку нужной версии.

Настройка библиотеки

Настройка log4net может осуществляться как и внутри фала App.config, так и отдельном файле например в файле Test.exe.log4net, где Test меняется на название приложения или Web.config для web приложений.

Настройка внутри App.config или Web.config

В файле App.config или Web.config в самое начало после открытого тега <configuration> вставляем следующий текст
<configSections>
  <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
Эта настройка указывает, что настройки для log4net находятся в секции "log4net". "log4net.Config.Log4NetConfigurationSectionHandler, log4net" - указывает чем будет разбираться этот файл.

Далее вставляем основные настройки логера

   <log4net>
      <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
        <param name="File" value="AllLog.log"/>
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <appendToFile value="true" />
        <rollingStyle value="Size" />
        <maxSizeRollBackups value="2" />
        <maximumFileSize value="10MB" />
        <staticLogFileName value="true" />
        <layout type="log4net.Layout.PatternLayout">
          <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
        </layout>
      </appender>

      <root>
        <level value="ALL" />
        <appender-ref ref="LogFileAppender" />
      </root>   
    </log4net>
Дам краткое описание параметров

appender - описывает куда будет выводится лог, в данном случае вывод происходит в перезаписываемый файл - log4net.Appender.RollingFileAppender. Подробнее о видах записи лога в http://logging.apache.org/log4net/release/sdk/log4net.Appender.html.

param name="File" - указывает на расположение и название файла куда будут писаться лог, в данном случае это "AllLog.log". Если лог писать в отдельную папку то "log\AllLog.log".

lockingModel - модель блокировки файла лога. В нашем случае "log4net.Appender.FileAppender+MinimalLock" это означает что лог будет открываться для каждой операции записи с минимальным временем удержанием файла. Подробнее  http://logging.apache.org/log4net/release/sdk/log4net.Appender.FileAppender.LockingModel.html. Вот еще вариант логирования из потоков http://habrahabr.ru/post/113663/.

appendToFile - Если значение False, то файл будет перезаписан, если True то лог будет добавлен в файл. По умолчанию верно. Подробнее  http://logging.apache.org/log4net/release/sdk/log4net.Appender.FileAppender.AppendToFile.html

rollingStyle - по какому параметру перезаписывать файл по размеру или по дате. В нашем случае по размеру "Size". Подробнее  http://logging.apache.org/log4net/release/sdk/log4net.Appender.RollingFileAppender.RollingStyle.html

maxSizeRollBackups - максимальное число файлов бэкапов лога. Подробнее  http://logging.apache.org/log4net/release/sdk/log4net.Appender.RollingFileAppender.MaxSizeRollBackups.html

maximumFileSize - максимальный файл лога. Подробнее http://logging.apache.org/log4net/release/sdk/log4net.Appender.RollingFileAppender.MaximumFileSize.html

staticLogFileName - Записывать лог все время в этот файл, можно установить дату в имя файла или еще какие нибудь параметры. Подробнее http://logging.apache.org/log4net/release/sdk/log4net.Appender.RollingFileAppender.StaticLogFileName.html

level value - уровень записи лога. В нашем случае пишутся все сообщения "ALL". Подробнее
http://logging.apache.org/log4net/release/sdk/log4net.Core.Level.html

Примеры настроек http://logging.apache.org/log4net/release/config-examples.html

Настройка в отдельном файле

Лучше настройки лога размещать в отдельном файле. Файл с настройками назвать лучше так Test.exe.log4net, где Test меняется на название приложения в сам файл записываем следующий текст.

<log4net>
 <appender name="TestLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value=".\log\log.log" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <filter type="log4net.Filter.LevelRangeFilter">
      <acceptOnMatch value="true" />
      <levelMin value="DEBUG" />
      <levelMax value="FATAL" />
    </filter>
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="10MB" />
    <staticLogFileName value="true" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%newline%date [%thread] %-5level - %message" />
    </layout>
  </appender>
  <root>
    <level value="ALL" />
    <appender-ref ref="TestLogFileAppender" />
  </root>
</log4net>

Настройки аналогичны размещенным в файле App.config. Добавился тег filter.

filter - фильтрует какие сообщения куда писать. Подробнее http://logging.apache.org/log4net/release/sdk/log4net.Filter.LevelRangeFilter.html, вопросы использования http://stackoverflow.com/questions/538095/how-do-i-filter-on-a-custom-level-in-log4net/538138.

Файл с настройками ищется относительно exe файла приложения, поэтому должен размещаться в папках сборки проекта Debug или Release. 
Так же можно настроить чтобы в App.config была ссылка на файл с настройками, для этого в файл App.config после закрытия тега </configSections> вставить такой текст
<log4net configSource=".\Config\Log4Net.config"/>

Чтение параметров для библиотеки из программы

Перед использованием log4net в программе необходимо прочитать параметры, которые описали в файле настроек. Есть два варианта: запускать чтение настроек при старте программы и запись команды в Assembly атрибуты.

Чтение при запуске программы


Для запуска чтения настроек при запуске программы wpf откроем файл App.xaml.cs и в классе App переопределим метод OnStartup.
protected override void OnStartup(StartupEventArgs e)
{
  base.OnStartup(e);

  //log4net.Config.XmlConfigurator.Configure();//если настройки прописаны в App.config

  log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(@"BuilderCrossingSeams.exe.log4net"));//Если файл с настройками в папке с exe файлом

  //log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(@".\Config\BuilderCrossingSeams.exe.log4net"));//Если файл с настройками лежит в папке конфигураций config
}

Чтение в Assembly атрибутах

Для чтения в Assembly нужно открыть файл Assembly.cs и добавить одну из строк

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "config\\BuilderCrossingSeams.exe.log4net", Watch = true)]//Если файл с настройками лежит в папке config

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "BuilderCrossingSeams.exe.log4net", Watch = true)]//если файл настроек лежит в папке с exe

[assembly: log4net.Config.XmlConfigurator()]//если настройки нужно брать из App.config

Реализация доступа к записи в лог

Рассмотрим два метода внедрения объекта лога в проект.

Статическое свойство

В каждом классе приложения можно реализовать приватное поле типа ILog и инициализировать его при объявлении.


private readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

Тогда внутри класса его можно использовать вот так
log.Info("Log");

Отдельный класс

Также возможно создать отдельный прокси класс который будет осуществлять доступ к записи в лог.
public class Log
{
  static Log()
  {
    XmlConfigurator.Configure();
  }

  public static ILog For( object LoggedObject )
  {
    if ( LoggedObject != null )
      return For( LoggedObject.GetType() );
    else
      return For( null );
  }

  public static ILog For( Type ObjectType )
  {
    if ( ObjectType != null )
      return LogManager.GetLogger( ObjectType.Name );
    else
      return LogManager.GetLogger( string.Empty );
  }
}
Тогда его использование будет выглядеть так
Log.For( this ).Info( "Log" );

3 комментария:

  1. Интересно, есть ли реализация вывода в TextBox при помощи Log4net и без гигантского количества кода

    ОтветитьУдалить
    Ответы
    1. Да можно реализовать свой апендер, например вот реализация http://stackoverflow.com/questions/14114614/configuring-log4net-textboxappender-custom-appender-via-xml-file

      Удалить
  2. Я, конечно, понимаю, что это просто, но желательно привести названия файлов к единому.

    плавно перетекает в
    [assembly: log4net.Config.XmlConfigurator(ConfigFile = "config\\BuilderCrossingSeams.exe.log4net", Watch = true)]//Если файл с настройками лежит в папке config

    ОтветитьУдалить