Конфигурация Log4Net во внешнем файле не работает


91

Мы используем log4net и хотим указать его конфигурацию во внешнем файле конфигурации (как мы это делали с другими разделами). Для этого мы изменили раздел log4net в App.config на:

...
<section name="log4net" 
     type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
...
<log4net configSource="Log.config" />
...

И в файле Log.Config (тот же каталог, что и App.config) у нас есть:

<log4net>
  <appender name="General" type="log4net.Appender.FileAppender">
    <file value="myapp.log" />
    <layout type="log4net.Layout.SimpleLayout" />
  </appender>
  <root>
    <appender-ref ref="General" />
  </root>
</log4net>

Однако при запуске приложения файл журнала не создается (и журнал не ведется). На консоль не выводятся сообщения об ошибках.

Если мы переместим содержимое файла Log.config обратно в App.config (заменив первую строку кода выше), он будет работать должным образом. Есть идеи, почему он не работает во внешнем файле?


Я столкнулся с той же проблемой - мы, вероятно, следовали одному и тому же (неверному) руководству!
— Zach Burlingame

14
Это то, что мне не нравится в log4net. На мой взгляд, фреймворк регистрации должен быть одной из самых надежных частей вашего приложения, но log4net часто кажется немного нестабильным.
— UpTheCreek

Ответы:


113

Есть ли в вашем AssemblyInfo.csфайле следующий атрибут :

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]

и код, подобный этому, в начале каждого класса, который требует функции ведения журнала:

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

У меня есть сообщение в блоге, содержащее эту и другую информацию здесь .


17
Это работает, убедитесь, что при создании файла log4net.config вы установили свойство «Копировать в выходной каталог» на «Всегда копировать».
— Э. ван дер Споэль

@mitchwheat Совершенно верно, я боролся с решением на основе ниндзя, чтобы делать именно то, что он делает весь день ... спасибо, чувак!
— War

39

В этом вопросе есть открытый недочет . Log4Net не поддерживает атрибут configSource элементов конфигурации. Чтобы использовать решение только с файлом конфигурации, используйте ключ log4net.Config в appSettings.

Шаг 1. Включите определение раздела нормальной конфигурации:

<configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>

Шаг 2: Используйте волшебный ключ log4net.Config в appSettings.

<appSettings>
      <add key="log4net.Config" value="log4net.simple.config" />
</appSettings>

Шаг 3: Внесите патч для исправления обработки configSource.


5
Вызов log4net.Config.XmlConfigurator.Configure (); должен решить эту проблему, не читая configSource
— Грег Домжан,

Для меня это ничего не изменило. Я еще не выяснил, в чем проблема, но постараюсь разобраться.
— Дон Роллинг,

5
Важно отметить файл конфигурации log4net как «копировать, если новее». Если файл конфигурации не скопирован в папку bin, он не сработает.
— Франсиско Гольденштейн,

Это сработало для меня как есть, и я предпочитаю его принятому решению, потому что некоторые из моих библиотек используются в веб-приложении, где ведение журнала настраивается в отдельном файле log4net.config и иногда используется в автономном приложении, где ведение журнала настраивается в app.exe.config. Таким образом, это все в конфигурации, а не в информации о сборке - я не хочу «жестко закодировать» ее в log4net.config
— Дэнни,

27

Пропущенный шаг -

log4net.Config.XmlConfigurator.Configure(); 

это приведет к использованию configSource. Обязательно вызовите его один раз перед вызовом GetLogger ();


Вам не нужно этого делать, если вы используете раствор Mitch Wheat.
— Роберт Вагнер,

4
@Robert: Конечно, хотя решение Митча Уита требует жесткого кодирования файла конфигурации вне app.config - я читал, что исходный вопрос был в том, почему не работает configSource, он работает, если следовать этому дополнительному шагу.
— Грег Домьян,

Мне больше нравится этот подход, особенно потому, что я создаю обработчик журнала оболочки, который внутренне использует log4net (который может быть заменен позже), а затем в этом обработчике журнала оболочки я всегда вызываю log4net.Config.XmlConfigurator.Configure (). Таким образом, любой проект со своим собственным app.config может использовать этот обработчик журнала оболочки без необходимости изменять
— zheng yu

