Налаштування 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, щоб встановити властивість "Копіювати до вихідного каталогу" на "Копіювати завжди".
E. van der Spoel

@mitchwheat Абсолютно подобається, я боровся з рішенням на основі ninject, щоб цілий день робити саме те, що це робить ... дякую, людино!
Війна

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
Greg Domjan,

Це для мене нічого не змінило. Я ще не з’ясував проблеми, але спробую продовжити.
Дон Роллінг

5
Важливо позначити файл налаштування log4net як "скопіювати, якщо новіший". Якщо файл конфігурації не скопійовано в папку bin, він не буде працювати.
Франсіско Гольденштейн

Це спрацювало для мене як є, і я віддаю перевагу прийнятому рішенню, оскільки деякі мої бібліотеки використовуються у веб-програмі, де ведення журналів налаштовано в окремому log4net.config, а іноді використовується в автономній програмі, де налаштовано в app.exe.config. Таким чином, це все в конфігурі, а не в інформації про збірку - я не хочу "жорстко кодувати" її до log4net.config
Денні

27

Крок, який було пропущено, є

log4net.Config.XmlConfigurator.Configure(); 

це призведе до використання configSource. Переконайтеся, що ви зателефонували один раз перед тим, як зателефонувати GetLogger ();


Не потрібно цього робити, якщо ви використовуєте розчин Mitch Wheat.
Роберт Вагнер,

4
@ Роберт: Звичайно, хоча рішення Mitch Wheat вимагає жорсткого кодування конфігураційного файлу поза app.config - я прочитав, оригінальне питання було, чому не працює configSource, воно працює, якщо виконати цей додатковий крок.
Greg Domjan

Мені більше подобається такий підхід, особливо тому, що я створюю обробник журналу обгортки, який внутрішньо використовує log4net (який можна замінити пізніше), тоді в цьому обробнику журналу обгортки я завжди викликаю log4net.Config.XmlConfigurator.Configure (). Таким чином, будь-який проект із власною програмою app.config може використовувати цей обробник журналу обгортки, не змінюючи assembler.cs
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, і він скинув ACL на сервері. Це в свою чергу скасувало всі дозволи на папки та файли - 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. Перевірте значення рівня рівня журналу = "ALL"

0

Варто також зазначити, що у веб-програмі вона виглядає у кореневому каталозі, а не в папці bin, тому переконайтеся, що саме туди ви поклали файл конфігурації.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.