6

I need to create loggers dynamically, so with a post from here and the help of reflector I have managed to create loggers dynamically, but I'd like to know if I should worry about something else ... I don't know which implications can have do it.

public static ILog GetDyamicLogger(Guid applicationId)
{
    Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
    RollingFileAppender roller = new RollingFileAppender();
    roller.LockingModel = new log4net.Appender.FileAppender.MinimalLock();
    roller.AppendToFile = true;
    roller.RollingStyle = RollingFileAppender.RollingMode.Composite;
    roller.MaxSizeRollBackups = 14;
    roller.MaximumFileSize = "15000KB";
    roller.DatePattern = "yyyyMMdd";
    roller.Layout = new log4net.Layout.PatternLayout();
    roller.File = "App_Data\\Logs\\"+applicationId.ToString()+"\\debug.log";
    roller.StaticLogFileName = true;

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

    roller.Layout = patternLayout;
    roller.ActivateOptions();

    // this will add this appender to all logger created by LogManager.GetLogger(...)
    //hierarchy.Root.AddAppender(roller);

    // this will change all Loggers level to Level.All
    //hierarchy.Root.Level = Level.All;
    hierarchy.Configured = true;

    DummyLogger dummyILogger = new DummyLogger(applicationId.ToString());
    dummyILogger.Hierarchy = hierarchy;
    dummyILogger.Level = log4net.Core.Level.All;
    dummyILogger.AddAppender(roller);

    return new LogImpl(dummyILogger);
}

internal sealed class DummyLogger : Logger
{
    // Methods
    internal DummyLogger(string name)
        : base(name)
    {
    }
}
Jason Aller
  • 3,541
  • 28
  • 38
  • 38
vtortola
  • 34,709
  • 29
  • 161
  • 263

2 Answers2

2

I would say that you don't have to worry about creating loggers in code. It's one of the supported methods of creating them. You do lose the ability to change things while the application is running (unless you write the code for it). That's just one of the benefits of using config files.

jvilalta
  • 6,679
  • 1
  • 28
  • 36
  • I was worried because LoggerImpl is "internal", so apparently is not supposed to be instantiated. Then I created a copy (DummyLogger) with the same implementation and I use it to create an ILogImpl, but I didn't know if log4net is avoiding you create instances on your own for any specific reason :P – vtortola Apr 16 '10 at 19:47
0

One thing I noticed is a logger created this way is not "properly" entered into the log hierarchy (LogManager.GetLogger will not return it). However, if instead of dummyILogger.Hierarchy = hierarchy;, I use hierarchy.GetLogger(string ILoggerFactory) thusly, it fixes the problem:

    //End of the GetDyamicLogger function
    hierarchy.GetLogger(loggerName, new DynamicLoggerFactory(loggerName, dummyILogger));
    return new LogImpl(dummyILogger);
}

/// <summary>
/// Dummy <c>ILoggerFactory</c> implementation used by <c>Hierarchy.GetLogger</c>.
/// </summary>
internal sealed class DynamicLoggerFactory : ILoggerFactory
{
    private readonly string name;
    private readonly Logger logger;
    public DynamicLoggerFactory(string name, Logger logger) { this.name=name; this.logger=logger; }
    
    public Logger CreateLogger(log4net.Repository.ILoggerRepository repository, string name)
    {
        if(name != this.name) { throw new ArgumentOutOfRangeException("name", name, "Unexpected logger name queried."); }
        return this.logger;
    }
}

With this, LogManager.GetLogger will return the dynamically-created logger.

Medinoc
  • 6,577
  • 20
  • 42