/// <summary> /// Prevent SPAM by suppressing frequent exceptions. /// For example it can allow maximum 10 errors of same type per 5 minutes (2880 per day). /// Amount of suppressed exceptions will be included inside next exception which is not suppressed. /// </summary> bool GroupExceptions(List <ExceptionGroup> group, Exception ex, string subject, string body, Action <Exception, string, string> action) { var value = ex.StackTrace == null ? string.Format("{0}: {1}", ex.GetType().Name, ex.Message) : ex.StackTrace.ToString(); // Get checksum. var algorithm = System.Security.Cryptography.SHA256.Create(); var bytes = System.Text.Encoding.UTF8.GetBytes(value); var hash = algorithm.ComputeHash(bytes); algorithm.Dispose(); var guidBytes = new byte[16]; Array.Copy(hash, guidBytes, guidBytes.Length); var checksum = new Guid(guidBytes); // Try to get existing exception. lock (group) { var ei = group.FirstOrDefault(x => x.Checksum == checksum); var notifyNow = ei == null; if (ei == null) { ei = new ExceptionGroup(group, GroupingDelay, ex, checksum, subject, body, action); group.Add(ei); } ei.Increment(); return(notifyNow); } }
public void Save(int exceptionGroupId, string userComment, string userFixedInCommitHash) { ExceptionGroup exceptionGroup = _db.ExceptionGroups.First(eg => eg.ExceptionGroupId == exceptionGroupId); exceptionGroup.UserComment = userComment; exceptionGroup.UserFixedInCommitId = SourceControlRepository.FindCommitId(userFixedInCommitHash); _db.SaveChanges(); }
protected void PreProcessExceptions() { List <ExceptionImport> exceptions = (from s in message.Sessions from e in s.Exceptions select new ExceptionImport(e) { ClientSessionId = s.SessionID, IsFirstInSession = false }).ToList(); if (0 == exceptions.Count) { return; // no exceptions reported, denormalisedExceptions remains null } // mark first exception in session - note that above LINQ query does not mix up order of items long clientSession = -1; exceptions.ForEach(ex => { if (ex.ClientSessionId != clientSession) { ex.IsFirstInSession = true; clientSession = ex.ClientSessionId; } }); List <string> distinctMsgExceptionGroups = (from e in exceptions select e.FingerprintHash).Distinct().ToList(); List <string> knownExceptionGroups = ImportCache.GetExceptionGroupFingerprintHashes(repository); List <string> missing = distinctMsgExceptionGroups.Except(knownExceptionGroups).ToList(); if (missing.Count > 0) { List <ExceptionImport> groupsToAdd = (from e in exceptions join m in missing on e.FingerprintHash equals m select e).Distinct(new ExceptionImportGroupEqualityComparer()).ToList(); foreach (ExceptionImport imp in groupsToAdd) { ExceptionGroup modelGroup = new ExceptionGroup() { ExceptionFingerprint = imp.Fingerprint, ExceptionLocation = imp.Location, ExceptionType = imp.Type, TypeFingerprintSha256Hash = imp.FingerprintHash }; repository.Context.ExceptionGroups.AddObject(modelGroup); } repository.IgnoreDuplicateKeysOnSaveChanges <ExceptionGroup>(); ImportCache.InvalidateExceptionGroupsCaches(); } this.denormalisedExceptions = exceptions; }