Log4Net config ในไฟล์ภายนอกไม่ทำงาน


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 เพื่อตั้งค่าคุณสมบัติ "Copy to Output Directory" บน "Copy Always"
E. van der Spoel

@mitchwheat พระเจ้าอย่างแน่นอนฉันต่อสู้กับวิธีการแก้ปัญหาตาม Ninject เพื่อทำสิ่งนี้ทุกวัน ... ขอบคุณมาก!
สงคราม

39

มีข้อบกพร่องที่เปิดเผยเกี่ยวกับปัญหานี้ Log4Net ไม่สนับสนุนแอตทริบิวต์ configSource ขององค์ประกอบการกำหนดค่า ในการใช้โซลูชันไฟล์คอนฟิกูเรชันทั้งหมดคุณใช้คีย์ log4net.Config ใน appSettings

ขั้นตอนที่ 1: รวมนิยามส่วนการกำหนดค่าปกติ:

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

ขั้นตอนที่ 2: ใช้ magic log4net.Config key ใน appSettings

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

ขั้นตอนที่ 3: สนับสนุนโปรแกรมแก้ไขเพื่อแก้ไขการจัดการ configSource


5
การเรียกใช้ log4net.Config.XmlConfigurator.Configure (); ควรจะผ่านพ้นปัญหานี้ไปได้โดยไม่ได้อ่าน configSource
Greg Domjan

สิ่งนี้ไม่ได้เปลี่ยนแปลงอะไรสำหรับฉัน ฉันยังไม่พบปัญหา แต่จะพยายามติดตาม
Don Rolling

5
สิ่งสำคัญคือต้องทำเครื่องหมายไฟล์กำหนดค่า log4net เป็น "copy if newer" หากไฟล์ config ไม่ได้ถูกคัดลอกไปยังโฟลเดอร์ bin มันจะไม่ทำงาน
Francisco Goldenstein

สิ่งนี้ใช้ได้ผลสำหรับฉันตามที่เป็นอยู่และฉันชอบมันมากกว่าโซลูชันที่ได้รับการยอมรับเนื่องจากไลบรารีบางส่วนของฉันถูกใช้ในแอปพลิเคชันเว็บที่มีการกำหนดค่าการบันทึกใน log4net.config แยกต่างหากและบางครั้งก็ใช้ในแอปแบบสแตนด์อโลนซึ่งการบันทึกอยู่ กำหนดค่าใน app.exe.config วิธีนี้ทั้งหมดอยู่ใน config แทนที่จะอยู่ในข้อมูลการประกอบ - ฉันไม่ต้องการ "ฮาร์ดโค้ด" ไปที่ log4net.config
Danny

27

ก้าวที่พลาดไปคือ

log4net.Config.XmlConfigurator.Configure(); 

สิ่งนี้จะทำให้ configSource ถูกใช้ ตรวจสอบให้แน่ใจว่าคุณโทรไปแล้วหนึ่งครั้งก่อนโทร GetLogger ();


คุณไม่จำเป็นต้องทำเช่นนี้หากคุณใช้โซลูชันของมิทช์วีท
Robert Wagner

4
@ โรเบิร์ต: แน่นอนว่าแม้ว่าโซลูชันของ Mitch Wheat ต้องการการเข้ารหัสไฟล์ config นอก app.config อย่างหนัก - ฉันอ่านคำถามเดิมคือทำไม configSource ไม่ทำงานมันจะทำงานได้หากทำตามขั้นตอนพิเศษนี้
Greg Domjan

ฉันชอบแนวทางนี้มากขึ้นโดยเฉพาะอย่างยิ่งเนื่องจากฉันสร้างตัวจัดการบันทึกกระดาษห่อหุ้มซึ่งใช้ log4net ภายใน (ซึ่งสามารถแทนที่ได้ในภายหลัง) จากนั้นในตัวจัดการบันทึกของ wrapper นี้ฉันจึงเรียก log4net.Config.XmlConfigurator.Configure () ด้วยวิธีนี้โครงการใด ๆ ที่มี app.config ของตัวเองสามารถใช้ตัวจัดการบันทึกของ wrapper นี้ได้โดยไม่จำเป็นต้องเปลี่ยนแอสเซมเบลอร์
cs

19

ตรวจสอบให้แน่ใจว่าไฟล์ log4net.config ของคุณถูกตั้งค่าด้วยคุณสมบัติต่อไปนี้:

Build Action: เนื้อหา

คัดลอกไปยังไดเร็กทอรีเอาต์พุต: คัดลอกเสมอ


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 ใน solution explorer Build Action - เนื้อหาและคัดลอกไปยัง Output Directory - คัดลอกเสมอ


คุณไม่ต้องใช้แท็ก <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 directoryCopy Always


0

@ มิทช์ปรากฎว่ามีไฟล์ที่มีการประกาศ [แอสเซมบลี: ... ] แต่ไม่มีคุณสมบัติ 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

เปลี่ยนCopy เป็น Output Dirctoryเป็นCopy ถ้าใหม่กว่า

  1. ตรวจสอบค่าระดับการบันทึกอีกครั้ง = "ALL"

0

นอกจากนี้ยังควรชี้ให้เห็นว่าในเว็บแอปจะมีลักษณะอยู่ในไดเรกทอรีรากไม่ใช่โฟลเดอร์ bin ดังนั้นโปรดตรวจสอบให้แน่ใจว่าเป็นที่ที่คุณใส่ไฟล์กำหนดค่า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.