user20358
user20358

Reputation: 14766

Programatically configuring log4net to write to separate log files

I am following this example to programatically configure log4net. However since I want to log information separately and errors separately I modified the setup method as below

public static void Setup()
{
    Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();

    PatternLayout patternLayout = new PatternLayout();
    patternLayout.ConversionPattern = "%date [%thread] %-5level %logger - %message%newline";
    patternLayout.ActivateOptions();

    RollingFileAppender info = new RollingFileAppender();
    info.AppendToFile = true;
    info.File = @"c:\Info\infolog.log";
    info.Layout = patternLayout;
    info.MaxSizeRollBackups = 5;
    info.MaximumFileSize = "1GB";
    info.RollingStyle = RollingFileAppender.RollingMode.Size;
    info.StaticLogFileName = true;
    info.ActivateOptions();
    info.Name = "info";



    RollingFileAppender error = new RollingFileAppender();
    error.AppendToFile = true;
    error.File = @"c:\Error\errorlog.log" ;
    error.Layout = patternLayout;
    error.MaxSizeRollBackups = 5;
    error.MaximumFileSize = "1GB";
    error.RollingStyle = RollingFileAppender.RollingMode.Size;
    error.StaticLogFileName = true;
    error.ActivateOptions();
    error.Name = "error";

    hierarchy.Root.AddAppender(info);
    hierarchy.Root.AddAppender(error);

    MemoryAppender memory = new MemoryAppender();
    memory.ActivateOptions();
    hierarchy.Root.AddAppender(memory);

    hierarchy.Root.Level = Level.Info;
    hierarchy.Configured = true;
}

and in my code I initialized it as below

public class myclass
{
     ILog errorLog ;
     ILog infoLog ;
     public myclass()
     {
          errorLog = LogManager.GetLogger("error");
          infoLog = LogManager.GetLogger("info");       
     }


     public void LogMessage()
     {
         infoLog.Warn("warn message");
         errorLog.Error("Error message");
     }

}

The problem is whatever I print to infoLog gets printed to both the infolog.log file as well as the errorlog.log file and the same vice versa. What is wrong in my configuration?

Upvotes: 1

Views: 673

Answers (1)

stuartd
stuartd

Reputation: 73303

You've added both file appenders to the root logger, which means any loggers you create inherit from that.

What you need to do is be able to get a specific logger with the right appender. I don't know of a way to define loggers programatically in the same way as you can define them in config, but there are ways round that.

One is to take advantage of the fact that log4net caches loggers: if you create a logger and configure it once, then when you request the logger with the same name, the configured logger is returned.

So in your code, add this after the hierarchy.Configured = true; call:

ILog log = LogManager.GetLogger("error");
Logger logger = (Logger)log.Logger;
logger.Additivity = false;
logger.AddAppender(error); 

log = LogManager.GetLogger("info");
logger = (Logger)log.Logger;
logger.Additivity = false;
logger.AddAppender(info); 

Note: Additivity = false instructs the logger not to inherit appenders from it's parent, in this case the root logger. If you remove the root logger config, this isn't required.

Upvotes: 3

Related Questions