【问题标题】:Log4Net config in external file does not work外部文件中的 Log4Net 配置不起作用
【发布时间】: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 通常看起来有点脆弱。

标签: file logging configuration log4net external


【解决方案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】:
                1. 将以下内容添加到 AssemblyInfo.cs

                  [程序集:log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config")]

                2. 确保 log4net.config 包含在项目中

                3. log4net.config

                  的属性中

                CopyToOutputDirctory 标签更改为 CopyIfNewer 标签

                1. 复查日志级别 等级value="ALL"

                【讨论】:

                  【解决方案13】:

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

                  【讨论】:

                    猜你喜欢
                    • 2011-09-20
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2018-09-17
                    • 2016-04-04
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多