创建自定义的事件接收器-Semantic Logging

创建自定义的事件接收器

Semantic Logging Application Block提供了大量的事件接收器,如Rolling Flat File,SQL Database, 云存储接收器等。这些接收器都实现了IObservable<EventEntry>接口。

有时这些并不能很好的满足客户需求,这时就需要定制事件接收器,比如邮件接收器、短信接收器等。

下面介绍以下如何定制邮件接收器,在特定的事件发生时自动发送邮件给指定的客户。

本文介绍了以下主题:

  • 创建自定义接收器

  • 在进程内使用自定义接收器

创建自定义接收器

要创建自定义接收器,必须实现IObservable<EventEntry>接口,该接口提供了3个函数:OnCompleted,OnError和OnExt

public interface IObserver<in T>
{
void OnCompleted();
void OnError(Exception error);
void OnNext(T value);
}

下面的展示了如何创建自定义的Email接收器。

public sealed class EmailSink : IObserver<EventEntry>
{
private const string DefaultSubject = "Email Sink Extension";
private IEventTextFormatter formatter;
private MailAddress sender;
private MailAddressCollection recipients = new MailAddressCollection();
private string subject;
private string host;
private int port;
private NetworkCredential credentials;
public EmailSink(string host, int port,
string recipients, string subject, string credentials,
IEventTextFormatter formatter)
{
this.formatter = formatter ?? new EventTextFormatter();
this.host = host;
this.port = GuardPort(port);
this.credentials = CredentialManager.GetCredentials(credentials);
this.sender = new MailAddress(this.credentials.UserName);
this.recipients.Add(GuardRecipients(recipients));
this.subject = subject ?? DefaultSubject;
}
public void OnNext(EventEntry entry)
{
if (entry != null)
{
using (var writer = new StringWriter())
{
this.formatter.WriteEvent(entry, writer);
Post(writer.ToString());
}
}
}
public void OnCompleted() {
}
public void OnError(Exception error) {
}
private void Post(string body)
{
using (var client = new SmtpClient(this.host, this.port)
{ Credentials = this.credentials, EnableSsl = true })
using (var message = new MailMessage(this.sender, this.recipients[0])
{ Body = body, Subject = this.subject })
{
for (int i = 1; i < this.recipients.Count; i++)
message.CC.Add(this.recipients[i]);
try
{
client.Send(message);
}
catch (SmtpException e)
{
SemanticLoggingEventSource.Log.CustomSinkUnhandledFault(
"SMTP error sending email: " + e.Message);
}
catch (InvalidOperationException e)
{
SemanticLoggingEventSource.Log.CustomSinkUnhandledFault(
"Configuration error sending email: " + e.Message);
}
catch (...)
{
// additional exception handling code here.
}
}
}
private static int GuardPort(int port)
{
if (port < 0)
throw new ArgumentOutOfRangeException("port");
return port;
}
private static string GuardRecipients(string recipients)
{
if (recipients == null)
throw new ArgumentNullException("recipients");
if (string.IsNullOrWhiteSpace(recipients))
throw new ArgumentException(
"The recipients cannot be empty", "recipients");
return recipients;
}
}

并使用一个扩展函数来实例化监听器,代码如下

public static class EmailSinkExtensions
{
public static EventListener CreateListener(string host, int port,
string recipients, string subject, string credentials,
IEventTextFormatter formatter = null)
{
var listener = new ObservableEventListener();
listener.LogToEmail(host, port, recipients, subject, credentials, formatter);
return listener;
}
public static SinkSubscription<EmailSink> LogToEmail(
this IObservable<EventEntry> eventStream, string host, int port,
string recipients, string subject, string credentials,
IEventTextFormatter formatter = null)
{
var sink = new EmailSink(host, port, recipients, subject, credentials, formatter);
var subscription = eventStream.Subscribe(sink);
return new SinkSubscription<EmailSink>(subscription, sink);
}
}

如何使用自定义接收器

private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var listener = new ObservableEventListener();
listener.LogToEmail("smtp.live.com", 25, "[email protected]", "In Proc Sample", "etw");
listener.EnableEvents(MyCompanyEventSource.Log,EventLevel.LogAlways, EventKeywords.All);
MyCompanyEventSource.Log.Startup();
}


猜你喜欢

转载自blog.51cto.com/13957086/2178099