public async Task should_be_able_to_identity_tags_when_only_multiple_tags_are_specified_with_spaces()
        {
            var repos    = Substitute.For <ITagsRepository>();
            var provider = Substitute.For <ITagIdentifierProvider>();

            provider.GetIdentifiers(Arg.Any <TagIdentifierContext>()).Returns(new ITagIdentifier[0]);
            var ctx      = Substitute.For <IMessageContext>();
            var incident = new IncidentSummaryDTO(1, "Ada");
            var report   = new ReportDTO
            {
                ContextCollections = new[]
                { new ContextCollectionDTO("Data", new Dictionary <string, string> {
                        { "ErrTags[]", "MyTag" }, { "ErrTags[]", "YourTag" }
                    }) }
            };
            var e = new ReportAddedToIncident(incident, report, false);

            var sut = new IdentifyTagsFromIncident(repos, provider);
            await sut.HandleAsync(ctx, e);

            var arguments = repos.ReceivedCalls().First(x => x.GetMethodInfo().Name == "AddAsync")
                            .GetArguments();
            var tags = (Tag[])arguments[1];

            tags[0].Name.Should().Be("MyTag");
            tags[1].Name.Should().Be("YourTag");
        }
        public async Task Should_be_able_to_use_position_in_regular_collection()
        {
            var repos    = Substitute.For <IErrorOriginRepository>();
            var incident = new IncidentSummaryDTO(1, "Hello");
            var data     = new Dictionary <string, string> {
                { "ReportLongitude", "60.6065" }, { "ReportLatitude", "15.6355" }
            };
            var report = new ReportDTO {
                ContextCollections = new[] { new ContextCollectionDTO("SomeCollection", data) }
            };
            var e             = new ReportAddedToIncident(incident, report, false);
            var context       = Substitute.For <IMessageContext>();
            var configWrapper = Substitute.For <IConfiguration <OriginsConfiguration> >();

            var sut = new StorePositionFromNewReport(repos, configWrapper);
            await sut.HandleAsync(context, e);

            var entity = (ErrorOrigin)repos.ReceivedCalls().First(x => x.GetMethodInfo().Name == "CreateAsync")
                         .GetArguments().First();

            entity.Latitude.Should().Be(15.6355);
            entity.Longitude.Should().Be(60.6065);
        }
        /// <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();
        }
Esempio n. 4
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();
        }
Esempio n. 5
0
        /// <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(nameof(report));
            }

            var countThisMonth = _repository.GetMonthReportCount();

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

            _logger.Debug("Running as " + context.Principal.ToFriendlyString());
            var exists = _repository.ExistsByClientId(report.ClientReportId);

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

            ErrorHashCode hashcodeResult;

            try
            {
                hashcodeResult = _hashCodeGenerator.GenerateHashCode(report);
                report.Init(hashcodeResult.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 storeReport        = true;
            var applicationVersion = GetVersionFromReport(report);
            var isReOpened         = false;

            IncidentBeingAnalyzed incident = null;

            if (hashcodeResult.CompabilityHashSource != null)
            {
                incident = _repository.FindIncidentForReport(report.ApplicationId, hashcodeResult.CompabilityHashSource, hashcodeResult.CollisionIdentifier);
                if (incident != null)
                {
                    report.Init(hashcodeResult.CompabilityHashSource);
                }
            }
            if (incident == null)
            {
                incident = _repository.FindIncidentForReport(report.ApplicationId, report.ReportHashCode, hashcodeResult.CollisionIdentifier);
            }

            var isNewIncident = false;

            if (incident == null)
            {
                if (report.Exception == null)
                {
                    _logger.Debug("Got no exception");
                }

                isNewIncident = true;
                incident      = BuildIncident(report);
                _repository.CreateIncident(incident);
                await _repository.StoreReportStats(new ReportMapping()
                {
                    IncidentId    = incident.Id,
                    ErrorId       = report.ClientReportId,
                    ReceivedAtUtc = report.CreatedAtUtc
                });

                var evt = new IncidentCreated(incident.ApplicationId,
                                              incident.Id, incident.Description, incident.FullName)
                {
                    CreatedAtUtc       = incident.CreatedAtUtc,
                    ApplicationVersion = applicationVersion,
                };
                _logger.Info($"Storing IncidentCreated with {context.Principal.ToFriendlyString()}: {JsonConvert.SerializeObject(evt)}");
                await _domainQueue.PublishAsync(context.Principal, evt);

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

                // Do this before checking closed
                // as we want to see if it still gets reports.
                var stat = new ReportMapping()
                {
                    IncidentId    = incident.Id,
                    ErrorId       = report.ClientReportId,
                    ReceivedAtUtc = report.CreatedAtUtc
                };
                await _repository.StoreReportStats(stat);

                _logger.Debug("Storing stats " + JsonConvert.SerializeObject(stat));

                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);

                // Let's continue to receive reports once a day when
                // limit is reached (to get more fresh data, and still not load the system unnecessary).
                var timesSinceLastReport = DateTime.UtcNow.Subtract(incident.LastStoredReportUtc);
                if (incident.ReportCount > _reportConfig.Value.MaxReportsPerIncident &&
                    timesSinceLastReport < TimeSpan.FromMinutes(10))
                {
                    _repository.UpdateIncident(incident);
                    _logger.Debug($"Report count is more than {_reportConfig.Value.MaxReportsPerIncident}. Ignoring reports for incident {incident.Id}. Minutes since last report: " + timesSinceLastReport.TotalMinutes);
                    storeReport = false;
                    //don't exit here, since we want to be able to process reports
                }
            }

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

            report.IncidentId = incident.Id;

            if (storeReport)
            {
                incident.LastStoredReportUtc = DateTime.UtcNow;
                _repository.UpdateIncident(incident);
                _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();
            var e = new ReportAddedToIncident(summary, ConvertToCoreReport(report, applicationVersion), isReOpened)
            {
                IsNewIncident   = isNewIncident,
                IsStored        = storeReport,
                EnvironmentName = report.EnvironmentName
            };
            await context.SendAsync(e);

            if (storeReport)
            {
                await context.SendAsync(new ProcessInboundContextCollections());
            }

            if (sw.ElapsedMilliseconds > 200)
            {
                _logger.Debug($"PublishAsync took {sw.ElapsedMilliseconds}");
            }
            sw.Stop();
        }