Beispiel #1
0
        /// <summary>
        /// Uploads all log entries that contains an exception to codeRR.
        /// </summary>
        /// <param name="loggingEvent">The logging event.</param>
        protected override void Append(LoggingEvent loggingEvent)
        {
            LogsProvider.Instance.Add(new LogEntryDto(loggingEvent.TimeStampUtc, ConvertLevel(loggingEvent.Level), loggingEvent.RenderedMessage)
            {
                Exception = loggingEvent.ExceptionObject?.ToString(),
                Source    = loggingEvent.LoggerName,
            });
            if (loggingEvent.ExceptionObject == null)
            {
                return;
            }

            IErrorReporterContext context = new ErrorReporterContext(this, loggingEvent.ExceptionObject);
            var dataCollection            = new LogEntryDetails
            {
                LogLevel   = loggingEvent.Level.ToString(),
                Message    = loggingEvent.RenderedMessage,
                ThreadName = loggingEvent.ThreadName,
                Timestamp  = loggingEvent.TimeStamp,
                LoggerName = loggingEvent.LoggerName,
                UserName   = loggingEvent.UserName
            }.ToContextCollection("LogEntry");

            context.ContextCollections.Add(dataCollection);

            var coderrCollection = context.ContextCollections.GetCoderrCollection();

            coderrCollection.Properties[CoderrCollectionProperties.HighlightCollection] = "LogEntry";

            Err.Report(context);
        }
Beispiel #2
0
        /// <summary>
        ///     Build an report, but do not upload it
        /// </summary>
        /// <param name="context">
        ///     context passed to all context providers when collecting information. This context is typically
        ///     implemented by one of the integration libraries to provide more context that can be used to process the
        ///     environment.
        /// </param>
        /// <remarks>
        ///     <para>
        ///         Will collect context info and generate a report.
        ///     </para>
        /// </remarks>
        /// <exception cref="ArgumentNullException">exception;contextData</exception>
        public ErrorReportDTO Build(IErrorReporterContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (context.Exception is CoderrClientException)
            {
                return(null);
            }
            if (IsReported(context.Exception))
            {
                return(null);
            }
            ErrorReporterContext.MoveCollectionsInException(context.Exception, context.ContextCollections);
            InvokePreProcessor(context);

            _configuration.ContextProviders.Collect(context);

            // Invoke partition collection AFTER other context info providers
            // since those other collections might provide the property that
            // we want to create partions on.
            InvokePartitionCollection(context);

            var reportId = ReportIdGenerator.Generate(context.Exception);

            AddAddemblyVersion(context.ContextCollections);
            var report = new ErrorReportDTO(reportId, new ExceptionDTO(context.Exception),
                                            context.ContextCollections.ToArray());

            return(report);
        }
Beispiel #3
0
        public void should_assign_the_exception_so_that_we_have_something_to_work_with()
        {
            var ex = new Exception();

            var sut = new ErrorReporterContext(this, ex);

            sut.Exception.Should().Be(ex);
        }
Beispiel #4
0
        /// <summary>
        ///     Build an report, but do not upload it
        /// </summary>
        /// <param name="exception">caught exception</param>
        /// <remarks>
        ///     <para>
        ///         Will collect context info and generate a report.
        ///     </para>
        /// </remarks>
        public ErrorReportDTO Build(Exception exception)
        {
            var context     = new ErrorReporterContext(null, exception);
            var contextInfo = _configuration.ContextProviders.Collect(context);
            var reportId    = ReportIdGenerator.Generate(exception);

            return(new ErrorReportDTO(reportId, new ExceptionDTO(exception), contextInfo.ToArray()));
        }
Beispiel #5
0
        public void should_initialize_the_colleciton_to_avoid_confusion_and_nullreference()
        {
            var ex = new Exception();

            var sut = new ErrorReporterContext(this, ex);

            sut.ContextCollections.Should().BeEmpty();
        }
        public void Should_remove_old_entries()
        {
            _sut.Add(new LogEntryDto(DateTime.UtcNow.AddMinutes(-5).AddSeconds(-1), 3, "Hello"));
            var context = new ErrorReporterContext(this, new Exception());

            _sut.Collect(context);

            context.LogEntries.Should().BeNull();
        }
        public void Should_ignore_incorrect_codeRRContext()
        {
            var context = new ErrorReporterContext(this, new Exception());

            var sut    = new FormProvider();
            var result = sut.Collect(context);

            result.Should().BeNull();
        }
