Konfigurasi Log4Net di file eksternal tidak berfungsi

91

Kami menggunakan log4net dan ingin menentukan konfigurasinya di file konfigurasi eksternal (seperti yang telah kami lakukan dengan bagian lain). Untuk melakukan ini, kami telah mengubah bagian log4net di App.config menjadi:

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

Dan di file Log.Config (direktori yang sama dengan App.config) kami memiliki:

<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>

Namun, saat kami menjalankan aplikasi, tidak ada file log yang dibuat (dan tidak ada logging yang dilakukan). Tidak ada keluaran pesan kesalahan ke konsol.

Jika kita memindahkan konten file Log.config kembali ke App.config (mengganti baris kode pertama di atas), ini berfungsi seperti yang diharapkan. Tahu mengapa itu tidak berfungsi di file eksternal?

Robert Wagner
sumber
Saya mengalami masalah yang sama - kami mungkin mengikuti panduan (salah arah) yang sama!
Zach Burlingame
14
Inilah yang saya tidak suka tentang log4net. Kerangka kerja logging harus menjadi salah satu bit aplikasi Anda yang paling solid menurut saya - tetapi log4net seringkali tampak agak tidak stabil.
UpTheCreek

Jawaban:

113

Apakah Anda memiliki atribut berikut di AssemblyInfo.csfile Anda :

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

dan kode seperti ini di awal setiap kelas yang memerlukan fungsionalitas logging:

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

Saya memiliki entri blog yang berisi ini dan info lainnya di sini .

Mitch Wheat
sumber
17
Ini berfungsi, pastikan Anda jika Anda membuat file log4net.config untuk menyetel properti "Salin ke Direktori Output" pada "Salin Selalu".
E. van der Spoel
@mitchwheat Benar-benar seperti Tuhan, saya telah berjuang dengan solusi berbasis ninject untuk melakukan persis apa yang ini dilakukan sepanjang hari ... terima kasih man!
Perang
39

Ada cacat terbuka pada masalah ini. Log4Net tidak mendukung atribut configSource elemen konfigurasi. Untuk menggunakan solusi file konfigurasi murni, Anda menggunakan kunci log4net.Config di appSettings.

Langkah 1: Sertakan definisi bagian konfigurasi normal:

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

Langkah 2: Gunakan kunci log4net.Config ajaib di appSettings.

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

Langkah 3: Kontribusikan tambalan untuk memperbaiki penanganan configSource.

Terjal
sumber
5
Panggilan ke log4net.Config.XmlConfigurator.Configure (); harus mengatasi masalah ini dengan tidak membaca configSource
Greg Domjan
Ini tidak mengubah apa pun bagi saya. Saya belum menemukan masalahnya, tetapi saya akan mencoba menindaklanjutinya.
Don Rolling
5
Penting untuk menandai file konfigurasi log4net sebagai "salin jika lebih baru". Jika file konfigurasi tidak disalin ke folder bin maka itu tidak akan berfungsi.
Francisco Goldenstein
Ini berfungsi untuk saya apa adanya, dan saya lebih suka solusi yang diterima karena beberapa perpustakaan saya digunakan dalam aplikasi web di mana pencatatan dikonfigurasikan dalam log4net.config terpisah dan kadang-kadang digunakan dalam aplikasi yang berdiri bersama di mana pencatatan dilakukan. dikonfigurasi di app.exe.config. Dengan cara ini, semuanya ada di konfigurasi, bukan di info perakitan - Saya tidak ingin "melakukan hard-code" ke log4net.config
Danny
27

Langkah yang terlewat adalah

log4net.Config.XmlConfigurator.Configure(); 

ini akan menyebabkan configSource digunakan. Pastikan Anda memanggilnya sekali sebelum memanggil GetLogger ();

Greg Domjan
sumber
Anda tidak perlu melakukan ini jika Anda menggunakan solusi Mitch Wheat.
Robert Wagner
4
@Robert: Tentu, meskipun solusi Mitch Wheat memerlukan pengkodean keras file konfigurasi di luar app.config - Saya membaca pertanyaan aslinya adalah mengapa configSource tidak berfungsi, itu berfungsi jika langkah tambahan ini diikuti.
Greg Domjan
Saya lebih menyukai pendekatan ini, terutama karena saya membuat penangan log pembungkus yang secara internal menggunakan log4net (yang dapat diganti nanti), maka dalam penangan log pembungkus ini saya selalu memanggil log4net.Config.XmlConfigurator.Configure (). Dengan cara ini, proyek apa pun dengan app.confignya sendiri dapat menggunakan penangan log pembungkus ini, tanpa perlu mengubah assembler.cs
zheng yu
19

