有谁知道有什么好方法可以像健康监控一样限制 Elmah 在一段时间内发送的电子邮件数量?
我希望能够将每个页面中每个错误的电子邮件限制为针对该特定错误和页面每小时左右发送一次电子邮件。
查看 elmah 文档,它看起来像使用:
void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e)
{
// perform filtering here
}
在 global.ascx 文件中可能是一个选项。我可以为每个应用程序设置一个静态对象,其中包含一些错误详细信息和记录的时间并检查它并在需要时取消电子邮件通知?
有谁有更好的解决方案或他们现在正在使用的示例?
我用与你问题中相同的方法写了这篇文章。看起来效果很好。
public static DateTime RoundUp(this DateTime dt, TimeSpan d)
{
return new DateTime(((dt.Ticks + d.Ticks - 1) / d.Ticks) * d.Ticks);
}
static ConcurrentDictionary<int, KeyValuePair<DateTime, string>> _concurrent = new ConcurrentDictionary<int, KeyValuePair<DateTime, string>>();
/// <summary>
/// This is an Elmah event used by the elmah engine when sending out emails. It provides an opportunity to weed out
/// irrelavent emails.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e)
{
preventSpammingDigestEmail(e);
}
/// <summary>
/// Prevents spamming by throttling emails to 5 minute intervals.
/// </summary>
/// <param name="e"></param>
private static void preventSpammingDigestEmail(ExceptionFilterEventArgs e)
{
DateTime roundedTimeStamp = DateTime.Now.RoundUp(TimeSpan.FromMinutes(5));
string serialisedException = Util.SerializeException(e.Exception);
var lastRaisedException = new KeyValuePair<DateTime, string>
(roundedTimeStamp, serialisedException);
int key = lastRaisedException.GetHashCode();
bool errorHasAlreadyBeenRaised = _concurrent.ContainsKey(key);
// If event has already been raised in the last five minutes dont raise again
if (errorHasAlreadyBeenRaised)
{
e.Dismiss();
return;
}
// Record that it has been raised
_concurrent.TryAdd(key, lastRaisedException);
// Clean up existing entries
Task.Factory.StartNew(() =>
{
var toRemove =
_concurrent.Where(pair => pair.Value.Key < DateTime.Now.Date).Select(pair => pair.Key).ToArray();
foreach (var i in toRemove)
{
KeyValuePair<DateTime, string> keyValuePair;
_concurrent.TryRemove(i, out keyValuePair);
}
});
}
private static string SerializeException(Exception e, string exceptionMessage = "")
{
if (e == null)
return String.Empty;
exceptionMessage = String.Format("{0}{1}{2}\n{3}", exceptionMessage, (exceptionMessage == String.Empty)
? String.Empty
: "\n\n", e.Message, e.StackTrace);
if (e.InnerException != null)
exceptionMessage = SerializeException(e.InnerException, exceptionMessage);
return exceptionMessage;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)