【问题标题】:Calling log4net from a singleton that is in a separate project stops all logging从单独项目中的单例调用 log4net 会停止所有日志记录
【发布时间】:2012-06-20 18:42:54
【问题描述】:

该应用程序是一个 WinForms .net 3.5 应用程序,具有多个项目、一个主项目和多个库项目。如果我从其中一个子项目中存在的单例调用 log4net,它会导致所有日志记录停止。

更新

基于一些 cmets,我通过以下方式更改了 TestSingletonLog4net 类。这些更改仍然存在问题。

  • 正如 Jon Skeet 指出的那样,使测试类线程安全。
  • 更改了成员声明并添加了 log4net.Config.XmlConfigurator.Configure();按照 Norla 的示例进行配置调用,结果相同,但无论何时调用,所有日志记录都会停止。

这是重现问题的更新类。

    public class TestSingletonLog4Net
{
    private static volatile TestSingletonLog4Net instance;
    private static object syncRoot = new Object();

    public static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(TestSingletonLog4Net));

    private  TestSingletonLog4Net()
    {
        log4net.Config.XmlConfigurator.Configure();

        log.Info("Test write from singleton");
    }
    public static TestSingletonLog4Net Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new TestSingletonLog4Net();
                }
            }

            return instance;
        }
    }
}

我设置了一个小项目来复制问题,这就是正在发生的事情。

  • 如果我使用主 UI 项目中的 log4net 和单例或普通类日志记录工作。
  • 如果我使用子项目库中的 log4net 不是单例日志记录工作。
  • 如果我尝试从子项目库之一中的单例中使用 log4net,所有日志记录都会停止,它不仅不会记录,而且从主项目完成的日志记录也不再有效。

我最初将 log4net 配置作为 app.config 的一部分,但我怀疑这可能是一个问题,所以我将 log4net 配置移动到它自己的配置文件中。

使用 log4net 版本 1.2.11

我也尝试过从构造函数外部调用 log,结果相同。

我的设置重置如下。

以下行就在我的 Program.cs 中 using 语句的下方

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

在每个班级我都用以下方式调用 log4net:

private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

非常感谢任何有关解决方案的建议。

【问题讨论】:

  • 一方面,你的单例实现不是线程安全的......
  • 我最初在使用另一个通过 IOC 容器实现为单例的类时发现了这个问题。我刚刚制作了这个测试类来复制问题而没有 IOC 的阻碍。

标签: c# singleton log4net


【解决方案1】:

您应该只在您的应用程序中调用log4net.Config.XmlConfigurator.Configure(); 一次 次。这应该在主应用程序中调用,而不是在包含单例的类中。

此外,如果您要致电log4net.Config.XmlConfigurator.Configure();,则应删除以下行:

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

【讨论】:

    【解决方案2】:

    我有一个使用 log4net 的单例对象。这就是我正在做的事情。

    在成员声明中:

    public static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(typeof (TestSingletonLog4Net));
    

    在构造函数中:

    log4net.Config.XmlConfigurator.Configure();
    

    就是这样。迄今为止没有任何问题。请让我知道这是否有效。

    【讨论】:

    • 谢谢,尝试了您的示例,更新的代码在上面的帖子中仍然无效。您的单身人士是否在单独的项目中?
    • 刚刚在引用另一个项目中的记录器的解决方案中找到了这个 gem。祝你好运。 log4net.GlobalContext.Properties["LogName"] = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
    猜你喜欢
    • 1970-01-01
    • 2014-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多