3

I want to do this:

Configure Log4net to write to multiple files

But I want to use code-as-configuration. How do I do this?

Here's what I've tried:

// Configure log A
Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();

PatternLayout patternLayout = new PatternLayout();
patternLayout.ConversionPattern = "%date %level %logger: %message%newline";
patternLayout.ActivateOptions();

RollingFileAppender appender = new RollingFileAppender();
appender.Name = @"MyLogA";
appender.File = @"C:\Temp\MyLogs\A.log";
appender.AppendToFile = true;
appender.MaxSizeRollBackups = 2;
appender.RollingStyle = RollingFileAppender.RollingMode.Size;
appender.MaximumFileSize = "10MB";
appender.Layout = patternLayout;
appender.LockingModel = new FileAppender.MinimalLock();
appender.StaticLogFileName = true;
appender.ActivateOptions();
hierarchy.Root.AddAppender(appender);

hierarchy.Configured = true;

// Configure log B
Hierarchy hierarchyB = (Hierarchy)LogManager.GetRepository();

PatternLayout patternLayoutB = new PatternLayout();
patternLayoutB.ConversionPattern = "%date %level %logger: %message%newline";
patternLayoutB.ActivateOptions();

RollingFileAppender appenderB = new RollingFileAppender();
appenderB.Name = @"MyLogB";
appenderB.File = @"C:\Temp\MyLogs\B.log";
appenderB.AppendToFile = true;
appenderB.MaxSizeRollBackups = 2;
appenderB.RollingStyle = RollingFileAppender.RollingMode.Size;
appenderB.MaximumFileSize = "10MB";
appenderB.Layout = patternLayout;
appenderB.LockingModel = new FileAppender.MinimalLock();
appenderB.StaticLogFileName = true;
appenderB.ActivateOptions();
hierarchyB.Root.AddAppender(appenderB);

hierarchyB.Configured = true;


// Test Log A

var loggerA = log4net.LogManager.GetLogger("MyLogA");

loggerA.Info("TestA");
loggerA.Info("TestA");
loggerA.Info("TestA");
loggerA.Info("TestA");
loggerA.Info("TestA");

// Test Log B
var loggerB = log4net.LogManager.GetLogger("MyLogB");
loggerB.Info("TestB");
loggerB.Info("TestB");
loggerB.Info("TestB");
loggerB.Info("TestB");
loggerB.Info("TestB");

But when I do this, all ten log messages get dumped into both LogA and LogB, they don't go to their respective individual log files.

How can I get this to work?

Community
  • 1
  • 1
Jay Sullivan
  • 17,332
  • 11
  • 62
  • 86

1 Answers1

3

I don't fully understand why, but the following fixes the problem:

var hierarchy = (Hierarchy)LogManager.GetRepository();
hierarchy.Threshold = Level.Debug;

// Configure LoggerA
string logNameA = @"A";
string fileNameA = @"C:\Temp\MyLogs\A.log";
var loggerA = hierarchy.LoggerFactory.CreateLogger("LoggerA");
loggerA.Hierarchy = hierarchy;
loggerA.AddAppender(CreateFileAppender(logNameA,fileNameA));
loggerA.Repository.Configured = true;
loggerA.Level = Level.Debug;

ILog logA = new LogImpl(loggerA);

// Configure LoggerB

string logNameB = @"B";
string fileNameB = @"C:\Temp\MyLogs\B.log";
var loggerB = hierarchy.LoggerFactory.CreateLogger("LoggerB");
loggerB.Hierarchy = hierarchy;
loggerB.AddAppender(CreateFileAppender(logNameB, fileNameB));
loggerB.Repository.Configured = true;
loggerB.Level = Level.Debug;

ILog logB = new LogImpl(loggerB);

// Test

logA.Error("logA");
logA.Error("logA");
logA.Error("logA");
logA.Error("logA");
logA.Error("logA");

logB.Error("logB");
logB.Error("logB");
logB.Error("logB");
logB.Error("logB");
logB.Error("logB");
logB.Error("logB");

Where CreateFileAppender() is:

private static IAppender CreateFileAppender(string name, string fileName)
{
    PatternLayout patternLayout = new PatternLayout();
    patternLayout.ConversionPattern = "%date %level %logger: %message%newline";
    patternLayout.ActivateOptions();

    RollingFileAppender appender = new RollingFileAppender();
    appender.Name = name;
    appender.File = fileName;
    appender.AppendToFile = true;
    appender.MaxSizeRollBackups = 2;
    appender.RollingStyle = RollingFileAppender.RollingMode.Size;
    appender.MaximumFileSize = "10MB";
    appender.Layout = patternLayout;
    appender.LockingModel = new FileAppender.MinimalLock();
    appender.StaticLogFileName = true;
    appender.ActivateOptions();
    return appender;
}
Jay Sullivan
  • 17,332
  • 11
  • 62
  • 86
  • I think it won't work if you do initialization of logB after loggerB is created. It's mostly working only because you created logA object when 2nd appender was not even added. ILog logA = new LogImpl(loggerA); --> moving this line after loggerB is defined should cause the same issue. – Jay Shah Dec 19 '22 at 19:19