How to specify common application data folder for log4net?
Asked Answered
R

6

37

I want log4net to write log files (using RollingFileAppender) to a subfolder of the common application data folder (e.g. C:\Documents and Settings\All Users\Application Data\Company\Product\Logs).
However, on Win XP, there is no environment variable that specifies this folder. We have %ALLUSERSPROFILE%, we have %APPDATA%, but there is nothing like %ALLUSERSAPPDATA%.
Programatically, I could use Environment.SpecialFolder.CommonApplicationData, but I need to put it in the log4net config, something like this:

<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
   <file value="%ALLUSERSAPPDATA%\Company\Product\Logs\error.log" />
</appender>

OK, we could define this in our setup, but maybe someone comes up with a better idea?

Rotate answered 22/1, 2009 at 12:51 Comment(2)
please correct the question title spelling "specifiy"Bedpost
Per the link in @codeulike's answer, as of 1.2.11, you can simply use a PatternString expression like %envFolderPath{CommonApplicationData}.Katabolism
S
12

This posting on the log4net mailinglist explains how you can define your own path replacement variables.

Savanna answered 22/1, 2009 at 13:0 Comment(4)
Thanks, this gave me the right idea. I will define a property and use a PatternString for the folder in the config file.Rotate
You can use solution from accepted answer from here #1536236 . This solution is working on Win Xp and all folowing systemsSpeculator
Can you summarize the main ideas from the link?Vanmeter
Link-only answer can use any value once the link goes dead. Please summarize the solution provided in that linked resource.Partan
G
36

We just use this:

<param name="File" value="${ALLUSERSPROFILE}/Company/Product/Logs/error.log"/>

It works great.


This line can simply be inserted into your current appender configuration:
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
   <param name="File" value="${ALLUSERSPROFILE}/Company/Product/Logs/error.log"/>
</appender>
Gilbertegilbertian answered 11/12, 2009 at 17:27 Comment(2)
This solution will not work on Win Xp, since there is no valid resolving for ${ALLUSERSPROFILE}. Solution for all systems (Win Xp and following) is in accepted answer from here #1536236Speculator
In Windows XP, ALLUSERSPROFILE does exist and defaults to C:\Documents and Settings\All Users, so this should work, unless you have a permissions issue.Gilbertegilbertian
S
12

This posting on the log4net mailinglist explains how you can define your own path replacement variables.

Savanna answered 22/1, 2009 at 13:0 Comment(4)
Thanks, this gave me the right idea. I will define a property and use a PatternString for the folder in the config file.Rotate
You can use solution from accepted answer from here #1536236 . This solution is working on Win Xp and all folowing systemsSpeculator
Can you summarize the main ideas from the link?Vanmeter
Link-only answer can use any value once the link goes dead. Please summarize the solution provided in that linked resource.Partan
R
12

Here's the full code from the log4net mailing list that pilif linked to:

Basically the method is to implement a custom pattern converter for the log4net config file.

First add this class to your project:

public class SpecialFolderPatternConverter : log4net.Util.PatternConverter
{
    override protected void Convert(System.IO.TextWriter writer, object state)
    {
        Environment.SpecialFolder specialFolder = (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), base.Option, true);
        writer.Write(Environment.GetFolderPath(specialFolder));
    }
}

Then set up the File parameter of your FileAppender as follows:

<file type="log4net.Util.PatternString">
    <converter>
      <name value="folder" />
      <type value="MyAppName.SpecialFolderPatternConverter,MyAppName" />
    </converter>
    <conversionPattern value="%folder{CommonApplicationData}\\SomeOtherFolder\\log.txt" />
</file>

Basically the %folder tells it to look at the converter called folder which points it to the SpecialFolderPatternConverter class. It then calls Convert on that class, passing in the CommonApplicationData (or whatever) enum value.

Apparently in the next release of log4net (1.2.11) there will be a simpler method, as described here.

Recalesce answered 8/12, 2010 at 16:36 Comment(1)
how to use this converter(which I also found in log4net official site but did not succeed) in <param name="File" section(in which @Gilbertegilbertian mentioned)Spiroid
J
4

In the current log4net version (2.0.8.0) you could simply use

<file value="${ProgramData}\myFolder\LogFiles\" /> for C:\ProgramData

${LocalAppData} for C:\Users\user\AppData\Local\

and ${AppData} for C:\Users\user\AppData\Roaming\

Jaunty answered 13/9, 2018 at 16:46 Comment(0)
S
3

Complete and working solution - content of my Log4net.config file. In actual version of Log4Net there is no need for writing own pattern converter anymore

<?xml version="1.0"?>
<log4net>
  <root>
    <level value="INFO" />
    <appender-ref ref="LogFileAppender" />
  </root>
  <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" >
    <file type="log4net.Util.PatternString" value="%envFolderPath{CommonApplicationData}\\MyProject\\Logs\\log.txt" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="100MB" />
    <layout type="log4net.Layout.PatternLayout">
      <ConversionPattern type="log4net.Util.PatternString" value="%%-5p %%d{yyyy-MM-dd HH:mm:ss} - %%m%%n" />
    </layout>
  </appender>
</log4net>
Speculator answered 12/6, 2014 at 18:9 Comment(1)
Tried this, it just created a goofy folder with a percent in it under my web application.Aiello
L
1

Now (in 2018 FEB) as per log4net version 2.0.8.0.

You can use without any converter to get Environment Variables as follows.

<file type="log4net.Util.PatternString" value="%envFolderPath{CommonApplicationData}\\mylogfile.txt" />

Refer: log4net.Util.PatternString class documentation for more details.

Langevin answered 19/2, 2018 at 11:1 Comment(1)
%env{LOCALAPPDATA} and not %envFolderPath{LOCALAPPDATA} worked for me.Melodeemelodeon

© 2022 - 2024 — McMap. All rights reserved.