/// <summary>
        ///     Creates a new instance of <see cref="IncidentBeingAnalyzed" />.
        /// </summary>
        /// <param name="entity">entity</param>
        /// <param name="exception">exception to analyze</param>
        /// <exception cref="ArgumentNullException">entity; exception</exception>
        /// <exception cref="ArgumentException">entity.hashcode is null</exception>
        public IncidentBeingAnalyzed(ErrorReportEntity entity, ErrorReportException exception)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            if (exception == null)
            {
                throw new ArgumentNullException("exception");
            }
            if (string.IsNullOrEmpty(entity.ReportHashCode))
            {
                throw new ArgumentException("ReportHashCode must be specified to be able to identify duplicates.");
            }

            Description = exception.Message;
            FullName    = exception.FullName;
            StackTrace  = HashCodeGenerator.CleanStackTrace(exception.StackTrace);

            AddReport(entity);
            ReportHashCode     = entity.ReportHashCode;
            HashCodeIdentifier = entity.GenerateHashCodeIdentifier();
            ApplicationId      = entity.ApplicationId;
            UpdatedAtUtc       = entity.CreatedAtUtc;
            CreatedAtUtc       = entity.CreatedAtUtc;
        }
Example #2
0
        /// <summary>
        ///     Creates an incident and a report.
        /// </summary>
        public void CreateReportAndIncident(out int reportId, out int incidentId)
        {
            using (var uow = CreateUnitOfWork())
            {
                CreateUserAndApplication(uow, out var accountId, out var applicationId);

                var report = new ErrorReportEntity(applicationId, Guid.NewGuid().ToString("N"), DateTime.UtcNow,
                                                   new ErrorReportException(new Exception("mofo")),
                                                   new List <ErrorReportContext>
                {
                    new ErrorReportContext("Maps", new Dictionary <string, string>())
                })
                {
                    Title = "Missing here"
                };
                report.Init(report.GenerateHashCodeIdentifier());

                var incident = new IncidentBeingAnalyzed(report);
                var incRepos = new AnalyticsRepository(new AnalysisDbContext(uow), ConfigStore);
                incRepos.CreateIncident(incident);
                incidentId = incident.Id;

                report.IncidentId = incident.Id;
                incRepos.CreateReport(report);
                reportId = report.Id;

                uow.SaveChanges();
            }
        }
Example #3
0
        /// <summary>
        ///     Creates an incident and a report.
        /// </summary>
        public void CreateReportAndIncident(out int reportId, out int incidentId)
        {
            ErrorReportEntity report;

            using (var uow = CreateUnitOfWork())
            {
                report = new ErrorReportEntity(ApplicationId, Guid.NewGuid().ToString("N"), DateTime.UtcNow,
                                               new ErrorReportException(new Exception("mofo")),
                                               new List <ErrorReportContextCollection>
                {
                    new ErrorReportContextCollection("Maps", new Dictionary <string, string>())
                })
                {
                    Title = "Missing here"
                };
                report.Init(report.GenerateHashCodeIdentifier());

                uow.SaveChanges();
            }

            using (var dbContext = CreateUnitOfWork())
            {
                var incident = new IncidentBeingAnalyzed(report);
                var incRepos = new AnalyticsRepository(dbContext);
                incRepos.CreateIncident(incident);
                incidentId = incident.Id;

                report.IncidentId = incident.Id;
                incRepos.CreateReport(report);
                reportId = report.Id;

                dbContext.SaveChanges();
            }
        }