Beispiel #8
0
 /// <summary>
 ///     Generate an error report
 /// </summary>
 /// <param name="context">context</param>
 /// <returns>generated report</returns>
 /// <exception cref="ArgumentNullException"></exception>
 public static ErrorReportDTO GenerateReport(IErrorReporterContext context)
 {
     if (context == null)
     {
         throw new ArgumentNullException("context");
     }
     ErrorReporterContext.MoveCollectionsInException(context.Exception, context.ContextCollections);
     return(_exceptionProcessor.Build(context));
 }
        public void Should_add_existing_entry()
        {
            _sut.Add(new LogEntryDto(DateTime.UtcNow.AddMinutes(-3), 3, "Hello"));
            var context = new ErrorReporterContext(this, new Exception());

            _sut.Collect(context);

            context.LogEntries[0].Message.Should().Be("Hello");
        }
Beispiel #10
0
        public void Should_ignore_invalid_json_in_collection_alternative()
        {
            var ex = new Exception();

            ex.Data["ErrCollection.MyName2"] = "MEX";

            var sut = new ErrorReporterContext(this, ex);

            var actual = sut.GetCollectionProperty("MyName2", "JSON");

            actual.Should().Be("MEX");
        }
        public void should_Be_able_to_add_a_contextcollection()
        {
            var collector = Substitute.For <IContextCollectionProvider>();
            var ctx       = new ErrorReporterContext(this, new Exception("errror"));

            var sut = new ContextProvidersRegistrar();

            sut.Add(collector);
            sut.Collect(ctx);

            collector.Received().Collect(ctx);
        }
        public void should_not_use_removed_collectors()
        {
            var collector = Substitute.For <IContextCollectionProvider>();
            var ctx       = new ErrorReporterContext(this, new Exception("errror"));
            var sut       = new ContextProvidersRegistrar();

            sut.Add(collector);

            sut.Remove(collector.Name);
            sut.Collect(ctx);

            collector.DidNotReceiveWithAnyArgs().Collect(null);
        }
Beispiel #13
0
        /// <summary>
        ///     Report an exception using a custom context
        /// </summary>
        /// <param name="reporterContext">Context used to be able to collect context information</param>
        /// <param name="errorContextModel">Extra context collection(s).</param>
        public static void Report(IErrorReporterContext reporterContext, object errorContextModel)
        {
            if (reporterContext == null)
            {
                throw new ArgumentNullException(nameof(reporterContext));
            }
            ErrorReporterContext.MoveCollectionsInException(reporterContext.Exception,
                                                            reporterContext.ContextCollections);
            var collection = errorContextModel.ToContextCollection();

            reporterContext.ContextCollections.Add(collection);
            _exceptionProcessor.Process(reporterContext);
        }
        public void failing_collector_should_generate_a_collection_with_an_Error_to_be_Able_To_See_failures_serverSide()
        {
            var collector = Substitute.For <IContextCollectionProvider>();
            var ctx       = new ErrorReporterContext(this, new Exception("errror"));

            collector.When(x => x.Collect(ctx)).Do(x => throw new InvalidOperationException());

            var sut = new ContextProvidersRegistrar();

            sut.Add(collector);
            sut.Collect(ctx);

            ctx.ContextCollections.Last().Properties.Should().NotBeEmpty();
        }
Beispiel #15
0
        /// <summary>
        ///     Process exception.
        /// </summary>
        /// <param name="exception">caught exception</param>
        /// <remarks>
        ///     <para>
        ///         Will collect context info, generate a report, go through filters and finally upload it.
        ///     </para>
        /// </remarks>
        public void Process(Exception exception)
        {
            var context     = new ErrorReporterContext(null, exception);
            var contextInfo = _configuration.ContextProviders.Collect(context);
            var reportId    = ReportIdGenerator.Generate(exception);
            var report      = new ErrorReportDTO(reportId, new ExceptionDTO(exception), contextInfo.ToArray());
            var canUpload   = _configuration.FilterCollection.CanUploadReport(report);

            if (!canUpload)
            {
                return;
            }
            _configuration.Uploaders.Upload(report);
        }
