Log4Net с AdoNetAppender - ничего не происходит

Описание

У меня есть файл конфигурации в качестве ресурса в моей сборке, и я хочу программно изменить ConnectionString в своем приложении.

Я загружаю конфигурацию, используя log4net.Config.XmlConfigurator.Configure.

У меня есть несколько точек останова, и я вижу, что конфигурация успешно загружена, а строка подключения — Data Source=localhost\SQLExpress;Initial Catalog=Log;Integrated Security=SSPI; (локальный SQLExpress).

Проблема

Ничего не происходит, никаких исключений и записей в журнале. Есть идеи.

using (Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("MyNamespace.Properties.log4net.config"))
{ 
    // stream is NOT null
    log4net.Config.XmlConfigurator.Configure(stream);
}

Hierarchy hier = LogManager.GetRepository() as Hierarchy;

if (hier != null)
{
    //get ADONetAppender
    var adoAppender = (AdoNetAppender)hier.GetAppenders().Where(appender => appender.Name.Equals("AdoNetAppender", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();

    if (adoAppender != null)
    {
        // update connectionstring
        adoAppender.ConnectionString = configuration.GetConnectionString(ConnectionStringNames.Log).ConnectionString;
        //refresh settings of appender
        adoAppender.ActivateOptions(); 
    }
}

ILog logger = LogManager.GetLogger("MyProject"); 
logger.Warn("Test");

содержимое файла log4net.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>

  <log4net>
    <appender name="AdoNetAppender" type="log4net.Appender.ADONetAppender">
      <bufferSize value="1" />
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data,
  Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <connectionString value="[we will set this automatically at runtime]" />
      <commandText value="INSERT INTO Log ([Date],[Level],[Logger],[Message],[Exception])
  VALUES (@log_date, @log_level, @logger, @message, @exception)" />
      <parameter>
        <parameterName value="@log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.RawTimeStampLayout" />
      </parameter>
      <parameter>
        <parameterName value="@log_level" />
        <dbType value="String" />
        <size value="50" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%p" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@logger" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%c" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%m" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@exception" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>
    </appender>

    <root>
      <level value="ALL" />
      <appender-ref ref="AdoNetAppender" />
    </root>
  </log4net>
</configuration>

person dknaack    schedule 31.05.2012    source источник
comment
Полное примечание, но не намного ли лучше, чтобы файл конфигурации существовал рядом с вашей сборкой, а не запекался? В конце концов, основная причина, по которой он находится в файле конфигурации (а не определен в коде C#), заключается в том, что вы можете настроить его без перекомпиляции приложения.   -  person Kirk Woll    schedule 31.05.2012
comment
В общем, да. Но в моей ситуации мне это нужно из ресурса.   -  person dknaack    schedule 31.05.2012


Ответы (2)


Вы можете отлаживать log4net, подключившись к log4net DebugAppender:

Добавьте параметр приложения log4net в файл app.config:

<appSettings>
  <!-- log4net configuration when running in debug mode. -->    
  <add key="log4net.Internal.Debug" value="true" />   
</appSettings>

Добавьте приложение отладки в конфигурацию log4net:

<appender name="DebugAppender" type="log4net.Appender.DebugAppender">
  <immediateFlush value="true" />
  <layout type="log4net.Layout.SimpleLayout" />
</appender>

Добавьте приложение в корень конфигурации log4net:

<root>
  <level value="ALL" />
  <appender-ref ref="AdoNetAppender" />
  <appender-ref ref="DebugAppender" />
</root>

Когда вы запускаете свое приложение, посмотрите в окно вывода Visual Studio, и вы должны увидеть все внутренние журналы для log4net. Если нет, то файл конфигурации log4net никогда не загружается.

Изменить

Если вы можете использовать строку подключения из файла app.config, удалите строку подключения из log4net AdoNetAppender и просто вызовите строку подключения по имени:

<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
  <bufferSize value="1" />
  <!-- note: you can use the 4.0 assembly -->
  <connectionType value="System.Data.SqlClient.SqlConnection,
              System.Data, 
              Version=4.0.0.0, 
              Culture=neutral, 
              PublicKeyToken=b77a5c561934e089" />
  <!-- This will retrieve a connection string by name from the app.config -->
  <connectionStringName value="ConnectionStringNameFromAppConfig" />
  <!-- snip -->
</appender>
person Metro Smurf    schedule 31.05.2012
comment
Спасибо, исключение состоит в том, что log4net не может подключить базу данных с помощью строки подключения [мы установим это автоматически во время выполнения]. Все в порядке, я меняю строку подключения в коде. Любая другая идея? - person dknaack; 31.05.2012
comment
Используете ли вы ту же строку подключения, которая определена в файле app.config? И является ли фактическая ошибка из окна вывода: log4net не может подключить базу данных с помощью строки подключения «[мы установим это автоматически во время выполнения]»? - person Metro Smurf; 31.05.2012
comment
это сообщение приходит до того, как я вызываю первое сообщение Warn. - person dknaack; 31.05.2012
comment
Вы говорите, что изменили строку подключения в коде/среде выполнения, но отладчик log4net четко указывает, что он не может подключиться к базе данных с помощью строки подключения, которую мы установим автоматически во время выполнения. Есть ли ошибки после первого предупреждающего сообщения? - person Metro Smurf; 31.05.2012
comment
Сообщение приходит log4net.Config.XmlConfigurator.Configure, после этого других сообщений не приходит. - person dknaack; 31.05.2012
comment
См. мое редактирование для использования строки подключения по имени из app.config. Если это не вариант, попробуйте жестко запрограммировать строку подключения в конфигурационном файле log4net, чтобы убедиться, что подключение работает правильно, если это так, то что-то не так с тем, как строка подключения обновляется в коде. - person Metro Smurf; 31.05.2012
comment
Очень полезный ответ; отличная инструкция, работает отлично. - person Shawn J. Molloy; 19.06.2013
comment
Я перепробовал множество других шагов отладки, о которых упоминали другие, это единственный, который позволил мне увидеть то, что мне нужно было увидеть :) забыл установить столбец идентификатора в качестве идентификатора :( Вот и прошло мое утро, лол. Спасибо! ! - person Tony; 24.09.2013
comment
Плюс 1 для DebugAppender - person Johnie Karr; 13.08.2015
comment
Я сделал все это, и я не получаю никаких отзывов от debugAppender. Я вызываю Log.error (запишите эту ошибку); и это пишет в окно вывода, но я все равно ничего не получаю в таблице sql. есть идеи? - person Moi Hawk; 04.04.2019

Вот некоторые вещи, которые я пробовал, которые сработали для меня...

  • Я ничего не видел, потому что мой <appender-ref ref="AdoNetAppender" /> неправильно ссылался на мой <appender name="AdoNetAppender" ... /> в Web.config. Имена «AdoNetAppender» должны совпадать.

  • Добавлено <bufferSize value="1" /> в раздел <appender name="AdoNetAppender" /> файла Web.config.

  • Я создал учетную запись пользователя с паролем на сервере SQL вместо использования проверки подлинности Windows. Предоставленный пользователю доступ для выполнения операций выбора и вставки в таблицу

  • В Global.asax.cs я инициализирую log4net, используя log4net.Config.XmlConfigurator.Configure();

  • В моем коде C# я создаю новый объект adoAppender и вызываю logger.Info("save to db");

Документация на веб-сайте Apache также полезна... http://logging.apache.org/log4net/release/config-examples.html#MS%20SQL%20Server

Надеюсь, это сэкономит кому-то время и нервы. Спасибо!

person Robert Bolton    schedule 19.06.2014
comment
Ваш второй пункт (размер буфера) был для меня ключевым. Мой размер буфера был равен 100, поэтому я не видел никакого вывода в течение нескольких минут и предположил, что он не работает. Спасибо. - person Whatever Man; 22.05.2015
comment
Размер буфера тоже сделал это для меня. Документации по конфигурационным файлам от log4net действительно не хватает... - person Alexander Derck; 23.12.2015
comment
Вот документация для BufferSize . - person techvice; 25.05.2016
comment
Я пробовал все, пока не обнаружил, что размер буфера препятствует записи в базу данных в течение длительного времени. Спасибо, что указали на это - person Maximiliano Rios; 03.07.2016