在C#中获取log4net日志文件

73

这是我的log4net配置:

<log4net>
    <appender name="MyLogger" type="log4net.Appender.RollingFileAppender">
        <file value="MyLog.log" />
        <appendToFile value="true" /> 
        <rollingStyle value="Size"/>
        <maxSizeRollBackups value="20"/>
        <maximumFileSize value="1000KB"/>
        <layout type="log4net.Layout.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss},%p,%m%n" />
        </layout>
    </appender>
    <root>
        <level value="DEBUG" />
        <appender-ref ref="MyLogger" />
    </root>
</log4net>

我正在尝试获取日志文件的名称(即MyLog.log)并且使用的是C#语言。我进行了谷歌搜索并尝试了很多方法,但都没成功。有人可以提供帮助吗?

谢谢!


你是在尝试解析log4net配置文件来获取你正在记录的文件名吗?这个问题并没有表述清楚。你究竟想要做什么,遇到了什么问题? - Scott Saad
我正在尝试获取配置的这一部分 "<file value="MyLog.log" />",我试图暂时避免自己解析它,因为我认为 asp4net 可能有内置的方法来完成,只是我找不到。如果没有,我将不得不自己解析。 - Carlo
7个回答

109

在您的情况下,解决方案非常简单; 只需使用此代码:

var rootAppender = ((Hierarchy)LogManager.GetRepository())
                                         .Root.Appenders.OfType<FileAppender>()
                                         .FirstOrDefault();

string filename = rootAppender != null ? rootAppender.File : string.Empty;

2
我用了相同的方法。但是((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root的Appenders数组与上述解决方案中指定的不同。有什么想法吗? - Sandeep
1
“Hierarchy”是哪个类?我需要使用哪个引用和命名空间来调用它? - Ephedra
2
使用 log4net; 使用 log4net.Appender; 使用 log4net.Repository.Hierarchy; - Yakeen

38

当存在多个文件appender时,您可能希望按名称获取它们。 为了确保即使没有被根节点引用也能获取到该appender, 下面的代码可提供帮助:

public static string GetLogFileName(string name)
{
     var rootAppender = LogManager.GetRepository()
                                  .GetAppenders()
                                  .OfType<FileAppender>()
                                  .FirstOrDefault(fa => fa.Name == name);

     return rootAppender != null ? rootAppender.File : string.Empty;
}

4
这需要更多的投票!简短、优雅,并且可以通过名称选择其中一个附加器。我在这里看到的大多数其他解决方案只是选择第一个附加器,这并不总是正确的。根据问题,您将使用GetLogFileName("MyLogger") - Matt
6
我唯一想改变的就是使用rootAppender?.File ?? string.Empty(C# 6的**'Elvis'运算符**),而不是使用rootAppender != null ? rootAppender.File : string.Empty,因为前者更短。请注意,两种表达方式的意思相同,只是前者更加简洁。 - Matt
请注意,返回值是日志文件的完整路径 - yu yang Jian

11

由于我在类中已经定义了一个日志记录器,因此我只是简单地使用了它。需要注意的一点是,可能会有多个追加器,通常第一个是控制台(没有文件)。这是我自己的解决方案。

using log4net;
using log4net.Appender;
using log4net.Repository;

namespace MyNameSpace {
public class MyClass {

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

    public String GetLogFileName() {

        String filename = null;

        IAppender[] appenders = logger.Logger.Repository.GetAppenders();
        // Check each appender this logger has
        foreach (IAppender appender in appenders) {
            Type t = appender.GetType();
            // Get the file name from the first FileAppender found and return
            if (t.Equals(typeof(FileAppender)) || t.Equals(typeof(RollingFileAppender))) {
                filename = ((FileAppender)appender).File;
                break;
            }
        }
        return filename;
    }
}

}


我喜欢这个,只需要进行一些调整以搜索特定的appender/logger。 - daniel_aren

1
        String filename = null;

        Hierarchy hierarchy = LogManager.GetRepository() as Hierarchy;
        Logger logger = hierarchy.Root;

        IAppender[] appenders = logger.Repository.GetAppenders();

        // Check each appender this logger has
        foreach (IAppender appender in appenders)
        {
            Type t = appender.GetType();
            // Get the file name from the first FileAppender found and return
            if (t.Equals(typeof(FileAppender)) || t.Equals(typeof(RollingFileAppender)))
            {
                filename = ((FileAppender)appender).File;
                break;
            }
        }

        System.Diagnostics.Process.Start(filename); //for example, open file in notepad

0
((log4net.Appender.FileAppender)(_log.Logger.Repository.GetAppenders())[0]).File

0
如果您的配置文件中没有<root>节点,则上述解决方案对您无效。请继续阅读。
<log4net>
  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="${LOCALAPPDATA}\Anonymous.log" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="2000KB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    </layout>
  </appender>
  <logger name="AnonymousLog">
    <level value="All" />
    <appender-ref ref="RollingFileAppender" />
  </logger>
</log4net>

这将检索日志文件:

string path = (LogManager.GetCurrentLoggers()[0].Logger.Repository.GetAppenders()[0] as FileAppender).File;

(希望)无崩溃版本:

string path = null;
if (LogManager.GetCurrentLoggers().Length > 0 && LogManager.GetCurrentLoggers()[0].Logger.Repository.GetAppenders().Length > 0)
{
    path = (LogManager.GetCurrentLoggers()[0].Logger.Repository.GetAppenders()[0] as FileAppender).File;
}

最后,如果您在使用log4net时遇到问题,请将以下内容添加到您的部分:
<add key="log4net.Internal.Debug" value="true"/>

-2

我发现上面的代码不起作用。 这个对我有用

var filename= ((log4net.Appender.FileAppender)(((log4net.Appender.IAppender[])((((((log4net.Repository.Hierarchy.Hierarchy)((((log4net.Core.LoggerWrapperImpl)(log)).Logger).Repository)).Root).Hierarchy.Root).Appenders).SyncRoot))[0])).File

16
哇...那段代码看起来真是太复杂了!我立刻就对这种样子的代码产生了不信任感。 - Keith Pinson
这段代码中的 (log4net.Core.LoggerWrapperImpl)(log) 是从哪里来的? - Nima Soroush

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接