2009-07-07 18 views
15

私は1つのappdomainからlog4netを初期化し、別のappdomainでそれを使用する必要があるアプリケーションがあります。それはサポートされていますか?log4netを介してappdomains

もしそうでなければ、各appdomainからlog4netを初期化する必要がありますか?同じアプリケーションの複数の初期化でリスクがありますか?私は同じlog4net.configを使用する必要がありますか?

答えて

10

log4net-userメーリングリストには、RollingFileAppenderで動作する回答があります。 log4net.configにアペンダに次の行を追加します。質問は数歳

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> 
5

ロガーは、app-domainごとに1回初期化する必要があります。

+0

2人のロガーが同じファイルに追加しようとするとロックに問題はありませんか? – Bartosz

3

アプリドメインごとに1回、ダリンと同意します。これらのアプリケーションで統合ログ機能を使用する場合は、競合の対象にならないログ対象を選択する必要があります(FileAppenderやRollingFileAppenderなど)。

7

が - 多分それは誰か助け:

親のAppDomainで構成されたロガーを使用することが可能です。 実行する必要があるのは、LoggingEventを子のAppDomainから親のAppDomainにルーティングすることです。このためには、子ドメインの外にレコードを転送するカスタムアペンダ...

/// <summary> 
/// Represents an <see cref="IAppender"/> implementation that forwards a <see cref="LoggingEvent"/> to a given Receiver. 
/// Instances of this class should be created in the child domain. 
/// </summary> 
public class CrossDomainOutboundAppender : AppenderSkeleton 
{ 
    private readonly CrossDomainParentAppender crossDomainParentAppender; 
    public CrossDomainOutboundAppender(CrossDomainParentAppender crossDomainParentAppender) 
    { 
     if (crossDomainParentAppender == null) 
     { 
      throw new ArgumentNullException("crossDomainParentAppender"); 
     } 
     this.crossDomainParentAppender = crossDomainParentAppender; 

    } 

    protected override void Append(LoggingEvent loggingEvent) 
    { 
     LoggingEvent copied = new LoggingEvent(loggingEvent.GetLoggingEventData()); 
     crossDomainParentAppender.Append(copied); 
    } 
} 

、転送されたLoggingEventのを受けて、利用可能なIAppender秒にそれらを追加するカスタムクラスを作成する必要があります...

/// <summary> 
/// Represents a Receiver that sends Log4Nets <see cref="LoggingEvent"/> to all available <see cref="IAppender"/>s. 
/// Instances of this class should be created in the ParentDomain. 
/// </summary> 
[Serializable] 
public class CrossDomainParentAppender : MarshalByRefObject 
{ 
    public void Append(LoggingEvent loggingEvent) 
    { 
     foreach (IAppender usedAppender in LogManager.GetRepository().GetAppenders()) 
     { 
      usedAppender.DoAppend(loggingEvent); 
     } 
    } 
} 

と2を結びつけるとlog4netの設定し、最後にセットアップクラス:今すぐ

public class CrossDomainChildLoggingSetup : MarshalByRefObject 
{ 
    private CrossDomainParentAppender parentAppender; 

    public void ConfigureAppender(CrossDomainParentAppender crossDomainParentAppender) 
    { 
     parentAppender = crossDomainParentAppender; 
     CrossDomainOutboundAppender outboundAppender = new CrossDomainOutboundAppender(parentAppender); 
     log4net.Config.BasicConfigurator.Configure(outboundAppender); 
    } 
} 

を - あなたは、セットアップあなたのAppDomainまでは、次のコを追加することができますde ...

CrossDomainParentAppender crossDomainParentAppender = new CrossDomainParentAppender(); 
Type crossDomainType = typeof(CrossDomainChildLoggingSetup); 
CrossDomainChildLoggingSetup crossDomainChildLoggingSetup = (CrossDomainChildLoggingSetup)domain.CreateInstanceFrom(crossDomainType.Assembly.Location, crossDomainType.FullName).Unwrap(); 
crossDomainChildLoggingSetup.ConfigureAppender(crossDomainParentAppender); 

...子ドメインに記録されているすべてが親ドメインログに記録されます。 (ご注意:私はCreateInstaceFrom(assemblyFilePath,...)を使用 - あなたの設定に応じて、あなたはfilePathにすることにより荷重を必要としない場合があります)

私はどんなバグや問題を発見していないものの:あなたは私に知らせてください発生する可能性が不備や問題が表示された場合。

+0

私が探していたアプローチのタイプとまったく同じです。ありがとうございました。 –

+2

BasicConfigurator.Configure(outputAppender)の代わりに改善を提案してもよければ、次のように変更して親ドメイン設定を取得してください:var hierarchy =(Hierarchy)LogManager.GetRepository(); hierarchy.Root.AddAppender(outboundAppender); hierarchy.Configured = true; –

+0

これを使用するとRemotingExceptionが発生しましたか? "Object '/a0720457_c9e6_4edf_bde5_86d96058cb4e/+mauuadzzsfpiaad3bjv4uss_264.rem'が切断されているか、サーバーに存在しないという例外が表示されます。私はガベージコレクションのためだと信じています。どのようにこれを修正するための任意のアイデア? – Charlie

0

私の答えはLinkyの答えに追加されます。

答えには、Jack Allanの質問です。あなたは、変更CrossDomainOutboundAppenderクラスを解くことによってこの問題を解決することができます

/// <summary> 
/// Represents an <see cref="IAppender"/> implementation that forwards a <see cref="LoggingEvent"/> to a given Receiver. 
/// Instances of this class should be created in the child domain. 
/// </summary> 
public class CrossDomainOutboundAppender : AppenderSkeleton 
{ 
    private readonly CrossDomainParentAppender crossDomainParentAppender; 
    public CrossDomainOutboundAppender(CrossDomainParentAppender crossDomainParentAppender) 
    { 
     if (crossDomainParentAppender == null) 
     { 
      throw new ArgumentNullException("crossDomainParentAppender"); 
     } 
     this.crossDomainParentAppender = crossDomainParentAppender; 

    } 

    protected override void Append(LoggingEvent loggingEvent) 
    { 
     LoggingEvent copied = new LoggingEvent(loggingEvent.GetLoggingEventData(FixFlags.All)); 
     crossDomainParentAppender.Append(copied); 
    } 
} 

お知らせFixFlags.All

....の現在のバージョンは、メッセージをログに記録するすべてのアペンダを引き起こして欠陥を持っている、などのthatsの異なるロガーが異なるレベルでログすることができるため、log4netの目的を凌駕します。クラスの私の改良版:これはLogManagerのにログを配布し

/// <summary> 
/// Represents a Receiver that sends Log4Nets <see cref="LoggingEvent"/> to all available <see cref="IAppender"/>s. 
/// Instances of this class should be created in the ParentDomain. 
/// </summary> 
[Serializable] 
public class CrossDomainParentAppender : MarshalByRefObject 
{ 
    public void Append(LoggingEvent loggingEvent) 
    { 
     LogManager.GetRepository().Log(loggingEvent); 
    } 
} 

が、これはロガー等責任があるログを配置する場所を見つけるだろう

関連する問題