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

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

81558 次浏览

Do you have the following attribute in your AssemblyInfo.cs file:

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

and code like this at the start of each class that requires logging functionality:

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

I have a blog post containing this and other info here.

@Mitch, It turns out there is a file with the [assembly:...] declaration, but it did not have the ConfigFile property.

Once I added it and pointed it to Log.config, it started working. I would have thought that it would work like all the other config sections (ie AppSettings) and accept external config files with no modification.

We don't have the second statement you mentioned, as we wrap it in a global static log provider.

There is an open defect on this issue. Log4Net does not support the configSource attribute of configuration elements. To use a purely configuration file solution you use the log4net.Config key in appSettings.

Step 1: Include the normal configuration section definition:

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

Step 2: Use the magic log4net.Config key in appSettings.

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

Step 3: Contribute a patch to fix the handling of configSource.

Make sure that your log4net.config file is set with the following properties:

Build Action: Content

Copy to output directory: Copy Always

The step that has been missed is

log4net.Config.XmlConfigurator.Configure();

this will cause the configSource to be used. Make sure you call it once before calling GetLogger();

Assuming you had an external config file called log4net.config that is copied to your deploy directory you can configure it like so:

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

Either use,

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

or just,

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

In both cases the file,Log4Net.config, should be there in output directory. You can do this by setting Log4Net.config file properties in solution explorer. Build Action - Content and Copy to Output Directory - Copy always

Watch out for this issue...

In my case everything was configured correctly. The problem is that I used Web Deploy inside Visual Studio 2013 to upload the site to WinHost.com and it reset the ACLs on the server. This in turn revoked all permission on folders and files - log4net could not write the file.

You can read more about it here:

How to stop Web Deploy/MSBuild from messing up server permissions

I asked the support team there to reset the ACLs and then log4net started spitting logs. :)

I had the same problem, besides having

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

in the running project, I also had the following line in a reference project:

[assembly: log4net.Config.XmlConfigurator]

When I removed this line in the referenced projects, the logs start to appear.

It is also possible to turn on a Debug mode for log4net. Insert this into the App.config file:

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

and you will at least get error messages, from which you can derive what exactly went wrong. In my case I simply forgot to set Copy to output directory to Copy Always.

In my case I got this error message:

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

And log4net.config the file was in Visual Studio 2017 project, but when I checked the file in bin\Debug folder I could not find it.

My original assembly setup was like this:

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

After some research time, I change it to the following and it works:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = @"..\..\log4net.config", Watch = true)]
  1. add following to AssemblyInfo.cs

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

  2. Make sure log4net.config is included in project

  3. In properties of log4net.config

change CopyToOutputDirctory tag to CopyIfNewer tag

  1. Double check log level level value="ALL"

It's also worth pointing out that in a web app it looks in the root directory, not the bin folder, so make sure that's where you put the config file.