奇怪的log4net初始化行为
本文关键字:初始化 log4net | 更新日期: 2023-09-27 18:12:47
我遇到了一些奇怪的行为与log4net,不知道是否有人可以解释这个给我,我想了解更多的了解它。
在我的WPF App.xaml.cs OnStartup覆盖方法中,我有以下代码设置了用于日志记录的log4net属性:
// logLocation is a path to a subdir in the users' appdata roaming dir
log4net.GlobalContext.Properties["LogLocation"] = logLocation;
logger = LogManager.GetLogger(typeof(App));
logger.Info("OnStartup: " + string.Join(" ", e.Args));
我在创建任何其他记录器之前这样做(至少我是这样认为的)。
在我的配置文件中有以下行:
<file type="log4net.Util.PatternString" value="%property{LogLocation}" />
用于指定日志文件的位置。但是,我遇到了这样一种情况,这种情况失败了——导致将日志写入执行目录中的文件名为"(null)"。
似乎是下面的伪代码导致了这个问题,它在上面代码之后的同一个OnStartup方法中:
AnyClass ac = new AnyClass();
ac.NoOp();
其中AnyClass有一个logger实例化如下:
private static ILog logger = LogManager.GetLogger(typeof(AnyClass));
我使用伪代码的原因是,我可以在任何我实例化并调用方法的类上复制这种行为。如果没有调用任何方法,则日志记录路径按预期工作。
有几点需要注意:
- 当我在调试或发布模式下在调试器中运行它时,它会起作用。这个错误只在我直接运行exe或通过'Start Without Debugging'时出现。
- 如果记录器不是静态定义的,那么问题就消失了
如果我添加一个静态构造函数到AnyClass,那么问题就消失了,即:
静态AnyClass() {}
如果我将ac.NoOp()的调用移动到次要方法,由OnStartup调用-错误消失
所以,回顾一下,这个错误仅仅是由使用静态日志初始化实例化一个类,并在OnStartup方法中调用该类的一个方法引起的。
我有几种方法来解决这个问题,但我想了解更多,以了解为什么会发生这种情况。
我认为ac.NoOp();
正在创建一个新实例的记录器和新实例不知道什么是PatternString的值。因此使用null
值
请参考此链接
public static Logger getLogger(String name)
Retrieve a logger named according to the value of the name parameter.
If the named logger already exists, then the existing instance will be returned.
Otherwise, **a new instance** is created.