外部文件中的Log4Net配置不起作用


92

我们正在使用log4net,并希望在外部配置文件中指定它的配置(与其他部分一样)。为此,我们将App.config中的log4net部分更改为:

...
<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中(替换上面的第一行代码),它将按预期工作。知道为什么它不能在外部文件中工作吗?


我遇到了同样的问题-我们可能遵循了同样的(误导)指南!
扎克·伯林格姆

14
这就是我不喜欢log4net的地方。在我看来,日志记录框架应该是应用程序中最可靠的部分之一-但log4net似乎常常有些麻烦。
UpTheCreek 2010年

Answers:


112

您的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 2015年

@mitchwheat绝对是上帝,我一直在与基于ninject的解决方案进行斗争,以整日做到这一点……谢谢男人!
战争

39

在这个问题上有一个公开的缺陷。Log4Net不支持配置元素的configSource属性。要使用纯配置文件解决方案,请使用appSettings中的log4net.Config键。

步骤1:包括常规配置部分定义:

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

步骤2:使用appSettings中的magic log4net.Config键。

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

步骤3:提供补丁以修复configSource的处理。


5
调用log4net.Config.XmlConfigurator.Configure(); 应该克服这个问题,因为它不读取configSource
Greg Domjan

这对我没有任何改变。我还没有弄清楚这个问题,但我会尽力跟进。
Don Rolling 2015年

5
将log4net配置文件标记为“如果较新则复制”很重要。如果配置文件未复制到bin文件夹,则它将无法工作。
弗朗西斯科·金斯坦

这按原样对我有用,我更喜欢它而不是公认的解决方案,因为我的一些库是在Web应用程序中使用的,在Web应用程序中,日志记录是在单独的log4net.config中配置的,有时在独立应用程序中使用,日志记录是在app.exe.config中配置。这样,它全部在配置中,而不是在装配信息中-我不想将其“硬编码”到log4net.config
Danny

27

错过的步骤是

log4net.Config.XmlConfigurator.Configure(); 

这将导致使用configSource。确保在调用GetLogger()之前调用一次。


如果使用Mitch Wheat的解决方案,则不需要这样做。
罗伯特·瓦格纳

4
@Robert:当然,尽管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


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

@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

还值得指出的是,在Web应用程序中,它查找的是根目录,而不是bin文件夹,因此请确保将其放在配置文件中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.