2009-07-07 63 views
15

我有一個應用程序從一個appdomain初始化log4net,並需要在另一個appdomain中使用它。它是否支持?跨應用程序域log4net

如果不是,我應該從每個appdomain初始化log4net嗎?在同一個應用程序中多次初始化有風險嗎?我應該使用相同的log4net.config嗎?

回答

10

log4net-user郵件列表有一個適用於RollingFileAppender的答案。以下行添加到附加器在log4net.config:

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

記錄器應該爲每個應用程序域初始化一次。

+0

當兩個記錄器試圖追加到同一個文件時,會不會導致鎖定問題? – Bartosz 2017-04-23 18:19:00

3

同意darin,每個應用程序域一次。如果您希望讓這些應用程序使用合併日誌記錄,那麼您需要選擇一個不會發生爭用的日誌記錄目標(即不是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); 
     } 
    } 
} 

,最後是關係的兩個配置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

準確地說我正在尋找的方法的類型。謝謝。 – 2014-09-15 17:04:33

0

我的答案增加了林克的答案。

回答傑克艾倫的問題。您可以通過求解改變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

當前版本的....有一個缺陷造成的所有追加程序登錄的消息,這就是像擊敗了log4net的目的,因爲不同的記錄器可以登錄不同的級別。我改進版本的類:

/// <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); 
    } 
} 

此日誌分配到日誌管理,這將找出的日誌,該日誌記錄器負責放置等。