外部文件中的 Log4Net 配置不起作用
Posted
技术标签:
【中文标题】外部文件中的 Log4Net 配置不起作用【英文标题】:Log4Net config in external file does not work 【发布时间】:2010-10-01 13:14:45 【问题描述】:我们正在使用 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(替换上面的第一行代码),它会按预期工作。知道为什么它不能在外部文件中工作吗?
【问题讨论】:
我遇到了同样的问题 - 我们可能遵循了相同的(错误引导的)指南! 这是我不喜欢 log4net 的地方。在我看来,日志框架应该是你的应用程序中最可靠的部分之一 - 但 log4net 通常看起来有点脆弱。 【参考方案1】:您的AssemblyInfo.cs
文件中是否有以下属性:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]
在每个需要日志记录功能的类的开头使用这样的代码:
private static readonly ILog log =
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
我有一篇博文包含此信息和其他信息 here。
【讨论】:
这行得通,如果您创建 log4net.config 文件,请确保您在“始终复制”上设置“复制到输出目录”属性。 @mitchwheat 绝对像上帝一样,我一直在与一个基于 ninject 的解决方案作斗争,以完全做到这一点......谢谢伙计!【参考方案2】:@Mitch,原来有一个带有 [assembly:...] 声明的文件,但它没有 ConfigFile 属性。
一旦我添加它并将它指向 Log.config,它就开始工作了。我原以为它会像所有其他配置部分(即 AppSettings)一样工作,并且无需修改即可接受外部配置文件。
我们没有您提到的第二条语句,因为我们将其包装在全局静态日志提供程序中。
【讨论】:
【参考方案3】:关于这个问题有一个open defect。 Log4Net 不支持配置元素的 configSource 属性。要使用纯粹的配置文件解决方案,您可以在 appSettings 中使用 log4net.Config 键。
第 1 步:包括正常的配置节定义:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
第 2 步:在 appSettings 中使用神奇的 log4net.Config 键。
<appSettings>
<add key="log4net.Config" value="log4net.simple.config" />
</appSettings>
第 3 步:贡献一个补丁来修复 configSource 的处理。
【讨论】:
调用 log4net.Config.XmlConfigurator.Configure();应该通过它不读取 configSource 来解决这个问题 这对我没有任何改变。我还没有弄清楚这个问题,但我会尽力跟进。 将 log4net 配置文件标记为“如果较新则复制”很重要。如果配置文件没有复制到 bin 文件夹,那么它就不会工作。 这对我来说是按原样工作的,我更喜欢它而不是接受的解决方案,因为我的一些库用于 Web 应用程序,其中日志记录在单独的 log4net.config 中配置,有时用于在 app.exe.config 中配置日志记录的独立应用程序。这样它就全部在配置中而不是在程序集信息中 - 我不想将它“硬编码”到 log4net.config【参考方案4】:确保您的 log4net.config 文件设置有以下属性:
构建操作:内容
复制到输出目录:总是复制
【讨论】:
【参考方案5】:错过的步骤是
log4net.Config.XmlConfigurator.Configure();
这将导致使用 configSource。 确保在调用 GetLogger() 之前调用它一次;
【讨论】:
如果您使用米奇小麦的解决方案,则不需要这样做。 @Robert:当然,尽管 Mitch Wheat 的解决方案需要在 app.config 之外对配置文件进行硬编码 - 我读到最初的问题是为什么 configSource 不起作用,如果这个额外的步骤它确实起作用跟随。 我更喜欢这种方法,特别是因为我创建了一个内部使用 log4net 的包装器日志处理程序(以后可以替换),然后在这个包装器日志处理程序中我总是调用 log4net.Config.XmlConfigurator.Configure ()。这样,任何拥有自己 app.config 的项目都可以使用这个包装器日志处理程序,而无需更改 assembler.cs 我应该在哪里称呼它? @Yola 在调用 GetLogger 之前调用一次【参考方案6】:假设你有一个名为 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());
【讨论】:
【参考方案7】:随便用,
<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 文件属性来执行此操作。 构建操作 - 内容并复制到输出目录 - 始终复制
【讨论】:
第一种情况不需要注意这个问题...
就我而言,一切都已正确配置。问题是我在 Visual Studio 2013 中使用 Web Deploy 将站点上传到 WinHost.com 并重置了服务器上的 ACLs。这反过来又撤销了对文件夹和文件的所有权限 - log4net 无法写入文件。
您可以在此处阅读更多信息:
How to stop Web Deploy/MSBuild from messing up server permissions
我要求那里的支持团队重置 ACL,然后 log4net 开始吐出日志。 :)
【讨论】:
【参考方案9】:我有同样的问题,除了有
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net")]
在正在运行的项目中,我在参考项目中也有以下行:
[assembly: log4net.Config.XmlConfigurator]
当我在引用的项目中删除这一行时,日志开始出现。
【讨论】:
【参考方案10】:也可以为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
。
【讨论】:
【参考方案11】:就我而言,我收到了以下错误消息:
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)]
【讨论】:
【参考方案12】:将以下内容添加到 AssemblyInfo.cs
[程序集:log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config")]
确保 log4net.config 包含在项目中
在 log4net.config
的属性中将 CopyToOutputDirctory 标签更改为 CopyIfNewer 标签
-
复查日志级别
等级
value="ALL"
【讨论】:
【参考方案13】:还值得指出的是,在 Web 应用程序中,它查看的是根目录,而不是 bin 文件夹,因此请确保这是放置配置文件的位置。
【讨论】:
以上是关于外部文件中的 Log4Net 配置不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Amazon Route 53 别名记录/区域文件不起作用 - 外部域注册商
google-cloud-platform:外部 DNS 配置不起作用