奇怪的log4net初始化行为

时间:2013-05-09 15:15:15

标签: c# log4net

我遇到了一些与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具有如下实例化的记录器:

private static ILog logger = LogManager.GetLogger(typeof(AnyClass));

我使用伪代码的原因是,我可以使用我实例化的任何类复制此行为并调用方法。如果没有调用方法,则日志记录路径按预期工作。

有几点需要注意:

  1. 当我在调试或调试模式下在调试器中运行它时,这是有效的。仅当我直接运行exe或通过“Start Without Debugging”启动时才会出现错误。
  2. 如果没有静态定义记录器 - 则问题就会消失
  3. 如果我向AnyClass添加一个静态构造函数,那么问题就会消失,即:

    static AnyClass(){}

  4. 如果我将对ac.NoOp()的调用移动到OnStartup调用的辅助方法 - 错误就会消失。

  5. 因此,回顾一下,错误只是通过使用静态记录器初始化实例化一个类,并在OnStartup方法中调用该类的方法引起的。

    我有几种方法可以解决这个问题,但我希望了解更多,以了解为什么会发生这种情况。

1 个答案:

答案 0 :(得分:0)

我认为ac.NoOp();正在创建一个新实例的记录器,而新实例不知道PatternString的值是什么。因此正在使用null值。

refer this link

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.