我有一個應用程序從一個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