我有一个应用程序从一个appdomain初始化log4net,并需要在另一个appdomain中使用它。它是否支持?跨应用程序域log4net
如果不是,我应该从每个appdomain初始化log4net吗?在同一个应用程序中多次初始化有风险吗?我应该使用相同的log4net.config吗?
我有一个应用程序从一个appdomain初始化log4net,并需要在另一个appdomain中使用它。它是否支持?跨应用程序域log4net
如果不是,我应该从每个appdomain初始化log4net吗?在同一个应用程序中多次初始化有风险吗?我应该使用相同的log4net.config吗?
log4net-user邮件列表有一个适用于RollingFileAppender的答案。以下行添加到附加器在log4net.config:
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
记录器应该为每个应用程序域初始化一次。
同意darin,每个应用程序域一次。如果您希望让这些应用程序使用合并日志记录,那么您需要选择一个不会发生争用的日志记录目标(即不是FileAppender或RollingFileAppender)。
虽然问题是几年前 - 也许它可以帮助别人:
它可以使用在父的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加载)
尽管我没有发现任何错误或问题:如果您发现任何可能出现的缺陷或问题,请让我知道。
准确地说我正在寻找的方法的类型。谢谢。 – 2014-09-15 17:04:33
我的答案增加了林克的答案。
回答杰克艾伦的问题。您可以通过求解改变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);
}
}
此日志分配到日志管理,这将找出的日志,该日志记录器负责放置等。
当两个记录器试图追加到同一个文件时,会不会导致锁定问题? – Bartosz 2017-04-23 18:19:00