我有一个使用log4net的程序集。我将此程序集加载到Windows窗体应用程序和控制台应用程序中。它在发布和调试版本中的Windows窗体应用程序和调试版本中的控制台应用程序中按预期工作,但对于控制台应用程序的发布版本却神秘失败。
我在AssemblyInfo.cs文件中有以下内容:
[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension="log4net", Watch = true)]
在使用日志记录的类中,我包含以下成员变量声明:
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
我的Library.dll.log4net配置文件如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" >
<file value="Library.log" />
<appendToFile value="true" />
<rollingStyle value="Once" />
<maxSizeRollBackups value="5" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
我已经尝试了this article(Log4Net doesn’t write log in release mode - Console Application)中的建议,但他们似乎没有帮助。
我还尝试在程序集中尽快以编程方式启用内部调试(在引用的第一个对象的构造函数中)但是也没有效果。
还有其他想法吗?谁能发现我做错了什么?
答案 0 :(得分:5)
正如the documentation for assembly configuration attributes中所述:
因此,如果使用配置属性,则必须调用log4net 允许它读取属性。一个简单的电话 LogManager.GetLogger将导致调用程序集上的属性 被阅读和处理。 因此必须进行日志记录 在应用程序启动期间尽早调用,以及 当然,在加载和调用任何外部程序集之前。
由于编译器可以更自由地重新组织Release版本中的内容,因此它似乎可以优化某些内容,并且汇编属性不会很快被拾取。
如果是这种情况,启动程序中的简单显式日志记录调用将强制log4net加载配置:
LogManager.GetLogger("Startup").Debug("This logging call loads the configuration");
然而,这仍然存在问题,例如对于一些Web应用程序或者如果(如在注释中)启动应用程序没有引用log4net:在这些情况下,您必须使用对配置系统的显式调用而不是装配属性。它只需要调用一次。
对于独立的log4net配置文件:
XmlConfigurator.Configure(new FileInfo(path_to_config));
对于web.config或app.config中的configSection中的配置
XmlConfigurator.Configure();