19

Убедитесь, что ваш файл log4net.config имеет следующие свойства:

Действие сборки: контент

Копировать в выходной каталог: копировать всегда


10

Либо используйте,

<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<appSettings>
<add key="log4net.Config" value="Log4Net.config" />
</appSettings>

или просто,

log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo("Log4Net.config"));

В обоих случаях файл Log4Net.config должен находиться в каталоге вывода. Вы можете сделать это, установив свойства файла Log4Net.config в обозревателе решений. Действие сборки - содержимое и копирование в выходной каталог - всегда копировать


вам не нужен тег <configSections> для первого случая
— disklosr

2

Остерегайтесь этой проблемы ...

В моем случае все было настроено правильно. Проблема в том, что я использовал Web Deploy внутри Visual Studio 2013 для загрузки сайта на WinHost.com и сбросил списки управления доступом на сервере. Это, в свою очередь, аннулировало все права доступа к папкам и файлам - log4net не смог записать файл.

Вы можете прочитать больше об этом здесь:

Как запретить Web Deploy / MSBuild испортить разрешения сервера

Я попросил техподдержку сбросить ACL, а затем log4net начал выдавать логи. :)


1

Предполагая, что у вас есть внешний файл конфигурации с именем log4net.config, который копируется в каталог развертывания, вы можете настроить его следующим образом:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Reflection;

using log4net;

namespace MyAppNamespace {
    static class Program {
        //declare it as static and public so all classes in the project can access it
        //like so: Program.log.Error("got an error");
        public static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() {
             //configure it to use external file
            log4net.Config.XmlConfigurator.Configure(new Uri(Application.StartupPath + "\\log4net.config"));
            //use it
            log.Debug("#############   STARING APPLICATION    #################");


            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FormMain());
        }
    }
}

1

У меня была такая же проблема, кроме того, что

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net")]

в работающем проекте у меня также была следующая строка в эталонном проекте:

[assembly: log4net.Config.XmlConfigurator]

Когда я удалил эту строку в упомянутых проектах, журналы начали появляться.


1

Также можно включить режим отладки для log4net. Вставьте это в файл App.config:

 <appSettings>
      <add key="log4net.Internal.Debug" value="true"/>
 </appSettings>
 <system.diagnostics>
      <trace autoflush="true">
      <listeners>
           <add
             name="textWriterTraceListener"
             type="System.Diagnostics.TextWriterTraceListener"
             initializeData="link\to\your\file.log" />
      </listeners>
      </trace>
 </system.diagnostics>

и вы, по крайней мере, будете получать сообщения об ошибках, из которых сможете понять, что именно пошло не так. В моем случае я просто забыл установить Copy to output directoryна Copy Always.


0

@Mitch, оказывается есть файл с объявлением [assembly: ...], но у него не было свойства ConfigFile.

Как только я добавил его и указал на Log.config, он начал работать. Я бы подумал, что он будет работать, как и все другие разделы конфигурации (например, AppSettings), и принимать внешние файлы конфигурации без каких-либо изменений.

У нас нет второго утверждения, о котором вы упомянули, поскольку мы оборачиваем его в глобальный поставщик статических журналов.


0

В моем случае я получил это сообщение об ошибке:

log4net: config file [C:\........\bin\Debug\log4net.config] not found.

И log4net.configфайл был в проекте Visual Studio 2017, но когда я проверил файл вbin\Debug папке, я не смог его найти.

Моя первоначальная установка сборки была такой:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]

После некоторого времени исследования я меняю его на следующее, и оно работает:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = @"..\..\log4net.config", Watch = true)]

0
  1. добавить следующее в AssemblyInfo.cs

[сборка: log4net.Config.XmlConfigurator (ConfigFile = "Log4Net.config")]

  1. Убедитесь, что log4net.config включен в проект
  2. В свойствах log4net.config

измените Копировать в выходной каталог на Копировать, если новее

  1. Дважды проверьте значение уровня уровня журнала = "ВСЕ"

0

Также стоит отметить, что в веб-приложении он ищет в корневом каталоге, а не в папке bin, поэтому убедитесь, что вы поместили туда файл конфигурации.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.