2009-07-07 65 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); 
    } 
} 

此日志分配到日志管理,这将找出的日志,该日志记录器负责放置等。