【问题标题】:No logging and repository root has appender but Logger has no appender没有日志记录和存储库根有附加程序,但记录器没有附加程序
【发布时间】:2018-10-17 22:53:29
【问题描述】:

我确定我缺少一些基本的东西。我正在尝试启用 log4net 日志记录作为 XUnit 集成测试的一部分,但没有日志文件被写入磁盘。

我尝试使用配置文件和编程方式指定日志配置:

配置文件:

 <log4net>
  <root>
    <level value="INFO" />
    <appender-ref ref="console" />
    <appender-ref ref="file" />
  </root>
  <appender name="file" type="log4net.Appender.RollingFileAppender">
    <file value="mylog.log" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="5" />
    <maximumFileSize value="10MB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
    </layout>
  </appender>
</log4net>

以编程方式

    private void ConfigureAppender()
    {
        var layout = new PatternLayout("%date [%thread] %level %logger - %message%newline");
        var appender = new RollingFileAppender {Name = "file", File = "c:\\temp\\mylog.log", AppendToFile = true, RollingStyle = RollingFileAppender.RollingMode.Size, MaxSizeRollBackups = 5, MaximumFileSize = "10MB", StaticLogFileName = true, Layout = layout};
        var repository = LogManager.GetRepository() as Hierarchy;
        repository.Root.AddAppender(appender);
        repository.Root.Level = Level.Info;
        repository.Configured = true;
        repository.RaiseConfigurationChanged(EventArgs.Empty);
    }

然后我尽可能早地在程序执行中使用类似这样的东西获取记录器(我也尝试过[assembly: XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]):

        var fileInfo = new FileInfo("log4net.config");
        if (!fileInfo.Exists) throw new Exception();
        XmlConfigurator.Configure(fileInfo);
        var log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        log.Fatal("This is a test");

两种方式都没有日志。无论我是通过配置还是以编程方式定义日志记录,当我检查日志对象时,我都会在底部看到屏幕截图。请注意以下几点:

  1. 级别设置已从配置定义中获取。
  2. 存储库根目录具有配置定义中定义的两个附加程序。
  3. Lo​​gger 实例本身没有附加程序。

谁能告诉我我错过了什么?

编辑: 根据 Z.R.T. 的回答,这就是我错过的:

  • 我需要在 log4net.config/app.config 中有一个 logger 元素。
  • 我需要按名称引用记录器,例如LogManager.GetLogger("IntegrationLogger");

一旦我添加了这两个东西,log4net 就开始工作了。唯一的缺点是所有日志都标有“IntegrationLogger”而不是生成日志的类,但这至少可以启动日志记录。

【问题讨论】:

  • 我没有 - 很棒的提示。时间不早了,明天我先去看看。
  • 我实际上只是尝试过 - 将您提供的链接中的内容逐字复制到我的 app.config 中,将 log4net 内容移动到 app.config 中,并更新 FileInfo 实例以使用 app.config ,运行它,然后......纳达。没有 mylog.log,也没有 log4net.txt。 :( 还是个好建议。

标签: c# logging log4net xunit


【解决方案1】:

log4net.config - 如果更新则设置副本或始终复制

<log4net>
  <appender name="SomeRollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="..\\logs\\loginfo.log" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="5" />
    <maximumFileSize value="10MB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
    </layout>
  </appender>
  <appender name="console" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
    </layout>
  </appender>
  <logger name="SomeLogger">
    <level value="INFO" />
    <appender-ref ref="SomeRollingLogFileAppender" />
    <appender-ref ref="console" />
  </logger>
</log4net>

Log.cs

public class Log
{
    private static readonly ILog someLogger = LogManager.GetLogger("SomeLogger");
    static Log()
    {
        if (!UnitTestDetector.IsRunningFromNUnit)
        {
            XmlConfigurator.Configure(new FileInfo("log4net.config"));
        }
        else
        {
            var testDir = TestContext.CurrentContext.TestDirectory;
            XmlConfigurator.Configure(new FileInfo(Path.Combine(testDir,"log4net.config")));
        }
    }

    public static void Info(string msg)
    {
        someLogger.Info(msg);
    }
}

static class UnitTestDetector
{
    static UnitTestDetector()
    {
        foreach (Assembly assem in AppDomain.CurrentDomain.GetAssemblies())
        {
            if (assem.FullName.ToLowerInvariant().StartsWith("nunit.framework"))
            {
                IsRunningFromNUnit = true;
                break;
            }
        }
    }

    public static bool IsRunningFromNUnit { get; } = false;
}

Program.cs

[TestFixture]
class Program
{

    static void Main()
    {
        Log.Info("test");
        Console.ReadLine();
    }

    [Test]
    public void Test()
    {
        Log.Info("test");
    }
}

【讨论】:

  • 那行得通,我明白我现在错过了什么。将用详细信息更新我的问题。谢谢!
猜你喜欢
  • 2019-12-17
  • 1970-01-01
  • 1970-01-01
  • 2015-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-09
  • 1970-01-01
相关资源
最近更新 更多