Example #4
0
        /// <summary>
        ///     Method that will be invoked if no implementations of <see cref="IHashCodeSubGenerator" /> generates an hash code.
        /// </summary>
        /// <param name="report">received report</param>
        /// <returns>hash code</returns>
        /// <exception cref="ArgumentNullException">report</exception>
        protected virtual ErrorHashCode DefaultCreateHashCode(ErrorReportEntity report)
        {
            if (report == null)
            {
                throw new ArgumentNullException("report");
            }


            var hashSource      = $"{report.Exception.FullName ?? report.Exception.Name}\r\n";
            var foundHashSource = false;

            // the client libraries can by themselves specify how we should identify
            // unique incidents. We then use that identifier in combination with the exception name.
            var collection = report.ContextCollections.FirstOrDefault(x => x.Name == "CoderrData");

            if (collection != null)
            {
                if (collection.Properties.TryGetValue("HashSource", out var reportHashSource))
                {
                    foundHashSource = true;
                    hashSource     += reportHashSource;
                }
            }
            if (!foundHashSource)
            {
                // This identifier is determined by the developer when  the error is generated.
                foreach (var contextCollection in report.ContextCollections)
                {
                    if (!contextCollection.Properties.TryGetValue("ErrorHashSource", out var ourHashSource))
                    {
                        continue;
                    }

                    hashSource      = ourHashSource;
                    foundHashSource = true;
                    break;
                }
            }

            var hashSourceForCompability = "";

            if (!foundHashSource)
            {
                hashSourceForCompability = hashSource + CleanStackTrace(report.Exception.StackTrace ?? "");
                hashSource += CleanStackTrace(report.Exception.StackTrace ?? "");
            }

            var hash = HashTheSource(hashSource);

            return(new ErrorHashCode
            {
                CollisionIdentifier = report.GenerateHashCodeIdentifier(),
                HashCode = hash.ToString("X"),
                CompabilityHashSource = hashSourceForCompability == "" ? null : HashTheSource(hashSourceForCompability).ToString("X")
            });
        }
