tags:

views:

3664

answers:

5

Hi, 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=Enviroment.GetFolderPath(Enviroment.SpecialFolder.CommonApplicationData;

and this path changes depending whether you are in windows Server 2008 or winxp 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=Enviroment.GetFolderPath(Enviroment.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

A: 

You need to dig through your logger's IAppenders and set the FileAppender.File to your required output path.

Here's a really good example.

Cam Soper
+8  A: 

log4net can handle this for you. Any appender property of type string can be formatted, in this case, using the log4net.Util.PatternString option handler. PatternString even supports the SpecialFolder enum which enables the following elegant config:

<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" >
    <file type="log4net.Util.PatternString" 
        value="%envFolderPath{CommonApplicationData}\\test.txt" />
    ...
</appender>

Here's a unit test that proofs the pudding:

[Test]
public void Load()
{
    XmlConfigurator.Configure();
    var fileAppender = LogManager.GetRepository()
        .GetAppenders().First(appender => appender is RollingFileAppender);

    var expectedFile = 
        Path.Combine(
            Environment.GetFolderPath(
                Environment.SpecialFolder.CommonApplicationData),
                "test.txt");

    Assert.That(fileAppender, 
        Is.Not.Null & Has.Property("File").EqualTo(expectedFile));
}

The following test verifies that log4net actually writes to disk (which basically makes this an "integration" test, not a unit test, but we'll leave it at that for now):

[Test]
public void Log4net_WritesToDisk()
{
    var expectedFile = 
        Path.Combine(
            Environment.GetFolderPath(
                Environment.SpecialFolder.CommonApplicationData),
                "test.txt");

    if (File.Exists(expectedFile))
        File.Delete(expectedFile);

    XmlConfigurator.Configure();

    var log = LogManager.GetLogger(typeof (ConfigTest));
    log.Info("Message from test");

    LogManager.Shutdown();

    Assert.That(File.ReadAllText(expectedFile), 
        Text.Contains("Message from test"));
}

NB: I strongly suggest using the compact property syntax demonstrated in the above sample. Removing all those "<property name=" makes your config that much more readable.

Peter Lillevold
HiTHanks I have tried this but still does not log in application DataI have had a look on the web I have found something called PatternString but I have no idea how to use it.Has anybody got an example?
brix
@brix - My initial answer didn't work, so I had to prove to myself that log4net can do this. PatternString is the solution :)
Peter Lillevold
hi,tried your solution but for some reasons it does not log at all.I have copied what you suggested.Run the app but no file created.Does yours actually create a file?thanks a lot
brix
@brix - it does create the file. One thing to have in mind is that log4net will not always flush data to disk immediately. You should also check that the user running your app have enough permissions in that folder to create and write to files.
Peter Lillevold
%envFolderPath{} does not appear to be part of the current (1.2.10) release of log4net. I had to pull r606477 from their subversion repository to enable this very useful feature. I would expect this to be included in the next (1.2.11) release.
rschuler
A: 

As an alternative to doing this programatically, you can use environment variables and customizable patterns in the configuration file. See this response to a similar question.

Look at "PatternString for pattern based configuration" in the Log4Net V1.2.10 release notes.

Also if you are thinking of writing to a directory such as Enviroment.SpecialFolder.CommonApplicationData you need to consider:

  • Will all instances of your application for all users have write access to the log file? E.g. I don't believe non-administrators will be able to write to Enviroment.SpecialFolder.CommonApplicationData.

  • Contention if multiple instances of your application (for the same or different users) are attempting to the same file. You can use the "minimal locking model" (see http://logging.apache.org/log4net/release/config-examples.html to allow multiple processes to write to the same log file, but there probably will be a performance impact. Or you could give each process a different log file, e.g. by including the process id in the filename using a customizable pattern.

Joe
A: 

Guys, Thanks for your replies very helpful.

Peter I am going to try whether that works as it's simple and could do the job.

Joe, Thanks for your answer,this is def something i want to dig deeper but time is not on my side if what Peter suggested works than I will be fine for now.

Need to deliver today.

thanks alot

brix
Sorry for a late solution. Hopefully not too late!
Peter Lillevold
@brix - you've managed to create a second account this one - http://stackoverflow.com/users/174863/brix (used to post this answer) and this one - http://stackoverflow.com/users/186134/brix (used to post the question). E-mail [email protected] about getting them merged.
ChrisF
A: 

Hi Peter this is my Log4net file do you see something wrong for some reasons it still does not seem to write to a file

<?xml version="1.0" encoding="utf-8" ?>
  <configuration>
    <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" >
  <file type="log4net.Util.PatternString"   value="%envFolderPath{CommonApplicationData}\\test.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>
 </configuration>

public class Bar { private static readonly ILog Log = LogManager.GetLogger(typeof(Bar));

        public void DoIt()
        {
            const string filePath = @"c:\MyConfigFiles\Log4net.config";
            XmlConfigurator.Configure(new FileInfo(filePath));

            Log.Info("Test");
        }
}
brix