Ограничение количества писем, отправленных Elmah
Кто-нибудь знает о хорошем способе ограничить количество писем, отправленных Elmah в течение периода времени, как вы можете с мониторингом работоспособности?
Я хочу иметь возможность ограничивать электронные письма для каждой ошибки с каждой страницы только электронной почтой один раз в час для этой конкретной ошибки и страницы.
Глядя на документацию elmah, это выглядит так:
void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e)
{
// perform filtering here
}
в файле global.ascx может быть опцией. Я могу настроить статический объект для каждого приложения, содержащий некоторые сведения об ошибке и время регистрации, и проверить его и отменить уведомление по электронной почте, если это необходимо?
У кого-нибудь есть лучшее решение или пример того, что они сейчас используют?
Ответы
Ответ 1
Я написал это, используя тот же метод, что и в вашем вопросе. Кажется, хорошо работает.
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);
}
});
}
Ответ 2
Я не знаю, обладает ли Elmah этой возможностью (документы не упоминают об этом), но мониторинг работоспособности ASP.NET делает: http://aspnet.4guysfromrolla.com/articles/032107-1.aspx
Я закончил писать свои собственные журналы регистрации событий, уведомлений и накопителей для моей CMS... Я использую трассировку стека для каждого исключения и использую ее для свертывания подобных событий (веб-приложение может получить тысячи исключения менее чем за секунду, если что-то пойдет не так).
Я установил свой период уведомления на 1 день - я получаю уведомление только о первом экземпляре ошибки каждый день. Последний экземпляр ошибки всегда сохраняется, но старые экземпляры "очищаются" до последних 20 или около того, в зависимости от частоты и т.д....
Он интегрируется с системой аутентификации, поэтому администраторы/разработчики получают "входящие" события, на которые они подписались, и могут просматривать информацию об отладке в режиме реального времени, а также предотвращать просмотр неаутентифицированных пользователей любой информацией об отладке.
Действительно приятно... И поскольку он общий, он работает и для событий без ошибок, таких как публикации, уведомления об изменениях пользователей и т.д.
Мне любопытно, будет ли кто-нибудь заинтересован в такой системе, представленной как библиотека?
Ответ 3
У меня была аналогичная проблема, и я решил использовать метод log-to-SQL для ELMAH. Я использовал SQLExpress 2008 (бесплатную версию) на своем веб-сервере, а затем настроил SQL Reporting для отправки электронных сообщений электронной почты каждое утро.
Этот метод не требует кодирования, просто настройки сервера SQL и служб отчетов. Это дает вам возможность запускать отчеты по месяцам журналов ошибок, а не просто просматривать их ежедневно. Кроме того, вы можете планировать отчеты так часто, как вам нравится.
В странице wiki ELMAH содержится информация о том, как настроить web.config, чтобы указать на SQL-сервер. Есть много вариантов для получения данных, как только данные находятся в SQL, но я нахожу, что службы отчетов SQL Express идеально подходят для моих нужд.
Ответ 4
Этот проект Codeplex ASP.NET Exception Reporting, который является оберткой для Elmah, выглядит многообещающим. http://aspexceptionreporter.codeplex.com/