我正在尝试为Failover Appender
编写异步Log4net
。我快到了,但有一些小问题。
appender需要尝试登录我们的内部Web服务,然后,如果失败,请写入该文件。
这是我需要帮助的地方......
症状:
我的附录代码看起来像:
最终,我将动态解析客户端,但现在......
namespace Testing.Appenders
{
using log4net.Appender;
using log4net.Core;
using System;
using System.IO;
using System.ServiceModel;
using System.Threading.Tasks;
using wsEventManager;
public class AsynchWebServiceFailoverAppender : AppenderSkeleton
{
#region <Properties>
public string ServiceUrl { get; set; }
public string File { get; set; }
#endregion
#region <Methods>
#region protected
protected override void Append(LoggingEvent loggingEvent)
{
if (loggingEvent == null)
throw new ArgumentNullException("LoggingEvent");
if (string.IsNullOrEmpty(File))
throw new ArgumentNullException("File");
if (string.IsNullOrEmpty(ServiceUrl))
throw new ArgumentNullException("ServiceUrl");
Task.Factory.StartNew(() =>
{
var uri = new Uri(ServiceUrl);
var myBinding = new BasicHttpBinding(BasicHttpSecurityMode.None);
var endpoint = new EndpointAddress(uri);
var client = new EventManagerSoapClient(myBinding, endpoint);
var eventType = GetEventType(loggingEvent);
var log = GetEvent(eventType);
client.Log(log);
client.Close();
client = null;
})
.ContinueWith(task =>
{
using (var streamWriter = new StreamWriter(File, true))
{
using (var textWriter = TextWriter.Synchronized(streamWriter))
{
textWriter.WriteLine(base.RenderLoggingEvent(loggingEvent));
textWriter.FlushAsync();
}
}
}, TaskContinuationOptions.OnlyOnFaulted);
}
#endregion
#endregion
}
}
我的配置工作,但这是:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="WebServiceFailoverAppender" type="Testing.Appenders.AsynchWebServiceFailoverAppender , Testing">
<ServiceUrl value="http://localhost/DiagnosticsWeb/BadUrl.asmx" />
<file value="C:\Logs\Support\Diagnostics.Appender\log4net.log" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="<%level date="%date{MM-dd-yyyy}" time="%date{h:mm:ss tt}" file="%class" thread="%thread">%message</%level>%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="WebServiceFailoverAppender" />
</root>
</log4net>
</configuration>
结果:
答案 0 :(得分:1)
如果您正在使用// get the webpage source -- depends on allow_url_fopen
// see the previously mentioned stack overflow answer for alternates
$externalWebpage = file_get_contents('http://yoursite.com/your-page.html');
// split the webpage by </head>
$websiteSections = explode($externalWebpage, '</head>',);
// don't neglect to add the '</head>' back if you want to use that
// portion somewhere else
$head = $websiteSections[0] . '</head>';
$body = $websiteSections[1];
电话,则应等待他们,否则,当您离开asynchronous
时可能无法完成。
我的猜测是scope
确实会对你所处的竞争条件产生任何影响。
要解决此问题,flush
应该await
。在flush
延续中,我将介绍task
架构:
await async
如果有效,请告诉我。
答案 1 :(得分:1)
写入文件时有竞争条件。您的TextWriter.Synchronized
无效,因为您每次都创建新的编写器,并且创建此构造以将写入同步到TextWriter
的单个实例。验证尝试锁定整个文件写入块。如果您想以一种即发即忘的异步方式从多个线程写入单个日志文件 - 请参阅我的其他答案here。