Limiting the Number of Emails Sent By Elmah

后端 未结 4 1545
有刺的猬
有刺的猬 2021-02-04 11:29

Does anyone know of a good way to limit the number of emails sent by Elmah during a time period like you can with Health Monitoring?

I want to be able to limit the email

4条回答
  •  一个人的身影
    2021-02-04 12:08

    I wrote this using the same method as in your question. Seems to work nicely.

    public static DateTime  RoundUp(this DateTime dt, TimeSpan d)
    {
        return new DateTime(((dt.Ticks + d.Ticks - 1) / d.Ticks) * d.Ticks);
    }
    static ConcurrentDictionary> _concurrent = new ConcurrentDictionary>();
    
    /// 
    /// This is an Elmah event used by the elmah engine when sending out emails. It provides an opportunity to weed out 
    /// irrelavent emails.
    /// 
    /// 
    /// 
    protected void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e)
    {
        preventSpammingDigestEmail(e);
    }
    
    /// 
    /// Prevents spamming by throttling emails to 5 minute intervals.
    /// 
    /// 
    private static void preventSpammingDigestEmail(ExceptionFilterEventArgs e)
    {
        DateTime roundedTimeStamp = DateTime.Now.RoundUp(TimeSpan.FromMinutes(5));
        string serialisedException = Util.SerializeException(e.Exception);
    
        var lastRaisedException = new KeyValuePair
            (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 keyValuePair;
                    _concurrent.TryRemove(i, out keyValuePair);
                }
            });
    }
    

提交回复
热议问题