log4net 输出未出现在某些测试中 - 如何解决?

log4net output not appearing in some tests - how work around?

我有 100 个单元测试。我的大部分日志记录工作正常(即出现在 ReSharper 和 VS 测试运行器输出 windows 中)。然而,非常奇怪的是,一些测试始终无法使用 log4net 写入输出 Window(显然是由于 0 appenders)。我将其追踪到引用的 class.

中的私有记录器字段

为什么一个 class(例如,FooA)中私有记录器字段的存在会中断另一个测试 class(例如,FooOtherTest)中的记录?这只是 log4net 中的一个错误吗? 作用机制是什么? (所以我可以避免它或解决它......因为由于间接级别,当它发生时真的很难在代码中追踪)。

这 2 个文件位于 2 个不同的项目中(一个 class 库项目和一个测试项目)。测试项目有一个 log4net.config 文件 w/Build Action = Content and Copy to Output Directory = Copy Always.

VS2017 企业版 15.7.4,log4net 2.0.8.0,C# 4.7.1

这是在 Visual Studio Test Explorer 中也发生的示例。

代码如下:

 using log4net;

 namespace FooBug
 {
    public static class FooA
    {
        // toggle to see symptom come and go (excluded = works fine, included = logging in test class fails)
        //private static readonly ILog Logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public static readonly int fooA = 4;
    }
}

using System;
using FooBug;
using log4net;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace OtherTest
{
    [TestClass]
    public class FooOtherTest
    {
        private static readonly ILog Logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        private static readonly int fooA = FooA.fooA;

        [TestMethod]
        public void Test0()
        {
            Console.WriteLine(@"sanity check to console");
            Logger.Debug("SUCCESS - the logging works right now");

            ConsoleWriteAppenders();
        }

        public static void ConsoleWriteAppenders()
        {
            var appenders = LogManager.GetRepository().GetAppenders();
            Console.WriteLine("appenders.Length = " + appenders.Length);

            foreach (var appender in appenders)
            {
                Console.WriteLine(appender.Name);
            }
        }

    }
}

Is this just a bug in log4net?

如果我认为发生的事情是正确的,那么它就是记录在案的行为。

https://logging.apache.org/log4net/release/faq.html#first-log

If you are configuring log4net by specifying assembly level attributes on your assembly then the configuration will be loaded once the first call to the LogManager.GetLogger is made. It is necessary that the first call to LogManager.GetLogger made during the process (or AppDomain) is made from the assembly that has the configuration attributes. Log4net will look only once and only on the first calling assembly for the configuration attributes.

我怀疑这是因为 FooOtherTest 依赖于 FooA,因此将首先加载 dll,因此记录器将从该 dll 初始化并且找不到测试项目中的配置。

您需要尝试确保第一次记录发生在具有正确属性并且可以找到配置文件的程序集中。

另见Initialize log4Net as early as possible with NUnit(它是关于 NUnit 的,但大多数测试系统都有类似的东西)

@sgmoore 是正确的。我选择的后续解决方法是开始在所有 class 库项目中包含 log4net.config(还需要 AssemblyInfo.cs 中的 XmlConfigurator 行),即使 class 库项目没有应用程序或测试入口点。