【问题标题】:log4net only works when XmlConfigurator.Configure() is calledlog4net 仅在调用 XmlConfigurator.Configure() 时有效
【发布时间】:2013-05-27 04:22:25
【问题描述】:

我知道thisquestionhasbeenaskedseveraltimes,但不幸的是,我无法让我的日志记录配置正常工作。我一定是在某个地方犯了一些非常小的错误。

我有一个 .NET 4.5 MVC 4/EF 5 Web 应用程序,我正在尝试让日志记录工作。该解决方案有两个项目,一个用于 DAO 和模型对象,一个用于网站。 App.Config 文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="RebuildingTogetherEntities" connectionString="stuff..."/>
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
  </entityFramework>
  <log4net configSource="Log.config" />
</configuration>

同样的 log4net 部分也已复制到 Web.Config 文件中。

我在两个 AssemblyInfo.cs 文件中添加了以下内容:

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

两个 Log.Config 文件的“复制到输出目录”都设置为 true。

我似乎可以让日志记录附加到输出文件的唯一方法是在第一个日志记录语句运行之前调用 XmlConfigurator.Configure()。我想我可以在第一次获得记录器时编写一个外观来做到这一点,但这感觉不对。

如何在不手动调用 XmlConfigurator 的情况下初始化记录器?

【问题讨论】:

  • 看起来不是...在这种情况下,在应用程序关闭之前 log4net 有一条消息,但在我的情况下我没有看到该消息。不过,感谢您的建议。
  • 不确定我是否同意你的逻辑。除非打开内部日志记录,否则您不会看到 log4net 消息,并且如果您的系统没有读取您的 log.config,那么它可能不会打开。重要的一点是,当您执行 GetLogger(...) 之类的操作时,系统基本上会执行与 Attribute.GetCustomAttributes(Assembly.GetCallingAssembly(), typeof(log4net.Config.ConfiguratorAttribute), false) 等效的操作。因此,如果您没有在应用程序启动的早期记录,那么您的第一个记录器可能会从不继续自定义属性的程序集初始化。
  • 我喜欢日志框架如何默默地失败

标签: c# .net log4net


【解决方案1】:

我遇到了完全相同的问题。正如您正确指出的那样,当您在AssemblyInfo.cs 中包含该行时,您不需要显式调用XmlConfigurator。当第一次使用 log4net 是在没有该行的程序集中时,问题就出现了。就我而言,我使用的是 Topshelf.Log4Net NuGet 包,我的应用程序记录的第一条日志行就是通过它。

您可以在应用程序的早期记录一行,或者如果您不需要记录任何内容,请执行我所做的并在应用程序的入口点添加以下内容

LogManager.GetLogger(typeof(Program));

【讨论】:

  • 很好的答案。我们遇到了同样的问题,即由我们的 DI 容器自动创建的对象在主应用程序之前吐出一行日志记录。
  • 多么救命啊。把它放在 global.asax.cs 中,它工作得很好。为此花了一天的时间。
  • 在这种情况下什么是程序?
  • Program 类通常用作 C# 应用程序的入口点。不过,您可以使用条目程序集中的任何类。
  • @ChrisGessler 这不是一个变通方法,它是as specified in the attribute documentation - "...必须在应用程序启动期间尽早进行日志调用,当然在任何外部程序集已加载并调用。”
【解决方案2】:

如果使用,则无需手动调用 XmlConfigurator:

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

但是您必须将标记添加到所有 dll 中(所有 assambly.cs 文件)。

【讨论】:

  • 不幸的是,即使添加了这个应用程序仍然没有记录。
  • 您能否解释一下为什么您建议将此属性添加到所有 dll 中,而不是仅添加到主机中?
  • 它将使您能够为每个 dll 分别配置不同的配置文件的日志记录。
  • 我认为 [assembly] 在 global.aspx 中,我在其他项目中使用它并且 log4net 运行良好,但我有一个项目不起作用
猜你喜欢
  • 1970-01-01
  • 2023-02-08
  • 2018-11-10
  • 2017-01-30
  • 2019-08-22
  • 2012-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多