0

I want to create many different loggers each writing to their own file.

How can I go about cloning my already configured appender, just change the name and file it uses, such that I can control all of them from my configuration in one place?

What I have so far looks like:

public Client(string host, int port, string sessionId, TimeSpan timeoutMilliseconds, TimeSpan reconnectAttemptInterval)
{
    //SNIP

    // Create an individual logger for each client
    string loggerName = "Client #" + _id.ToString();
    string logFilename = loggerName + ".log";

    var hierarchy = (Hierarchy)LogManager.GetRepository();
    var logger = hierarchy.LoggerFactory.CreateLogger((ILoggerRepository)hierarchy, loggerName);
    logger.Hierarchy = hierarchy;

    // Get the appenders from config
    var consoleAppender = (ConsoleAppender)LogManager.GetRepository().GetAppenders().First(x => x.Name == "Console");
    var rollingAppender = (RollingFileAppender)LogManager.GetRepository().GetAppenders().First(x => x.Name == "RollingFile");

    // Create the per client appenders
    // TODO - Instead, clone this from the rolling appender in the config and change its name and its file.
    //        That way we can configure all appenders without a rebuild
    var fileAppender = new RollingFileAppender
    {
        Name = loggerName + "Appender",
        File = logFilename,
        LockingModel = new FileAppender.MinimalLock(),
        AppendToFile = false,
        RollingStyle = RollingFileAppender.RollingMode.Size,
        MaxSizeRollBackups = 20,
        MaximumFileSize = "50MB",
        StaticLogFileName = true,
        Layout = new log4net.Layout.PatternLayout("%-5p %d [%t] %m %n")
    };
    fileAppender.ActivateOptions();
    logger.AddAppender(fileAppender);
    logger.AddAppender(consoleAppender);

    logger.Level        = Level.All;     // See appender for filtering
    hierarchy.Threshold = Level.Fatal;

    logger.Repository.Configured = true;

    _log = new LogImpl(logger);
    _log.Debug(string.Format("{0} has been created.", loggerName));
}

One user has suggested this is a duplicate question Deep cloning objects

I don't see how any of the solutions listed are applicable, because log4net is a 3rd party library and I cannot implement ICloneable or ISerializable in a third party's source.

Christopher Pisz
  • 3,757
  • 4
  • 29
  • 65
  • Possible duplicate of [Deep cloning objects](https://stackoverflow.com/questions/78536/deep-cloning-objects) – Marisa Dec 08 '17 at 17:12
  • @Marisa Log4Net is a third party library... No solutions at your linked post will address this question. I cannot implement ICloneable or ISerialziable in a third party's library.... – Christopher Pisz Dec 08 '17 at 17:20

1 Answers1

0

AppenderCollection implements ICloneable so you could do:

// Copies the appenders in the default repository
AppenderCollection copyAppenders = new AppenderCollection(LogManager.GetRepository().GetAppenders()).Clone() as AppenderCollection;

foreach (IAppender appender in copyAppenders)
{
    // Assuming we only have a RollingFileAppender
    RollingFileAppender file = appender as RollingFileAppender;
    file.Name = "FooBar";
    ...
    file.ActivateOptions();
}
Jimenemex
  • 3,104
  • 3
  • 24
  • 56