How can I change the file location programmatically?

Viewed 97129

I am totally new to Log4net. I have managed to get something going by adding a config file and simple logging. I have hardcoded the value to be "C:\temp\log.txt" but this is not good enough.

The logs must go to the special folders

path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);

and this path changes depending whether you are using Windows Server 2008 or Windows XP or Vista etc...

How can I just change the location of the file in log4net programmatically?

This is what I have done:

<configSections>
<section name="log4net"
         type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<log4net>         
    <root>
        <level value="DEBUG" />
        <appender-ref ref="LogFileAppender" />
    </root>
    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
        <param name="File" value="C:\temp\log.txt" />
        <param name="AppendToFile" value="true" />
        <rollingStyle value="Size" />
        <maxSizeRollBackups value="10" />
        <maximumFileSize value="10MB" />
        <staticLogFileName value="true" />
        <layout type="log4net.Layout.PatternLayout">
            <param name="ConversionPattern" value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n" />
        </layout>
    </appender>
</log4net>

class Program
{
    protected static readonly ILog log = LogManager.GetLogger(typeof(Program));

    static void Main(string[] args)
    {
        log4net.Config.XmlConfigurator.Configure();
        log.Warn("Log something");

        path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);


        // How can I change where I log stuff?
    }
}

Just need to figure out how I can change to log stuff to where I want to.

Any suggestions? Thanks a lot

13 Answers

JackAce's answer, just more concise using Linq:

C#

XmlConfigurator.Configure();
var appender = (LogManager.GetRepository() as Hierarchy).Root.Appenders
    .OfType<FileAppender>()
    .First();

appender.File = logPath;
appender.ActivateOptions();

VB.NET

XmlConfigurator.Configure()
Dim appender = CType(LogManager.GetRepository(), Hierarchy).Root.Appenders _
    .OfType(FileAppender)() _
    .First()

appender.File = logPath
appender.ActivateOptions()

In the current version of Log4Net (2.0.8.0) you could simply use <file value="${ProgramData}\myFolder\LogFiles\" /> for C:\ProgramData\.. and ${LocalAppData} for C:\Users\user\AppData\Local\

Those who are looking to set the file path to Project root dicrectory Path can refer below code. I have implemented this in .NET 5 API Project

Changes for Log4net.config file. Remember type="log4net.Util.PatternString" this line is very important

<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="%property{LoggerFilePath}\Logs\server.log" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<maxSizeRollBackups value="2" />
<layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date %5level %logger.%method [%line] - MESSAGE: %message%newline %exception" />
</layout>

Then, in Program.cs file

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging((context,loggerBuilder) => 
        {
            log4net.GlobalContext.Properties["LoggerFilePath"] = context.HostingEnvironment.ContentRootPath;
            loggerBuilder.ClearProviders();
            loggerBuilder.AddLog4Net();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Thanks!

//Make sure you include System.Linq
//Though is an answer to old question, 
//but more concise, just two lines of code. 
((FileAppender)LogManager.GetRepository().GetAppenders().Select(a => a).First()).File = @"C:\log.txt";
((FileAppender)LogManager.GetRepository().GetAppenders().Select(a => a).First()).ActivateOptions();
Related