Example #5
0
        public void CreateUserAndApp()
        {
            using (var uow = CreateUnitOfWork())
            {
                var accountRepos = new AccountRepository(uow);
                var account      = new Account("arne", "123456")
                {
                    Email = "*****@*****.**"
                };
                accountRepos.Create(account);
                var userRepos = new UserRepository(uow);
                var user      = new User(account.Id, "arne")
                {
                    EmailAddress = "*****@*****.**"
                };
                userRepos.CreateAsync(user).GetAwaiter().GetResult();

                var appRepos = new ApplicationRepository(uow);
                var app      = new Application(account.Id, "MinApp");
                appRepos.CreateAsync(app).GetAwaiter().GetResult();
                var member = new ApplicationTeamMember(app.Id, account.Id, "Admin");
                appRepos.CreateAsync(member).GetAwaiter().GetResult();


                var report = new ErrorReportEntity(app.Id, Guid.NewGuid().ToString("N"), DateTime.UtcNow,
                                                   new ErrorReportException(new Exception("mofo")),
                                                   new List <ErrorReportContext> {
                    new ErrorReportContext("Maps", new Dictionary <string, string>())
                });
                report.Title = "Missing here";
                report.Init(report.GenerateHashCodeIdentifier());

                var incident = new ReportAnalyzer.Domain.Incidents.IncidentBeingAnalyzed(report);
                var incRepos = new AnalyticsRepository(new AnalysisDbContext(uow), ConfigStore);
                incRepos.CreateIncident(incident);
                report.IncidentId = incident.Id;
                incRepos.CreateReport(report);

                uow.SaveChanges();
            }
        }
        public void Should_load_ignored_state_into_class_correctly()
        {
            var report = new ErrorReportEntity(FirstApplicationId, Guid.NewGuid().ToString("N"), DateTime.UtcNow,
                                               new ErrorReportException(new Exception("mofo")),
                                               new List <ErrorReportContext> {
                new ErrorReportContext("Maps", new Dictionary <string, string>())
            })
            {
                Title = "Missing here"
            };

            report.Init(report.GenerateHashCodeIdentifier());

            using (var uow = new AnalysisDbContext(CreateUnitOfWork()))
            {
                var incident = new IncidentBeingAnalyzed(report);
                var incRepos = new AnalyticsRepository(uow, new TestConfigStore());
                incRepos.CreateIncident(incident);
                report.IncidentId = incident.Id;
                incRepos.CreateReport(report);
            }
        }
        /// <summary>
        ///     Analyze report
        /// </summary>
        /// <param name="report">report</param>
        /// <exception cref="ArgumentNullException">report</exception>
        public async Task Analyze(IMessageContext context, ErrorReportEntity report)
        {
            if (report == null)
            {
                throw new ArgumentNullException("report");
            }

            var countThisMonth = _repository.GetMonthReportCount();

            if (countThisMonth >= 500)
            {
                _repository.AddMissedReport(DateTime.Today);
                return;
            }

            var exists = _repository.ExistsByClientId(report.ClientReportId);

            if (exists)
            {
                _logger.Warn("Report have already been uploaded: " + report.ClientReportId);
                return;
            }

            try
            {
                var hashCode = _hashCodeGenerator.GenerateHashCode(report);
                report.Init(hashCode);
            }
            catch (Exception ex)
            {
                var reportJson = JsonConvert.SerializeObject(report);
                if (reportJson.Length > 1000000)
                {
                    reportJson = reportJson.Substring(0, 100000) + "[....]";
                }
                _logger.Fatal("Failed to init report " + reportJson, ex);
                return;
            }

            var applicationVersion = GetVersionFromReport(report);
            var isReOpened         = false;
            var firstLine          = report.GenerateHashCodeIdentifier();
            var incident           = _repository.FindIncidentForReport(report.ApplicationId, report.ReportHashCode, firstLine);

            if (incident == null)
            {
                incident = BuildIncident(report);
                _repository.CreateIncident(incident);

                var evt = new IncidentCreated(incident.ApplicationId,
                                              incident.Id, incident.Description, incident.FullName)
                {
                    CreatedAtUtc       = incident.CreatedAtUtc,
                    ApplicationVersion = applicationVersion,
                };

                await _domainQueue.PublishAsync(context.Principal, evt);

                await context.SendAsync(evt);
            }
            else
            {
                await _repository.StoreReportStats(new ReportMapping()
                {
                    IncidentId    = incident.Id,
                    ErrorId       = report.ClientReportId,
                    ReceivedAtUtc = report.CreatedAtUtc
                });

                if (incident.IsIgnored)
                {
                    _logger.Info("Incident is ignored: " + JsonConvert.SerializeObject(report));
                    incident.WasJustIgnored();
                    _repository.UpdateIncident(incident);
                    return;
                }

                if (incident.IsClosed)
                {
                    if (applicationVersion != null && incident.IsReportIgnored(applicationVersion))
                    {
                        _logger.Info("Ignored report since it's for a version less that the solution version: " + JsonConvert.SerializeObject(report));
                        incident.WasJustIgnored();
                        _repository.UpdateIncident(incident);
                        return;
                    }

                    isReOpened = true;
                    incident.ReOpen();
                    var evt = new IncidentReOpened(incident.ApplicationId, incident.Id,
                                                   incident.CreatedAtUtc)
                    {
                        ApplicationVersion = applicationVersion
                    };
                    await context.SendAsync(evt);

                    await _domainQueue.PublishAsync(context.Principal, evt);
                }

                incident.AddReport(report);
                _repository.UpdateIncident(incident);
                if (incident.ReportCount > 25)
                {
                    _logger.Debug("Report count is more than 25. Storing only report stats for incident " + incident.Id);
                    return;
                }
            }

            if (!string.IsNullOrWhiteSpace(report.EnvironmentName))
            {
                _repository.SaveEnvironmentName(incident.Id, report.EnvironmentName);
            }

            report.IncidentId = incident.Id;
            _repository.CreateReport(report);
            _logger.Debug("saving report " + report.Id + " for incident " + incident.Id);
            var appName = _repository.GetAppName(incident.ApplicationId);

            var summary = new IncidentSummaryDTO(incident.Id, incident.Description)
            {
                ApplicationId   = incident.ApplicationId,
                ApplicationName = appName,
                CreatedAtUtc    = incident.CreatedAtUtc,
                LastUpdateAtUtc = incident.UpdatedAtUtc,
                IsReOpened      = incident.IsReOpened,
                Name            = incident.Description,
                ReportCount     = incident.ReportCount
            };
            var sw = new Stopwatch();

            sw.Start();
            _logger.Debug("Publishing now: " + report.ClientReportId);
            var e = new ReportAddedToIncident(summary, ConvertToCoreReport(report, applicationVersion), isReOpened);
            await context.SendAsync(e);

            await context.SendAsync(new ProcessInboundContextCollections());

            if (sw.ElapsedMilliseconds > 200)
            {
                _logger.Debug("PublishAsync took " + sw.ElapsedMilliseconds);
            }
            sw.Stop();
        }
