外部文件中的 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 文件属性来执行此操作。 构建操作 - 内容并复制到输出目录 - 始终复制

【讨论】:

第一种情况不需要 标签 第二个是唯一对我有用的选项【参考方案8】:

注意这个问题...

就我而言,一切都已正确配置。问题是我在 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 配置不起作用

数据源的 Spring Boot 外部化配置不起作用

“无法连接到数据库”:Keycloak Operator 外部数据库配置不起作用

使用外部硬盘驱动器,heroku 2.4.0 命令不起作用