Pastikan file log4net.config Anda disetel dengan properti berikut:

Build Action: Konten

Salin ke direktori keluaran: Salin Selalu

Lewis Moten
sumber
10

Baik digunakan,

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

atau hanya,

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

Dalam kedua kasus, file, Log4Net.config, harus ada di direktori keluaran. Anda dapat melakukan ini dengan mengatur properti file Log4Net.config di explorer solusi. Build Action - Konten dan Salin ke Direktori Output - Salin selalu

Byju
sumber
Anda tidak memerlukan tag <configSections> untuk kasus pertama
disklosr
2

Waspadai masalah ini ...

Dalam kasus saya semuanya telah dikonfigurasi dengan benar. Masalahnya adalah saya menggunakan Penyebaran Web di dalam Visual Studio 2013 untuk mengunggah situs ke WinHost.com dan mereset ACL di server. Ini pada gilirannya mencabut semua izin pada folder dan file - log4net tidak dapat menulis file.

Anda dapat membaca lebih lanjut di sini:

Bagaimana cara menghentikan Penyebaran Web / MSBuild dari mengacaukan izin server

Saya meminta tim dukungan di sana untuk mengatur ulang ACL dan kemudian log4net mulai mengeluarkan log. :)

Leniel Maccaferri
sumber
1

Dengan asumsi Anda memiliki file konfigurasi eksternal bernama log4net.config yang disalin ke direktori penerapan Anda, Anda dapat mengkonfigurasinya seperti ini:

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());
        }
    }
}
JJ_Coder4Hire
sumber
1

Saya memiliki masalah yang sama, selain memiliki

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

dalam proyek yang sedang berjalan, saya juga memiliki baris berikut dalam proyek referensi:

[assembly: log4net.Config.XmlConfigurator]

Ketika saya menghapus baris ini di proyek yang direferensikan, log mulai muncul.

Tamu
sumber
1

Dimungkinkan juga untuk mengaktifkan mode Debug untuk log4net. Masukkan ini ke dalam file 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>

dan Anda setidaknya akan mendapatkan pesan kesalahan, yang darinya Anda dapat mengetahui apa yang sebenarnya salah. Dalam kasus saya, saya hanya lupa menyetel Copy to output directoryke Copy Always.

waka
sumber
0

@ Mitch, Ternyata ada file dengan deklarasi [assembly: ...], tetapi tidak memiliki properti ConfigFile.

Setelah saya menambahkannya dan mengarahkannya ke Log.config, itu mulai berfungsi. Saya akan berpikir bahwa ini akan berfungsi seperti semua bagian konfigurasi lainnya (yaitu AppSettings) dan menerima file konfigurasi eksternal tanpa modifikasi.

Kami tidak memiliki pernyataan kedua yang Anda sebutkan, karena kami membungkusnya dalam penyedia log statis global.

Robert Wagner
sumber
0

Dalam kasus saya, saya mendapat pesan kesalahan ini:

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

Dan log4net.configfile itu ada di proyek Visual Studio 2017, tetapi ketika saya memeriksa file di bin\Debugfolder saya tidak dapat menemukannya.

Pengaturan perakitan asli saya seperti ini:

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

Setelah beberapa waktu penelitian, saya mengubahnya menjadi yang berikut dan berhasil:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = @"..\..\log4net.config", Watch = true)]
maytham-ɯɐɥʇʎɐɯ
sumber
0
  1. tambahkan yang berikut ke AssemblyInfo.cs

[perakitan: log4net.Config.XmlConfigurator (ConfigFile = "Log4Net.config")]

  1. Pastikan log4net.config disertakan dalam proyek
  2. Di properti log4net.config

ubah Copy to Output Dirctory menjadi Copy jika lebih baru

  1. Periksa kembali nilai level log = "SEMUA"
e03050
sumber
0

Perlu juga ditunjukkan bahwa di aplikasi web, ini terlihat di direktori root, bukan folder bin, jadi pastikan di situlah Anda meletakkan file konfigurasi.

Richard
sumber