73

This is my configuration for 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>

In C# I'm trying to get the name of the log file (which is MyLog.log). I googled and tried many things but failed to do so. Any help?

Thanks!

Philipp M
  • 1,877
  • 7
  • 27
  • 38
Carlo
  • 25,602
  • 32
  • 128
  • 176
  • Are you saying that you're trying to parse the log4net config file in an attempt to get the file name you're logging to? The question doesn't make that clear. What exactly are you trying to do, and what's the problem? – Scott Saad Aug 27 '09 at 21:28
  • I'm trying to get this part of the configuration "", I'm trying to move away from parsing it myself (for now), because I think asp4net may have a built in way to do so, only I can't find it. If not, I will have to do the parsing myself. – Carlo Aug 27 '09 at 21:30

7 Answers7

108

Solution is quite easy in your situation; just use this code:

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

string filename = rootAppender != null ? rootAppender.File : string.Empty;
Noctis
  • 11,507
  • 3
  • 43
  • 82
Yakeen
  • 2,142
  • 1
  • 17
  • 21
  • 2
    i used the same. but (FileAppender)((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root doesnt have an array of Appenders as specified in the above solution. Any ideas ??? – Sandeep Nov 23 '11 at 11:10
  • 1
    What class is "Hierarchy" and wich reference and namespace do I need to use it? – Ephedra Apr 19 '16 at 10:48
  • 2
    using log4net; using log4net.Appender; using log4net.Repository.Hierarchy; – Yakeen Apr 29 '16 at 07:06
38

When having multiple file appenders, you might want to get them by name. Also to make sure to get the appender even if it is not referenced by the root node, the following code helps:

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;
}
falstaff
  • 3,413
  • 2
  • 25
  • 26
  • 4
    **This needs more votes!** Short, elegant and allowing to choose one of the appenders by name. Most of the other solutions I saw here just pick the 1st appender which isn't always correct. According to the question you would use `GetLogFileName("MyLogger")` – Matt Jun 15 '16 at 15:37
  • 6
    The only thing I'd change is to use `rootAppender?.File ?? string.Empty` (the C# 6 **['Elvis' operator](https://csharp.today/c-6-features-null-conditional-and-and-null-coalescing-operators/))** instead of `rootAppender != null ? rootAppender.File : string.Empty`, which is shorter. – Matt Jun 16 '16 at 08:49
  • note that the return value is **full path** of log file – yu yang Jian Aug 01 '18 at 03:06
11

Since I already had a logger defined in the class I just used it. One thing to be aware of is that there may be more than one appender and often the first one is the console (which doesn't have a file). Here is my solution for what its worth.

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;
    }
}

}

N5ARW
  • 111
  • 1
  • 3
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
Andrey Prokhorov
  • 890
  • 2
  • 13
  • 25
0

If your config does not have a <root> node then the above solution will not work for you. Read on.

<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>

This retrieves the log file:

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

The (hopefully) crash-proof version:

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;
}

Finally, if you get stuck with log4net add this to your <appSettings> section:

<add key="log4net.Internal.Debug" value="true"/>
Polluks
  • 525
  • 2
  • 8
  • 19
stevieg
  • 652
  • 4
  • 14
0
((log4net.Appender.FileAppender)(_log.Logger.Repository.GetAppenders())[0]).File
-1

I didn't find the above code working. This worked for me

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
Nick Mehrdad Babaki
  • 11,560
  • 15
  • 45
  • 70
Jyo Reddy
  • 712
  • 5
  • 10