Beispiel #16
0
        /// <summary>
        ///     Build an report, but do not upload it
        /// </summary>
        /// <param name="exception">caught exception</param>
        /// <remarks>
        ///     <para>
        ///         Will collect context info and generate a report.
        ///     </para>
        /// </remarks>
        /// <exception cref="ArgumentNullException">exception</exception>
        public ErrorReportDTO Build(Exception exception)
        {
            if (exception == null)
            {
                throw new ArgumentNullException(nameof(exception));
            }
            if (IsReported(exception))
            {
                return(null);
            }

            var context = new ErrorReporterContext(null, exception);

            return(Build(context));
        }
        public static string GetCollectionProperty(this ErrorReporterContext dto, string collectionName, string propertyName)
        {
            var col = dto.ContextCollections.FirstOrDefault(x => x.Name == collectionName);

            if (col != null)
            {
                return(col.Property(propertyName));
            }

            var collectionNames = string.Join(",", dto.ContextCollections.Select(x => x.Name));

            throw new AssertActualExpectedException(collectionName, null,
                                                    $"Failed to find collection \'{collectionName}\', existing collections: {collectionNames}."
                                                    );
        }
        public void Should_merge_with_existing_entries()
        {
            _sut.Add(new LogEntryDto(DateTime.UtcNow.AddMinutes(-3), 3, "Hello1"));
            _sut.Add(new LogEntryDto(DateTime.UtcNow.AddMinutes(-1), 3, "Hello3"));
            var context = new ErrorReporterContext(this, new Exception())
            {
                LogEntries = new[] { new LogEntryDto(DateTime.UtcNow.AddMinutes(-2), 3, "Hello2") }
            };

            _sut.Collect(context);

            context.LogEntries[0].Message.Should().Be("Hello1");
            context.LogEntries[1].Message.Should().Be("Hello2");
            context.LogEntries[2].Message.Should().Be("Hello3");
        }
Beispiel #19
0
        public void should_add_log_entries_from_context()
        {
            var dispatcher = Substitute.For <IUploadDispatcher>();
            var config     = new CoderrConfiguration(dispatcher);
            var ex         = new Exception("hello");
            var context    = new ErrorReporterContext(this, ex)
            {
                LogEntries = new LogEntryDto[] { new LogEntryDto(DateTime.UtcNow, 1, "Hello") }
            };

            var sut    = new ExceptionProcessor(config);
            var actual = sut.Build(context);

            actual.LogEntries[0].Message.Should().Be(context.LogEntries[0].Message);
        }
        public void failing_collectors_should_not_abort_the_processing()
        {
            var collector  = Substitute.For <IContextCollectionProvider>();
            var collector2 = Substitute.For <IContextCollectionProvider>();
            var ctx        = new ErrorReporterContext(this, new Exception("errror"));

            collector.When(x => x.Collect(ctx)).Do(x => throw new InvalidOperationException());

            var sut = new ContextProvidersRegistrar();

            sut.Add(collector);
            sut.Add(collector2);
            sut.Collect(ctx);

            collector2.Received().Collect(ctx);
        }
Beispiel #21
0
        public void Should_ignore_reports_that_have_already_been_reported_since_same_frameworks_have_multiple_injection_points_which_would_Report_the_same_exception()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();
            var ex     = new Exception("hello");
            var ctx    = new ErrorReporterContext(this, ex);

            config.Uploaders.Register(upl);
            ex.Data[ExceptionProcessor.AlreadyReportedSetting] = 1;

            var processor = new ExceptionProcessor(config);

            processor.Process(ctx);

            upl.Report.Should().BeNull("because report should have been ignored");
        }
Beispiel #22
0
        public void Should_be_able_to_move_collection()
        {
            var ex  = new Exception();
            var col = new ContextCollectionDTO("MyName", new Dictionary <string, string>()
            {
                { "Key", "Value" }
            });

            ex.Data["ErrCollection.MyName"] = JsonConvert.SerializeObject(col);

            var sut = new ErrorReporterContext(this, ex);

            var actual = sut.GetCollectionProperty("MyName", "Key");

            actual.Should().Be("Value");
        }
        public void clear_should_remove_all_collectors()
        {
            var collector1 = Substitute.For <IContextCollectionProvider>();
            var collector2 = Substitute.For <IContextCollectionProvider>();
            var ctx        = new ErrorReporterContext(this, new Exception("errror"));
            var sut        = new ContextProvidersRegistrar();

            sut.Add(collector1);
            sut.Add(collector2);

            sut.Clear();
            sut.Collect(ctx);

            collector1.DidNotReceiveWithAnyArgs().Collect(null);
            collector2.DidNotReceiveWithAnyArgs().Collect(null);
        }
Beispiel #24
0
        public void Filter_should_not_affect_non_filtered_reports()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();
            var filter = Substitute.For <IReportFilter>();
            var ctx    = new ErrorReporterContext(this, new Exception());

            config.Uploaders.Register(upl);
            config.FilterCollection.Add(filter);

            var processor = new ExceptionProcessor(config);

            processor.Process(ctx);

            upl.Report.Should().NotBeNull("because the report is not affected by the filter");
            filter.ReceivedWithAnyArgs().Invoke(null);
        }
