Question

I would like to set the full path and the file name for the log file (I use log4net) and I would like to use the c:\ProgramData\Logs folder. I get the path of the ProgramData folder using the environment variable #PROGRAMDATA#.

I would like to set the path for the log file in the next way: I use a property in the App.config, and I set the value for this property in the class where I do the loggings.

My App.config file:

<configuration>
...
    <log4net>
        <appender name="Console" type="log4net.Appender.ConsoleAppender">
            <layout type="log4net.Layout.PatternLayout">
                <!-- Pattern to output the caller's file name and line number -->
                <conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
            </layout>
        </appender>
        <appender name="AppRollingFile" type="log4net.Appender.RollingFileAppender">
          <file type="log4net.Util.PatternString" value="%property{ProgramDataPath}\Logs\Application.log" />
          <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
            <appendToFile value="true" />
            <maximumFileSize value="1000KB" />
            <maxSizeRollBackups value="5" />

            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="[%-5level][%d{yy-MM-dd HH:mm:ss,fff}] %m%n" />
            </layout>
        </appender>
        <root>
            <level value="DEBUG" />
            <appender-ref ref="Console" />
            <appender-ref ref="AppRollingFile" />
        </root>
    </log4net>
</configuration>

And the code where I set the property:

static void Main(string[] args)
{
    log4net.GlobalContext.Properties["ProgramDataPath"] = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
    log4net.Config.XmlConfigurator.Configure();

My problem is that an empty log file is created before the value of the property is set (then the property it is null). The initialization of the log4net it is done before entering in the main function of the class where I set the property, so it will always be created an empty file in the application's folder: bin\Debug(null)\Logs\Application.log. After I set the property, everything works fine, because another Apllication.log file will be created in c:\ProgramData\Logs folder.

My question is that how can I set the value of the property before the empty log file is created/before entering in the main function of the class where I set the property, or what other solution is there?

Using the environment variable in the App.config as it is shown below did not work.

<file type="log4net.Util.PatternString" value="${PROGRAMDATA}\Logs\Application.log"/>
Was it helpful?

Solution

Try

<file type="log4net.Util.PatternString" value="${ProgramData}\Logs\Application.log"/>

The environment variables are case sensitive, which is why ${PROGRAMDATA} does not work.

OTHER TIPS

Removing the assembly attribute should fix the problem:

[assembly: log4net.Config.XmlConfigurator(Watch=true)]

If you want log4net to watch app.config for configuration changes, use this code (I prefer to put log4net configuration in a separate log4net.config file for easier reuse):

log4net.GlobalContext.Properties["ProgramDataPath"] = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
FileInfo configFile = new FileInfo(Process.GetCurrentProcess().MainModule.FileName + ".config");
log4net.Config.XmlConfigurator.ConfigureAndWatch(configFile);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top