1

log4net を広く使用する C# (.NET 3.5) アプリケーションがあります。log4net 構成はapp.configファイル内にあります。

アプリは、ロガー ラッパー クラスの静的コンストラクターでインスタンス化された単一のアプリケーション全体のロガー インスタンスを使用します[assembly: XmlConfigurator(Watch = true)]AssemlyInfo.cs

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

わかりました、質問はすでにGoogleにあり、答えを見つけたので、ここに残します. :)

アペンダーを操作するための鍵は、メソッドIAppenderAttachableを実装しているため、インターフェースです。AddAppenderremoveAppender

によって返されるのLogManager.GetLogger()は のインスタンスでありILog、これには プロパティ が含まれていますLogger。によって返されるオブジェクトはILog.LoggerクラスLoggerインスタンスです。Loggerクラスはインターフェイスを実装し、ロガーのリポジトリを抽出するためのプロパティをIAppenderAttachable含みます。Repositoryリポジトリには、ロガーのすべてのアクティブなアペンダーを含むクラス インスタンス (implements 、、など) をGetAppenders返すメソッドがあります。AppenderCollectionICollectionIListIenumerable

総括する:

//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 に答える