1

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

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

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

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

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

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

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

4

1 回答 1

0

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

操作 appender 的关键是IAppenderAttachable接口,因为它实现AddAppenderremoveAppender方法。

返回的LogManager.GetLogger()是 的实例ILog,该实例又包含属性Logger。返回的对象ILog.Logger是一个Logger类实例。Logger类实现IAppenderAttachable接口并包含Repository用于提取记录器存储库的属性。存储库具有GetAppenders返回AppenderCollection类实例(实现ICollection、、、IListIenumerable)的方法以及记录器的所有活动附加器。

总结一下:

//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,则不会抛出任何异常(至少开箱即用),但不会将附加程序附加到记录器。

于 2012-06-27T13:29:55.853 回答