log4net: How to set logger file name dynamically?

45,238

Solution 1

What about to use "%property" to define a dynamic 'tag' to the file name (at runtime) ?

<file type="log4net.Util.PatternString" value="~/App_Data/%property{LogName}" />

Explained here: Best way to dynamically set an appender file path

Solution 2

you can use this function : in this function first get file location that you set in webconfig and after that you can add any path that you want ! like Date ! our Customer ! or .....

WebConfig:

<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="C:\\t4\\"/>
    <appendToFile value="true"/>
    <rollingStyle value="Composite"/>
    <datePattern value="_yyyy-MM-dd.lo'g'"/>
    <maxSizeRollBackups value="10"/>
    <maximumFileSize value="1MB"/>
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date User:%identity IP:%X{addr} Browser: %X{browser} Url: %X{url} [%thread] %-5level %c:%m%n"/>
    </layout>
</appender>

Function:

public static void ChangeFileLocation(string _CustomerName,string _Project)
{
    XmlConfigurator.Configure();
    log4net.Repository.Hierarchy.Hierarchy h =(log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository();

    foreach (IAppender a in h.Root.Appenders)
    {
        if (a is FileAppender)
        {
            FileAppender fa = (FileAppender)a;
            string sNowDate=  DateTime.Now.ToLongDateString();
            // Programmatically set this to the desired location here
            string FileLocationinWebConfig = fa.File;
            string logFileLocation = FileLocationinWebConfig + _Project + "\\" + _CustomerName + "\\" + sNowDate + ".log";

            fa.File = logFileLocation;
            fa.ActivateOptions();
            break;
        }
    }
}

and result like this : C:\t4\TestProject\Customer1\Saturday, August 31, 2013.log

Share:
45,238

Related videos on Youtube

ROBERT RICHARDSON
Author by

ROBERT RICHARDSON

Updated on March 07, 2020

Comments

  • ROBERT RICHARDSON
    ROBERT RICHARDSON over 4 years

    This is a really common question, but I have not been able to get an answer to work. Here is my configuration file:

    <?xml version="1.0" encoding="utf-8"?>
    <log4net>
      <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
        <file value="CraneUserInterface.log" />
        <appendToFile value="true" />
        <maxSizeRollBackups value="90" />
        <rollingStyle value="Size" />
    
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%date - %message%newline" />
        </layout>
      </appender>
    
      <root>
        <level value="DEBUG" />
        <appender-ref ref="RollingFile" />
      </root>
    

    But I need to determine the actual logging file name at run time. I found a nice example here, but when I try to loop through the collection returned by the call to GetIterators(), I find that that collection is empty.

    I need to change the name "CraneUserInterface.log" to "CraneUserInterface_1.log", or 2, or 3, depending on something the program reads at run time. How can I do that?

    Here's my first pass at using the code presented in that sample:

    static bool ChangeLogFileName(string AppenderName, string NewFilename)
    {           
       // log4net.Repository.ILoggerRepository RootRep;
       // RootRep = log4net.LogManager.GetRepository();
       log4net.Repository.ILoggerRepository RootRep = m_logger.Logger.Repository;
       foreach (log4net.Appender.IAppender iApp in RootRep.GetAppenders())
       {
       string appenderName = iApp.Name;
       if (iApp.Name.CompareTo(AppenderName) == 0
           && iApp is log4net.Appender.FileAppender)
       {
           log4net.Appender.FileAppender fApp = (log4net.Appender.FileAppender)iApp;
           fApp.File = NewFilename;
           fApp.ActivateOptions();
           return true; // Appender found and name changed to NewFilename
       }
    }
    return false; // appender not found
    }
    

    Thanks very much!

    • Mitch Wheat
      Mitch Wheat almost 11 years
      Despite reading twice, I have no idea why you would want to do this.
    • ROBERT RICHARDSON
      ROBERT RICHARDSON almost 11 years
      This is for use in a laptop that will be in the cab of a crane in an annealing plant. The plant has 3 cranes. Since I am not at the plant, nor will I be in the near future, I have a simulator that pretends to be all three cranes. There will be 3 instances of this program runniing at the same time. I need to track events for each of the 3 cranes separately, and I probably should avoid any chance of two instances of this program writing to the same log file at the same time.
    • Mitch Wheat
      Mitch Wheat almost 11 years
      I think my gut instinct was right. You're trying to solve the wrong problem.
    • ROBERT RICHARDSON
      ROBERT RICHARDSON almost 11 years
      So what is the right problem?
    • ROBERT RICHARDSON
      ROBERT RICHARDSON almost 11 years
      It turns out the problem isn't in this code at all. The problem was that my call to XmlConfigurator.ConfigureAndWatch() specified a file that the program couldn't see. Once I found that, the call to GetAppenders() returned the appender I expected. My thanks to all who took the time to read this question.
    • Jacob Barnes
      Jacob Barnes over 6 years
      @MitchWheat Will you please elaborate? I'm attempting to do a similar thing, but felt there may be better alternatives, but I'm ignorant to any. Your comment seems to indicate this is the wrong strategy for this problem. I know this is an old comment, I appreciate any response.
  • kleopatra
    kleopatra almost 11 years
    please don't post the exact same answer to multiple questions - they either don't really fit or the question is a duplicate and should be flagged as such