【问题标题】:log4net fallback appender configuration in case of missing config file?如果缺少配置文件,log4net 后备附加程序配置?
【发布时间】:2012-06-27 11:22:22
【问题描述】:

我有一个广泛使用 log4net 的 C# (.NET 3.5) 应用程序。 log4net 配置位于app.config 文件中。

AssemlyInfo.cs 中使用[assembly: XmlConfigurator(Watch = true)] 完成配置 应用程序使用单个应用程序范围的记录器实例,在记录器包装类的静态构造函数中实例化:

public class Logger{
    //....
    private static readonly ILog logger;
    static Logger()
    {
        logger = LogManager.GetLogger(Assembly.GetEntryAssembly().GetName().Name);

        AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
    }
    //....
}

该应用程序旨在通过调度程序在远程服务器上运行,无需人工,独自在黑暗中。 :) 问题是,如果缺少配置文件,它只会静默崩溃(没有 log4net 配置 => 没有日志记录)。

有没有办法检查配置中是否有任何附加程序,如果没有 - 以编程方式添加某种后备附加程序。

我是 log4X 记录器家族的新手,所以,如果我要问一些琐碎的问题 - 请善待,log4net 文档真的很糟糕。 :)

【问题讨论】:

标签: c# log4net config


【解决方案1】:

好的,这个问题已经在谷歌上,我已经找到了答案,所以我就把它留在这里。 :)

操作附加程序的关键是IAppenderAttachable 接口,因为它实现了AddAppenderremoveAppender 方法。

LogManager.GetLogger() 返回的是ILog 的一个实例,它又包含属性LoggerILog.Logger 返回的对象是一个Logger 类实例。 Logger 类实现IAppenderAttachable 接口并包含Repository 属性以提取记录器的存储库。 Repository 有方法 GetAppenders,它返回 AppenderCollection 类实例(实现 ICollectionIListIenumerable 等)以及记录器的所有活动附加程序。

总结一下:

//no need to put it in the static constructor, but in my case it is so
static Logger() 
{
    logger = LogManager.GetLogger(...);
    if (logger.Logger.Repository.GetAppenders().Length == 0) {
        (logger.Logger as IAppenderAttachable).AddAppender(CreateConsoleAppender());
    }
}

private static ConsoleAppender CreateConsoleAppender()
{
    var appender = new ConsoleAppender();
    appender.Layout = CreateDefaultLayout();
    appender.AddFilter(CreateDefaultFilter());
    appender.ActivateOptions(); // if omitted - throws an excpetion
    log4net.Config.BasicConfigurator.Configure(appender); //if omitted - no errors, but logging does not work
    return appender;
}

private static ILayout CreateDefaultLayout()
{
    PatternLayout layout = new PatternLayout();
    layout.ConversionPattern = "%d{yyyy-MM-dd hh:mm:ss} - %level %m%n";
    layout.ActivateOptions();
    return layout;
}


private static IFilter CreateDefaultFilter()
{
    LevelRangeFilter filter = new LevelRangeFilter { LevelMin = Level.Info };
    filter.ActivateOptions();
    return filter;
}

请注意,如果文件丢失或损坏,log4net 不会抛出任何异常(至少是开箱即用的),但没有附加到记录器的附加程序。

【讨论】:

  • 感谢您提供此信息。只需几个注意事项:log4net.Config.BasicConfigurator.Configure(appender); 行可能只需要向存储库发出它已配置的信号。如果多次调用它也可能会向 Root appender 添加不必要的 appender(在您的情况下,这不是一种情况,因为您使用的是静态的)。您可以在(logger.Logger as IAppenderAttachable).AddAppender(CreateConsoleAppender()); 之后添加行logger.Logger.Repository.Configured = true;。希望这可以帮助任何人理解这部分代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多