Beispiel #25
0
        public void Should_be_able_to_filter_Reports()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();
            var filter = Substitute.For <IReportFilter>();
            var ctx    = new ErrorReporterContext(this, new Exception());

            config.Uploaders.Register(upl);
            config.FilterCollection.Add(filter);
            filter.Invoke(Arg.Do((ReportFilterContext context) => context.CanSubmitReport = false));


            var processor = new ExceptionProcessor(config);

            processor.Process(ctx);

            upl.Report.Should().BeNull("because report should have been filtered away");
        }
        public void Should_include_partitions_in_reports()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();
            var ex     = new Exception("hello");
            var ctx    = new ErrorReporterContext(this, ex);

            config.Uploaders.Register(upl);
            config.AddPartition(x =>
            {
                x.AddPartition("Id", "42");
            });

            var processor = new ExceptionProcessor(config);

            processor.Process(ctx);

            upl.Report.GetCollectionProperty("CoderrData", "ErrPartition.Id").Should().Be("42");
        }
        public void Should_ignore_reports_that_have_already_been_reported_since_same_frameworks_have_multiple_injection_points_which_would_Report_the_same_exception()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();
            var ex     = new Exception("hello");
            var ctx    = new ErrorReporterContext(this, ex);

            config.Uploaders.Register(upl);
            config.AddPartition(x =>
            {
                x.AddPartition("Id", "42");
            });

            var processor = new ExceptionProcessor(config);

            processor.Process(ctx);

            upl.Report.GetCollectionProperty("ErrPartitions", "Id").Should().Be("42");
        }
Beispiel #28
0
        public void Should_unpack_collections_that_are_attached_to_the_exception()
        {
            var upl    = new TestUploader();
            var config = new CoderrConfiguration();

            config.Uploaders.Register(upl);
            var json =
                @"{""$type"":""System.Collections.Generic.List`1[[codeRR.Client.Contracts.ContextCollectionDTO, Coderr.Client]], mscorlib"",""$values"":[{""Name"":""SqlCommand"",""Properties"":{""CommandText"":""WaitFor Delay '00:00:05'"",""CommandTimeout"":""3"",""ExecutionTime"":""00:00:03.0313327"",""OtherCommand[0]"":""select * from accounts where id=@id""}},{""Name"":""DbConnection"",""Properties"":{""ConnectionString"":""Data Source=.;Initial Catalog=OneTrueError;Integrated Security=True;Connect Timeout=30;multipleactiveresultsets=true"",""DataSource"":""."",""Database"":""OneTrueError"",""RunTime"":""00:00:03.0681702"",""State"":""Open"",""IsDisposed"":""False"",""ServerVersion"":""12.00.5207""}}]}";
            var ex  = new InvalidOperationException();
            var ctx = new ErrorReporterContext(this, ex);

            ex.Data["ErrCollections"] = json;

            var processor = new ExceptionProcessor(config);

            processor.Process(ctx);

            upl.Report.ContextCollections.Should().Contain(x => x.Name == "SqlCommand");
        }
        /// <summary>
        ///     Build an report, but do not upload it
        /// </summary>
        /// <param name="exception">caught exception</param>
        /// <param name="contextData">context data</param>
        /// <remarks>
        ///     <para>
        ///         Will collect context info and generate a report.
        ///     </para>
        /// </remarks>
        public ErrorReportDTO Build(Exception exception, object contextData)
        {
            if (exception is CoderrClientException)
            {
                return(null);
            }
            if (exception.Data.Contains(AlreadyReportedSetting))
            {
                return(null);
            }

            var context = new ErrorReporterContext(null, exception);

            if (contextData != null)
            {
                AppendCustomContextData(contextData, context.ContextCollections);
            }

            return(Build(context));
        }
Beispiel #30
0
        /// <summary>
        ///     Build an report, but do not upload it
        /// </summary>
        /// <param name="exception">caught exception</param>
        /// <param name="contextData">context data</param>
        /// <remarks>
        ///     <para>
        ///         Will collect context info and generate a report.
        ///     </para>
        /// </remarks>
        /// <exception cref="ArgumentNullException">exception;contextData</exception>
        public ErrorReportDTO Build(Exception exception, object contextData)
        {
            if (exception == null)
            {
                throw new ArgumentNullException(nameof(exception));
            }
            if (contextData == null)
            {
                throw new ArgumentNullException(nameof(contextData));
            }
            if (IsReported(exception))
            {
                return(null);
            }

            var context = new ErrorReporterContext(null, exception);

            AppendCustomContextData(contextData, context.ContextCollections);
            return(Build(context));
        }