C#
log4net
logging
.NET
programming

Get log4net log file in C

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

log4net is a popular logging framework for .NET applications that writes log output to files, consoles, databases, and other targets. To get the log file path at runtime, access the FileAppender from the log4net configuration and read its File property. Setting up log4net involves installing the NuGet package, adding an XML configuration section (in App.config, Web.config, or a standalone file), and initializing the logger in your code. This article covers the complete setup, configuration, and programmatic access to log file paths.

Installing log4net

bash
1# NuGet Package Manager Console
2Install-Package log4net
3
4# .NET CLI
5dotnet add package log4net

Configuration

App.config / Web.config

xml
1<?xml version="1.0" encoding="utf-8"?>
2<configuration>
3  <configSections>
4    <section name="log4net"
5             type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
6  </configSections>
7
8  <log4net>
9    <!-- File Appender -->
10    <appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
11      <file value="logs/application.log" />
12      <appendToFile value="true" />
13      <rollingStyle value="Size" />
14      <maxSizeRollBackups value="5" />
15      <maximumFileSize value="10MB" />
16      <staticLogFileName value="true" />
17      <layout type="log4net.Layout.PatternLayout">
18        <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
19      </layout>
20    </appender>
21
22    <!-- Console Appender -->
23    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
24      <layout type="log4net.Layout.PatternLayout">
25        <conversionPattern value="%date %-5level %logger - %message%newline" />
26      </layout>
27    </appender>
28
29    <root>
30      <level value="DEBUG" />
31      <appender-ref ref="FileAppender" />
32      <appender-ref ref="ConsoleAppender" />
33    </root>
34  </log4net>
35</configuration>

Standalone log4net.config File

xml
1<!-- log4net.config -->
2<log4net>
3  <appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
4    <file value="logs/app.log" />
5    <appendToFile value="true" />
6    <rollingStyle value="Date" />
7    <datePattern value="yyyyMMdd" />
8    <layout type="log4net.Layout.PatternLayout">
9      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
10    </layout>
11  </appender>
12
13  <root>
14    <level value="INFO" />
15    <appender-ref ref="FileAppender" />
16  </root>
17</log4net>

Initializing log4net

csharp
1// Option 1: Assembly attribute (reads from App.config)
2[assembly: log4net.Config.XmlConfigurator(Watch = true)]
3
4// Option 2: Assembly attribute (reads from standalone file)
5[assembly: log4net.Config.XmlConfigurator(
6    ConfigFile = "log4net.config", Watch = true)]
7
8// Option 3: Programmatic initialization
9using log4net;
10using log4net.Config;
11
12public class Program
13{
14    private static readonly ILog log = LogManager.GetLogger(typeof(Program));
15
16    static void Main(string[] args)
17    {
18        // Initialize from standalone config file
19        XmlConfigurator.Configure(new FileInfo("log4net.config"));
20
21        log.Info("Application started");
22        log.Debug("Debug message");
23        log.Error("Something went wrong", new Exception("test"));
24    }
25}

Getting the Log File Path at Runtime

csharp
1using log4net;
2using log4net.Appender;
3using log4net.Repository.Hierarchy;
4
5public static string GetLogFilePath()
6{
7    var hierarchy = (Hierarchy)LogManager.GetRepository();
8    var fileAppender = hierarchy.Root.Appenders
9        .OfType<FileAppender>()
10        .FirstOrDefault();
11
12    return fileAppender?.File;
13}
14
15// Usage
16string logPath = GetLogFilePath();
17Console.WriteLine($"Log file: {logPath}");
18// Output: Log file: C:\MyApp\logs\application.log

Getting All Log File Paths

csharp
1public static List<string> GetAllLogFilePaths()
2{
3    var hierarchy = (Hierarchy)LogManager.GetRepository();
4
5    return hierarchy.Root.Appenders
6        .OfType<FileAppender>()
7        .Select(a => a.File)
8        .ToList();
9}

Getting a Named Appender's File Path

csharp
1public static string GetLogFileByAppenderName(string appenderName)
2{
3    var hierarchy = (Hierarchy)LogManager.GetRepository();
4
5    var appender = hierarchy.Root.Appenders
6        .OfType<FileAppender>()
7        .FirstOrDefault(a => a.Name == appenderName);
8
9    return appender?.File;
10}
11
12// Usage
13string errorLogPath = GetLogFileByAppenderName("ErrorFileAppender");

Common Appender Types

AppenderDescription
FileAppenderWrites to a single file
RollingFileAppenderRolls files by size or date
ConsoleAppenderWrites to stdout
ColoredConsoleAppenderColored console output
AdoNetAppenderWrites to a database
SmtpAppenderSends logs via email

Log Levels

csharp
1private static readonly ILog log = LogManager.GetLogger(typeof(MyClass));
2
3log.Debug("Detailed diagnostic info");      // Level: DEBUG
4log.Info("Normal operation messages");       // Level: INFO
5log.Warn("Potential issues");                // Level: WARN
6log.Error("Error occurred", exception);      // Level: ERROR
7log.Fatal("Application cannot continue");    // Level: FATAL

Levels are ordered: DEBUG < INFO < WARN < ERROR < FATAL. Setting the root level to WARN suppresses DEBUG and INFO messages.

Common Pitfalls

  • Forgetting to call XmlConfigurator.Configure(): log4net does nothing until explicitly configured. Without calling Configure() or using the assembly attribute, no log output is produced and GetLogFilePath() returns null.
  • Using a relative file path without understanding the base directory: The <file value="logs/app.log" /> path is relative to the application's working directory, which may differ from the executable's directory. Use <file value="${APPDATA}/MyApp/logs/app.log" /> or an absolute path for predictable locations.
  • Not setting Watch = true in production: Without Watch = true, changes to the log4net configuration require an application restart. Setting Watch = true in the assembly attribute enables hot-reloading of log configuration.
  • Querying the file path before configuration is loaded: If you call GetLogFilePath() before XmlConfigurator.Configure() runs, the repository has no appenders and returns null. Ensure configuration runs early in application startup.
  • Mixing App.config sections with standalone config files: If both App.config contains a <log4net> section and you also configure from a standalone file, the standalone file overwrites the embedded config. Use one approach consistently.

Summary

  • Install log4net via NuGet and configure with XML in App.config or a standalone log4net.config file
  • Initialize with XmlConfigurator.Configure() or the [assembly: XmlConfigurator] attribute
  • Get the log file path at runtime by casting LogManager.GetRepository() to Hierarchy and accessing FileAppender.File
  • Use RollingFileAppender for production — it handles file rotation by size or date automatically
  • Always call configuration before accessing appender properties, and use absolute paths for predictable log file locations

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.