Example #8
0
        /// <summary>
        ///     Analyze report
        /// </summary>
        /// <param name="report">report</param>
        /// <exception cref="ArgumentNullException">report</exception>
        public void Analyze(ErrorReportEntity report)
        {
            if (report == null)
            {
                throw new ArgumentNullException("report");
            }

            var exists = _repository.ExistsByClientId(report.ClientReportId);

            if (exists)
            {
                _logger.Warn("Report have already been uploaded: " + report.ClientReportId);
                return;
            }

            try
            {
                var hashCode = _hashCodeGenerator.GenerateHashCode(report);
                report.Init(hashCode);
            }
            catch (Exception ex)
            {
                _logger.Fatal("Failed to store report " + JsonConvert.SerializeObject(report), ex);
                return;
            }

            var isReOpened = false;
            var firstLine  = report.GenerateHashCodeIdentifier();
            var incident   = _repository.FindIncidentForReport(report.ApplicationId, report.ReportHashCode, firstLine);

            if (incident == null)
            {
                incident = BuildIncident(report);
                _repository.CreateIncident(incident);
            }
            else
            {
                if (incident.ReportCount > 10000)
                {
                    _logger.Debug("Reportcount is more than 10000. Ignoring report for incident " + incident.Id);
                    return;
                }

                if (incident.IsIgnored)
                {
                    _logger.Info("Incident is ignored: " + JsonConvert.SerializeObject(report));
                    incident.WasJustIgnored();
                    _repository.UpdateIncident(incident);
                    return;
                }
                if (incident.IsSolved)
                {
                    isReOpened = true;
                    incident.ReOpen();
                    _eventBus.PublishAsync(new IncidentReOpened(incident.ApplicationId, incident.Id,
                                                                incident.CreatedAtUtc));
                }

                incident.AddReport(report);
                _repository.UpdateIncident(incident);
            }

            report.IncidentId = incident.Id;
            _repository.CreateReport(report);
            _logger.Debug("saving report " + report.Id + " for incident " + incident.Id);
            var appName = _repository.GetAppName(incident.ApplicationId);

            var summary = new IncidentSummaryDTO(incident.Id, incident.Description)
            {
                ApplicationId   = incident.ApplicationId,
                ApplicationName = appName,
                CreatedAtUtc    = incident.CreatedAtUtc,
                LastUpdateAtUtc = incident.UpdatedAtUtc,
                IsReOpened      = incident.IsReOpened,
                Name            = incident.Description,
                ReportCount     = incident.ReportCount
            };
            var sw = new Stopwatch();

            sw.Start();
            _logger.Debug("Publishing now: " + report.ClientReportId);
            var e = new ReportAddedToIncident(summary, ConvertToCoreReport(report), isReOpened);

            _eventBus.PublishAsync(e);
            if (sw.ElapsedMilliseconds > 200)
            {
                _logger.Debug("Publish took " + sw.ElapsedMilliseconds);
            }
            sw.Stop();
        }