From 6eb6dbe21f211b0245ad7fe960246769e8ba5ae3 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Tue, 9 Jul 2024 16:40:23 +0200 Subject: [PATCH 01/15] Record dropped spans --- .../client_report_recorder.dart | 6 +- .../src/client_reports/discarded_event.dart | 2 + .../noop_client_report_recorder.dart | 3 +- dart/lib/src/hub.dart | 5 ++ dart/lib/src/sentry_client.dart | 36 ++++++++--- dart/lib/src/transport/data_category.dart | 1 + dart/test/hub_test.dart | 15 ++++- .../mocks/mock_client_report_recorder.dart | 7 ++- dart/test/sentry_client_test.dart | 61 +++++++++++++++++++ 9 files changed, 120 insertions(+), 16 deletions(-) diff --git a/dart/lib/src/client_reports/client_report_recorder.dart b/dart/lib/src/client_reports/client_report_recorder.dart index d064941f84..045168f0c5 100644 --- a/dart/lib/src/client_reports/client_report_recorder.dart +++ b/dart/lib/src/client_reports/client_report_recorder.dart @@ -13,11 +13,11 @@ class ClientReportRecorder { final ClockProvider _clock; final Map<_QuantityKey, int> _quantities = {}; - void recordLostEvent( - final DiscardReason reason, final DataCategory category) { + void recordLostEvent(final DiscardReason reason, final DataCategory category, + {int count = 1}) { final key = _QuantityKey(reason, category); var current = _quantities[key] ?? 0; - _quantities[key] = current + 1; + _quantities[key] = current + count; } ClientReport? flush() { diff --git a/dart/lib/src/client_reports/discarded_event.dart b/dart/lib/src/client_reports/discarded_event.dart index 01caa31ca2..2d413e01a7 100644 --- a/dart/lib/src/client_reports/discarded_event.dart +++ b/dart/lib/src/client_reports/discarded_event.dart @@ -54,6 +54,8 @@ extension _DataCategoryExtension on DataCategory { return 'session'; case DataCategory.transaction: return 'transaction'; + case DataCategory.span: + return 'span'; case DataCategory.attachment: return 'attachment'; case DataCategory.security: diff --git a/dart/lib/src/client_reports/noop_client_report_recorder.dart b/dart/lib/src/client_reports/noop_client_report_recorder.dart index acd6472347..b03bd9c9ef 100644 --- a/dart/lib/src/client_reports/noop_client_report_recorder.dart +++ b/dart/lib/src/client_reports/noop_client_report_recorder.dart @@ -15,5 +15,6 @@ class NoOpClientReportRecorder implements ClientReportRecorder { } @override - void recordLostEvent(DiscardReason reason, DataCategory category) {} + void recordLostEvent(DiscardReason reason, DataCategory category, + {int count = 1}) {} } diff --git a/dart/lib/src/hub.dart b/dart/lib/src/hub.dart index a8e06e28ed..b69bc5056f 100644 --- a/dart/lib/src/hub.dart +++ b/dart/lib/src/hub.dart @@ -542,6 +542,11 @@ class Hub { DiscardReason.sampleRate, DataCategory.transaction, ); + _options.recorder.recordLostEvent( + DiscardReason.sampleRate, + DataCategory.span, + count: transaction.spans.length + 1, + ); _options.logger( SentryLevel.warning, 'Transaction ${transaction.eventId} was dropped due to sampling decision.', diff --git a/dart/lib/src/sentry_client.dart b/dart/lib/src/sentry_client.dart index 63fcbfb421..71c414ae8f 100644 --- a/dart/lib/src/sentry_client.dart +++ b/dart/lib/src/sentry_client.dart @@ -84,7 +84,8 @@ class SentryClient { Hint? hint, }) async { if (_sampleRate()) { - _recordLostEvent(event, DiscardReason.sampleRate); + _options.recorder + .recordLostEvent(DiscardReason.sampleRate, _getCategory(event)); _options.logger( SentryLevel.debug, 'Event ${event.eventId.toString()} was dropped due to sampling decision.', @@ -404,6 +405,8 @@ class SentryClient { Hint hint, ) async { SentryEvent? eventOrTransaction = event; + final spanCountBeforeCallback = + event is SentryTransaction ? event.spans.length : 0; final beforeSend = _options.beforeSend; final beforeSendTransaction = _options.beforeSendTransaction; @@ -439,11 +442,28 @@ class SentryClient { } if (eventOrTransaction == null) { - _recordLostEvent(event, DiscardReason.beforeSend); + _options.recorder + .recordLostEvent(DiscardReason.beforeSend, _getCategory(event)); + if (event is SentryTransaction) { + // We dropped the whole transaction, the dropped count includes all child spans + 1 root span + _options.recorder.recordLostEvent( + DiscardReason.beforeSend, DataCategory.span, + count: spanCountBeforeCallback + 1); + } _options.logger( SentryLevel.debug, '${event.runtimeType} was dropped by $beforeSendName callback', ); + } else if (event is SentryTransaction && + eventOrTransaction is SentryTransaction) { + // If beforeSend removed spans but not all we still record them as lost + final spanCountAfterCallback = eventOrTransaction.spans.length; + final droppedSpanCount = spanCountBeforeCallback - spanCountAfterCallback; + if (droppedSpanCount > 0) { + _options.recorder.recordLostEvent( + DiscardReason.beforeSend, DataCategory.span, + count: droppedSpanCount); + } } return eventOrTransaction; @@ -475,7 +495,8 @@ class SentryClient { } } if (processedEvent == null) { - _recordLostEvent(event, DiscardReason.eventProcessor); + _options.recorder + .recordLostEvent(DiscardReason.eventProcessor, _getCategory(event)); _options.logger(SentryLevel.debug, 'Event was dropped by a processor'); break; } @@ -490,14 +511,11 @@ class SentryClient { return false; } - void _recordLostEvent(SentryEvent event, DiscardReason reason) { - DataCategory category; + DataCategory _getCategory(SentryEvent event) { if (event is SentryTransaction) { - category = DataCategory.transaction; - } else { - category = DataCategory.error; + return DataCategory.transaction; } - _options.recorder.recordLostEvent(reason, category); + return DataCategory.error; } Future _attachClientReportsAndSend(SentryEnvelope envelope) { diff --git a/dart/lib/src/transport/data_category.dart b/dart/lib/src/transport/data_category.dart index ecdb1c9500..f54db98f1b 100644 --- a/dart/lib/src/transport/data_category.dart +++ b/dart/lib/src/transport/data_category.dart @@ -5,6 +5,7 @@ enum DataCategory { error, session, transaction, + span, attachment, security, metricBucket, diff --git a/dart/test/hub_test.dart b/dart/test/hub_test.dart index 8dcc622654..c53ab74e48 100644 --- a/dart/test/hub_test.dart +++ b/dart/test/hub_test.dart @@ -694,11 +694,22 @@ void main() { test('record sample rate dropping transaction', () async { final hub = fixture.getSut(sampled: false); var transaction = SentryTransaction(fixture.tracer); + fixture.tracer.startChild('child1'); + fixture.tracer.startChild('child2'); + fixture.tracer.startChild('child3'); await hub.captureTransaction(transaction); - expect(fixture.recorder.reason, DiscardReason.sampleRate); - expect(fixture.recorder.category, DataCategory.transaction); + expect(fixture.recorder.discardedEvents.length, 2); + + // we dropped the whole tracer and it has 3 span children so the span count should be 4 + // 3 children + 1 root span + final spanCount = fixture.recorder.discardedEvents + .firstWhere((element) => + element.category == DataCategory.span && + element.reason == DiscardReason.sampleRate) + .quantity; + expect(spanCount, 4); }); }); diff --git a/dart/test/mocks/mock_client_report_recorder.dart b/dart/test/mocks/mock_client_report_recorder.dart index fa1af54ed8..a84b67215d 100644 --- a/dart/test/mocks/mock_client_report_recorder.dart +++ b/dart/test/mocks/mock_client_report_recorder.dart @@ -1,9 +1,12 @@ import 'package:sentry/src/client_reports/client_report_recorder.dart'; import 'package:sentry/src/client_reports/discard_reason.dart'; import 'package:sentry/src/client_reports/client_report.dart'; +import 'package:sentry/src/client_reports/discarded_event.dart'; import 'package:sentry/src/transport/data_category.dart'; class MockClientReportRecorder implements ClientReportRecorder { + List discardedEvents = []; + DiscardReason? reason; DataCategory? category; @@ -18,8 +21,10 @@ class MockClientReportRecorder implements ClientReportRecorder { } @override - void recordLostEvent(DiscardReason reason, DataCategory category) { + void recordLostEvent(DiscardReason reason, DataCategory category, + {int count = 1}) { this.reason = reason; this.category = category; + discardedEvents.add(DiscardedEvent(reason, category, count)); } } diff --git a/dart/test/sentry_client_test.dart b/dart/test/sentry_client_test.dart index 153c1515f0..8c9e1fe54e 100644 --- a/dart/test/sentry_client_test.dart +++ b/dart/test/sentry_client_test.dart @@ -1444,6 +1444,67 @@ void main() { expect(fixture.recorder.category, DataCategory.error); }); + test('transaction dropped by beforeSendTransaction is recorded', () async { + final sut = fixture.getSut(); + final transaction = SentryTransaction(fixture.tracer); + fixture.tracer.startChild('child1'); + fixture.tracer.startChild('child2'); + fixture.tracer.startChild('child3'); + + fixture.options.beforeSendTransaction = (transaction) { + if (transaction.tracer == fixture.tracer) { + return null; + } + return transaction; + }; + + await sut.captureTransaction(transaction); + + // 1 for the transaction and 1 for the spans + expect(fixture.recorder.discardedEvents.length, 2); + + // we dropped the whole tracer and it has 3 span children so the span count should be 4 + // 3 children + 1 root span + final spanCount = fixture.recorder.discardedEvents + .firstWhere((element) => + element.category == DataCategory.span && + element.reason == DiscardReason.beforeSend) + .quantity; + expect(spanCount, 4); + }); + + test( + 'transaction dropped partial spans by beforeSendTransaction is recorded', + () async { + final sut = fixture.getSut(); + final transaction = SentryTransaction(fixture.tracer); + fixture.tracer.startChild('child1'); + fixture.tracer.startChild('child2'); + fixture.tracer.startChild('child3'); + + fixture.options.beforeSendTransaction = (transaction) { + if (transaction.tracer == fixture.tracer) { + transaction.spans + .removeWhere((element) => element.context.operation == 'child2'); + return transaction; + } + return transaction; + }; + + await sut.captureTransaction(transaction); + + // we didn't drop the whole transaction, we only have 1 event for the dropped spans + expect(fixture.recorder.discardedEvents.length, 1); + + // tracer has 3 span children and we dropped 1 of them + final spanCount = fixture.recorder.discardedEvents + .firstWhere((element) => + element.category == DataCategory.span && + element.reason == DiscardReason.beforeSend) + .quantity; + expect(spanCount, 1); + }); + test('record event processor dropping transaction', () async { final client = fixture.getSut(eventProcessor: DropAllEventProcessor()); From ab8e9ea254f79544eae93c000b525cae934f8e73 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Tue, 9 Jul 2024 17:04:16 +0200 Subject: [PATCH 02/15] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d024ca890..d00aecb6a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Features +- Record dropped spans in client reports for Web, Linux and Windows ([#2154](https://github.com/getsentry/sentry-dart/pull/2154)) - Add memory usage to contexts ([#2133](https://github.com/getsentry/sentry-dart/pull/2133)) - Only for Linux/Windows applications, as iOS/Android/macOS use native SDKs From 8ad162fbd64686a0d3fbfbebe18399fb155b661f Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Tue, 9 Jul 2024 19:19:03 +0200 Subject: [PATCH 03/15] Naming --- dart/lib/src/sentry_client.dart | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dart/lib/src/sentry_client.dart b/dart/lib/src/sentry_client.dart index 71c414ae8f..ccd841b995 100644 --- a/dart/lib/src/sentry_client.dart +++ b/dart/lib/src/sentry_client.dart @@ -404,7 +404,7 @@ class SentryClient { SentryEvent event, Hint hint, ) async { - SentryEvent? eventOrTransaction = event; + SentryEvent? processedEvent = event; final spanCountBeforeCallback = event is SentryTransaction ? event.spans.length : 0; @@ -415,18 +415,18 @@ class SentryClient { try { if (event is SentryTransaction && beforeSendTransaction != null) { beforeSendName = 'beforeSendTransaction'; - final e = beforeSendTransaction(event); - if (e is Future) { - eventOrTransaction = await e; + final callbackResult = beforeSendTransaction(event); + if (callbackResult is Future) { + processedEvent = await callbackResult; } else { - eventOrTransaction = e; + processedEvent = callbackResult; } } else if (beforeSend != null) { - final e = beforeSend(event, hint); - if (e is Future) { - eventOrTransaction = await e; + final callbackResult = beforeSend(event, hint); + if (callbackResult is Future) { + processedEvent = await callbackResult; } else { - eventOrTransaction = e; + processedEvent = callbackResult; } } } catch (exception, stackTrace) { @@ -441,7 +441,7 @@ class SentryClient { } } - if (eventOrTransaction == null) { + if (processedEvent == null) { _options.recorder .recordLostEvent(DiscardReason.beforeSend, _getCategory(event)); if (event is SentryTransaction) { @@ -455,9 +455,9 @@ class SentryClient { '${event.runtimeType} was dropped by $beforeSendName callback', ); } else if (event is SentryTransaction && - eventOrTransaction is SentryTransaction) { - // If beforeSend removed spans but not all we still record them as lost - final spanCountAfterCallback = eventOrTransaction.spans.length; + processedEvent is SentryTransaction) { + // If beforeSend removed only some spans we still report them as dropped + final spanCountAfterCallback = processedEvent.spans.length; final droppedSpanCount = spanCountBeforeCallback - spanCountAfterCallback; if (droppedSpanCount > 0) { _options.recorder.recordLostEvent( @@ -466,7 +466,7 @@ class SentryClient { } } - return eventOrTransaction; + return processedEvent; } Future _runEventProcessors( From dccede3f7f7cb4de4cb8c77dd4675d6e3c2ae2dd Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 10 Jul 2024 08:17:50 +0200 Subject: [PATCH 04/15] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a6294383b..762fb18dac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Features -- Record dropped spans in client reports for Web, Linux and Windows ([#2154](https://github.com/getsentry/sentry-dart/pull/2154)) +- Record dropped spans in client reports ([#2154](https://github.com/getsentry/sentry-dart/pull/2154)) - Add memory usage to contexts ([#2133](https://github.com/getsentry/sentry-dart/pull/2133)) - Only for Linux/Windows applications, as iOS/Android/macOS use native SDKs From 1e0eafed82235c8d4d4324fefeb3593b07e3831f Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Wed, 10 Jul 2024 09:24:17 +0200 Subject: [PATCH 05/15] Send dropped event as well for rate limit and network error --- dart/lib/src/sentry_envelope_item.dart | 34 ++++++++++++++-------- dart/lib/src/transport/data_category.dart | 21 +++++++++++++- dart/lib/src/transport/rate_limiter.dart | 35 +++++++++-------------- dart/lib/src/utils/transport_utils.dart | 15 ++++++++++ 4 files changed, 71 insertions(+), 34 deletions(-) diff --git a/dart/lib/src/sentry_envelope_item.dart b/dart/lib/src/sentry_envelope_item.dart index 019e1e0a08..2158ec80de 100644 --- a/dart/lib/src/sentry_envelope_item.dart +++ b/dart/lib/src/sentry_envelope_item.dart @@ -1,6 +1,8 @@ import 'dart:async'; import 'dart:convert'; +import 'package:meta/meta.dart'; + import 'client_reports/client_report.dart'; import 'metrics/metric.dart'; import 'protocol.dart'; @@ -12,7 +14,10 @@ import 'sentry_user_feedback.dart'; /// Item holding header information and JSON encoded data. class SentryEnvelopeItem { - SentryEnvelopeItem(this.header, this.dataFactory); + /// The original, non-encoded object, used when direct access to the source data is needed. + Object? originalObject; + + SentryEnvelopeItem(this.header, this.dataFactory, {this.originalObject}); /// Creates a [SentryEnvelopeItem] which sends [SentryTransaction]. factory SentryEnvelopeItem.fromTransaction(SentryTransaction transaction) { @@ -24,7 +29,8 @@ class SentryEnvelopeItem { cachedItem.getDataLength, contentType: 'application/json', ); - return SentryEnvelopeItem(header, cachedItem.getData); + return SentryEnvelopeItem(header, cachedItem.getData, + originalObject: transaction); } factory SentryEnvelopeItem.fromAttachment(SentryAttachment attachment) { @@ -37,7 +43,8 @@ class SentryEnvelopeItem { fileName: attachment.filename, attachmentType: attachment.attachmentType, ); - return SentryEnvelopeItem(header, cachedItem.getData); + return SentryEnvelopeItem(header, cachedItem.getData, + originalObject: attachment); } /// Create a [SentryEnvelopeItem] which sends [SentryUserFeedback]. @@ -50,7 +57,8 @@ class SentryEnvelopeItem { cachedItem.getDataLength, contentType: 'application/json', ); - return SentryEnvelopeItem(header, cachedItem.getData); + return SentryEnvelopeItem(header, cachedItem.getData, + originalObject: feedback); } /// Create a [SentryEnvelopeItem] which holds the [SentryEvent] data. @@ -59,13 +67,13 @@ class SentryEnvelopeItem { _CachedItem(() async => utf8JsonEncoder.convert(event.toJson())); return SentryEnvelopeItem( - SentryEnvelopeItemHeader( - SentryItemType.event, - cachedItem.getDataLength, - contentType: 'application/json', - ), - cachedItem.getData, - ); + SentryEnvelopeItemHeader( + SentryItemType.event, + cachedItem.getDataLength, + contentType: 'application/json', + ), + cachedItem.getData, + originalObject: event); } /// Create a [SentryEnvelopeItem] which holds the [ClientReport] data. @@ -80,6 +88,7 @@ class SentryEnvelopeItem { contentType: 'application/json', ), cachedItem.getData, + originalObject: clientReport, ); } @@ -102,7 +111,8 @@ class SentryEnvelopeItem { cachedItem.getDataLength, contentType: 'application/octet-stream', ); - return SentryEnvelopeItem(header, cachedItem.getData); + return SentryEnvelopeItem(header, cachedItem.getData, + originalObject: buckets); } /// Header with info about type and length of data in bytes. diff --git a/dart/lib/src/transport/data_category.dart b/dart/lib/src/transport/data_category.dart index f54db98f1b..cbfb26ea58 100644 --- a/dart/lib/src/transport/data_category.dart +++ b/dart/lib/src/transport/data_category.dart @@ -9,5 +9,24 @@ enum DataCategory { attachment, security, metricBucket, - unknown + unknown; + + static DataCategory fromItemType(String itemType) { + switch (itemType) { + case 'event': + return DataCategory.error; + case 'session': + return DataCategory.session; + case 'attachment': + return DataCategory.attachment; + case 'transaction': + return DataCategory.transaction; + // The envelope item type used for metrics is statsd, + // whereas the client report category is metric_bucket + case 'statsd': + return DataCategory.metricBucket; + default: + return DataCategory.unknown; + } + } } diff --git a/dart/lib/src/transport/rate_limiter.dart b/dart/lib/src/transport/rate_limiter.dart index ef9b168edd..cbc4f3893b 100644 --- a/dart/lib/src/transport/rate_limiter.dart +++ b/dart/lib/src/transport/rate_limiter.dart @@ -1,3 +1,6 @@ +import 'dart:convert'; + +import '../../sentry.dart'; import '../transport/rate_limit_parser.dart'; import '../sentry_options.dart'; import '../sentry_envelope.dart'; @@ -25,8 +28,17 @@ class RateLimiter { _options.recorder.recordLostEvent( DiscardReason.rateLimitBackoff, - _categoryFromItemType(item.header.type), + DataCategory.fromItemType(item.header.type), ); + + final originalObject = item.originalObject; + if (originalObject is SentryTransaction) { + _options.recorder.recordLostEvent( + DiscardReason.rateLimitBackoff, + DataCategory.span, + count: originalObject.spans.length + 1, + ); + } } } @@ -80,7 +92,7 @@ class RateLimiter { // Private bool _isRetryAfter(String itemType) { - final dataCategory = _categoryFromItemType(itemType); + final dataCategory = DataCategory.fromItemType(itemType); final currentDate = DateTime.fromMillisecondsSinceEpoch( _options.clock().millisecondsSinceEpoch); @@ -106,25 +118,6 @@ class RateLimiter { return false; } - DataCategory _categoryFromItemType(String itemType) { - switch (itemType) { - case 'event': - return DataCategory.error; - case 'session': - return DataCategory.session; - case 'attachment': - return DataCategory.attachment; - case 'transaction': - return DataCategory.transaction; - // The envelope item type used for metrics is statsd, - // whereas the client report category is metric_bucket - case 'statsd': - return DataCategory.metricBucket; - default: - return DataCategory.unknown; - } - } - void _applyRetryAfterOnlyIfLonger(DataCategory dataCategory, DateTime date) { final oldDate = _rateLimitedUntil[dataCategory]; diff --git a/dart/lib/src/utils/transport_utils.dart b/dart/lib/src/utils/transport_utils.dart index fa2f20096a..26716ea9b5 100644 --- a/dart/lib/src/utils/transport_utils.dart +++ b/dart/lib/src/utils/transport_utils.dart @@ -19,6 +19,21 @@ class TransportUtils { } if (response.statusCode >= 400 && response.statusCode != 429) { + for (final item in envelope.items) { + options.recorder.recordLostEvent( + DiscardReason.networkError, + DataCategory.fromItemType(item.header.type), + ); + + final originalObject = item.originalObject; + if (originalObject is SentryTransaction) { + options.recorder.recordLostEvent( + DiscardReason.networkError, + DataCategory.span, + count: originalObject.spans.length + 1, + ); + } + } options.recorder .recordLostEvent(DiscardReason.networkError, DataCategory.error); } From dc50f69f5ce278b144c2c4916267ac8d526afa63 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Wed, 10 Jul 2024 09:42:39 +0200 Subject: [PATCH 06/15] Update --- dart/lib/src/utils/transport_utils.dart | 2 - .../mocks/mock_client_report_recorder.dart | 5 -- dart/test/protocol/rate_limiter_test.dart | 34 +++++++++-- dart/test/sentry_client_test.dart | 24 +++++--- dart/test/transport/http_transport_test.dart | 61 +++++++++++++++++-- 5 files changed, 99 insertions(+), 27 deletions(-) diff --git a/dart/lib/src/utils/transport_utils.dart b/dart/lib/src/utils/transport_utils.dart index 26716ea9b5..399809b179 100644 --- a/dart/lib/src/utils/transport_utils.dart +++ b/dart/lib/src/utils/transport_utils.dart @@ -34,8 +34,6 @@ class TransportUtils { ); } } - options.recorder - .recordLostEvent(DiscardReason.networkError, DataCategory.error); } } else { options.logger( diff --git a/dart/test/mocks/mock_client_report_recorder.dart b/dart/test/mocks/mock_client_report_recorder.dart index a84b67215d..4d8eaa5b1d 100644 --- a/dart/test/mocks/mock_client_report_recorder.dart +++ b/dart/test/mocks/mock_client_report_recorder.dart @@ -7,9 +7,6 @@ import 'package:sentry/src/transport/data_category.dart'; class MockClientReportRecorder implements ClientReportRecorder { List discardedEvents = []; - DiscardReason? reason; - DataCategory? category; - ClientReport? clientReport; bool flushCalled = false; @@ -23,8 +20,6 @@ class MockClientReportRecorder implements ClientReportRecorder { @override void recordLostEvent(DiscardReason reason, DataCategory category, {int count = 1}) { - this.reason = reason; - this.category = category; discardedEvents.add(DiscardedEvent(reason, category, count)); } } diff --git a/dart/test/protocol/rate_limiter_test.dart b/dart/test/protocol/rate_limiter_test.dart index 1f52a60003..35c266d86b 100644 --- a/dart/test/protocol/rate_limiter_test.dart +++ b/dart/test/protocol/rate_limiter_test.dart @@ -1,5 +1,7 @@ +import 'package:collection/collection.dart'; import 'package:sentry/sentry.dart'; import 'package:sentry/src/client_reports/discard_reason.dart'; +import 'package:sentry/src/client_reports/discarded_event.dart'; import 'package:sentry/src/transport/data_category.dart'; import 'package:test/test.dart'; @@ -9,6 +11,7 @@ import 'package:sentry/src/sentry_envelope_header.dart'; import '../mocks/mock_client_report_recorder.dart'; import '../mocks/mock_hub.dart'; +import 'breadcrumb_test.dart'; void main() { var fixture = Fixture(); @@ -205,14 +208,18 @@ void main() { final result = rateLimiter.filter(eventEnvelope); expect(result, isNull); - expect(fixture.mockRecorder.category, DataCategory.error); - expect(fixture.mockRecorder.reason, DiscardReason.rateLimitBackoff); + expect(fixture.mockRecorder.discardedEvents.first.category, + DataCategory.error); + expect(fixture.mockRecorder.discardedEvents.first.reason, + DiscardReason.rateLimitBackoff); }); test('dropping of transaction recorded', () { final rateLimiter = fixture.getSut(); final transaction = fixture.getTransaction(); + transaction.tracer.startChild('child1'); + transaction.tracer.startChild('child2'); final eventItem = SentryEnvelopeItem.fromTransaction(transaction); final eventEnvelope = SentryEnvelope( SentryEnvelopeHeader.newEventId(), @@ -225,8 +232,21 @@ void main() { final result = rateLimiter.filter(eventEnvelope); expect(result, isNull); - expect(fixture.mockRecorder.category, DataCategory.transaction); - expect(fixture.mockRecorder.reason, DiscardReason.rateLimitBackoff); + expect(fixture.mockRecorder.discardedEvents.length, 2); + + final transactionDiscardedEvent = fixture.mockRecorder.discardedEvents + .firstWhereOrNull((element) => + element.category == DataCategory.transaction && + element.reason == DiscardReason.rateLimitBackoff); + + final spanDiscardedEvent = fixture.mockRecorder.discardedEvents + .firstWhereOrNull((element) => + element.category == DataCategory.span && + element.reason == DiscardReason.rateLimitBackoff); + + expect(transactionDiscardedEvent, isNotNull); + expect(spanDiscardedEvent, isNotNull); + expect(spanDiscardedEvent!.quantity, 3); }); test('dropping of metrics recorded', () { @@ -244,8 +264,10 @@ void main() { final result = rateLimiter.filter(eventEnvelope); expect(result, isNull); - expect(fixture.mockRecorder.category, DataCategory.metricBucket); - expect(fixture.mockRecorder.reason, DiscardReason.rateLimitBackoff); + expect(fixture.mockRecorder.discardedEvents.first.category, + DataCategory.metricBucket); + expect(fixture.mockRecorder.discardedEvents.first.reason, + DiscardReason.rateLimitBackoff); }); group('apply rateLimit', () { diff --git a/dart/test/sentry_client_test.dart b/dart/test/sentry_client_test.dart index 8c9e1fe54e..26fceaea42 100644 --- a/dart/test/sentry_client_test.dart +++ b/dart/test/sentry_client_test.dart @@ -1440,8 +1440,10 @@ void main() { await client.captureEvent(fakeEvent); - expect(fixture.recorder.reason, DiscardReason.eventProcessor); - expect(fixture.recorder.category, DataCategory.error); + expect(fixture.recorder.discardedEvents.first.reason, + DiscardReason.eventProcessor); + expect( + fixture.recorder.discardedEvents.first.category, DataCategory.error); }); test('transaction dropped by beforeSendTransaction is recorded', () async { @@ -1514,8 +1516,10 @@ void main() { await client.captureTransaction(transaction); - expect(fixture.recorder.reason, DiscardReason.eventProcessor); - expect(fixture.recorder.category, DataCategory.transaction); + expect(fixture.recorder.discardedEvents.first.reason, + DiscardReason.eventProcessor); + expect(fixture.recorder.discardedEvents.first.category, + DataCategory.transaction); }); test('record beforeSend dropping event', () async { @@ -1525,8 +1529,10 @@ void main() { await client.captureEvent(fakeEvent); - expect(fixture.recorder.reason, DiscardReason.beforeSend); - expect(fixture.recorder.category, DataCategory.error); + expect(fixture.recorder.discardedEvents.first.reason, + DiscardReason.beforeSend); + expect( + fixture.recorder.discardedEvents.first.category, DataCategory.error); }); test('record sample rate dropping event', () async { @@ -1536,8 +1542,10 @@ void main() { await client.captureEvent(fakeEvent); - expect(fixture.recorder.reason, DiscardReason.sampleRate); - expect(fixture.recorder.category, DataCategory.error); + expect(fixture.recorder.discardedEvents.first.reason, + DiscardReason.sampleRate); + expect( + fixture.recorder.discardedEvents.first.category, DataCategory.error); }); test('user feedback envelope contains dsn', () async { diff --git a/dart/test/transport/http_transport_test.dart b/dart/test/transport/http_transport_test.dart index 8319e21b7d..b3618393d3 100644 --- a/dart/test/transport/http_transport_test.dart +++ b/dart/test/transport/http_transport_test.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:collection/collection.dart'; import 'package:http/http.dart' as http; import 'package:http/testing.dart'; import 'package:sentry/sentry.dart'; @@ -7,6 +8,7 @@ import 'package:sentry/src/client_reports/discard_reason.dart'; import 'package:sentry/src/sentry_envelope_header.dart'; import 'package:sentry/src/sentry_envelope_item_header.dart'; import 'package:sentry/src/sentry_item_type.dart'; +import 'package:sentry/src/sentry_tracer.dart'; import 'package:sentry/src/transport/data_category.dart'; import 'package:sentry/src/transport/http_transport.dart'; import 'package:sentry/src/transport/rate_limiter.dart'; @@ -14,6 +16,7 @@ import 'package:test/test.dart'; import '../mocks.dart'; import '../mocks/mock_client_report_recorder.dart'; +import '../mocks/mock_hub.dart'; void main() { SentryEnvelope givenEnvelope() { @@ -205,8 +208,42 @@ void main() { ); await sut.send(envelope); - expect(fixture.clientReportRecorder.reason, DiscardReason.networkError); - expect(fixture.clientReportRecorder.category, DataCategory.error); + expect(fixture.clientReportRecorder.discardedEvents.first.reason, + DiscardReason.networkError); + expect(fixture.clientReportRecorder.discardedEvents.first.category, + DataCategory.error); + }); + + test('does records lost transaction and span for error >= 400', () async { + final httpMock = MockClient((http.Request request) async { + return http.Response('{}', 400); + }); + final sut = fixture.getSut(httpMock, MockRateLimiter()); + + final transaction = fixture.getTransaction(); + transaction.tracer.startChild('child1'); + transaction.tracer.startChild('child2'); + final envelope = SentryEnvelope.fromTransaction( + transaction, + fixture.options.sdk, + dsn: fixture.options.dsn, + ); + await sut.send(envelope); + + final transactionDiscardedEvent = fixture + .clientReportRecorder.discardedEvents + .firstWhereOrNull((element) => + element.category == DataCategory.transaction && + element.reason == DiscardReason.networkError); + + final spanDiscardedEvent = fixture.clientReportRecorder.discardedEvents + .firstWhereOrNull((element) => + element.category == DataCategory.span && + element.reason == DiscardReason.networkError); + + expect(transactionDiscardedEvent, isNotNull); + expect(spanDiscardedEvent, isNotNull); + expect(spanDiscardedEvent!.quantity, 3); }); test('does not record lost event for error 429', () async { @@ -223,8 +260,8 @@ void main() { ); await sut.send(envelope); - expect(fixture.clientReportRecorder.reason, null); - expect(fixture.clientReportRecorder.category, null); + expect(fixture.clientReportRecorder.discardedEvents.first.reason, null); + expect(fixture.clientReportRecorder.discardedEvents.first.category, null); }); test('does record lost event for error >= 500', () async { @@ -241,8 +278,10 @@ void main() { ); await sut.send(envelope); - expect(fixture.clientReportRecorder.reason, DiscardReason.networkError); - expect(fixture.clientReportRecorder.category, DataCategory.error); + expect(fixture.clientReportRecorder.discardedEvents.first.reason, + DiscardReason.networkError); + expect(fixture.clientReportRecorder.discardedEvents.first.category, + DataCategory.error); }); }); } @@ -262,4 +301,14 @@ class Fixture { }; return HttpTransport(options, rateLimiter); } + + SentryTransaction getTransaction() { + final context = SentryTransactionContext( + 'name', + 'op', + samplingDecision: SentryTracesSamplingDecision(true), + ); + final tracer = SentryTracer(context, MockHub()); + return SentryTransaction(tracer); + } } From 747ee854ba3e0580ae78c460e9f097afc0627919 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Wed, 10 Jul 2024 09:46:03 +0200 Subject: [PATCH 07/15] Dart analyze --- dart/lib/src/sentry_envelope_item.dart | 2 -- dart/lib/src/transport/rate_limiter.dart | 5 ----- dart/test/protocol/rate_limiter_test.dart | 2 -- 3 files changed, 9 deletions(-) diff --git a/dart/lib/src/sentry_envelope_item.dart b/dart/lib/src/sentry_envelope_item.dart index 2158ec80de..b0f19cfccd 100644 --- a/dart/lib/src/sentry_envelope_item.dart +++ b/dart/lib/src/sentry_envelope_item.dart @@ -1,8 +1,6 @@ import 'dart:async'; import 'dart:convert'; -import 'package:meta/meta.dart'; - import 'client_reports/client_report.dart'; import 'metrics/metric.dart'; import 'protocol.dart'; diff --git a/dart/lib/src/transport/rate_limiter.dart b/dart/lib/src/transport/rate_limiter.dart index cbc4f3893b..fa0f7a9018 100644 --- a/dart/lib/src/transport/rate_limiter.dart +++ b/dart/lib/src/transport/rate_limiter.dart @@ -1,10 +1,5 @@ -import 'dart:convert'; - import '../../sentry.dart'; import '../transport/rate_limit_parser.dart'; -import '../sentry_options.dart'; -import '../sentry_envelope.dart'; -import '../sentry_envelope_item.dart'; import 'rate_limit.dart'; import 'data_category.dart'; import '../client_reports/discard_reason.dart'; diff --git a/dart/test/protocol/rate_limiter_test.dart b/dart/test/protocol/rate_limiter_test.dart index 35c266d86b..b4364bceff 100644 --- a/dart/test/protocol/rate_limiter_test.dart +++ b/dart/test/protocol/rate_limiter_test.dart @@ -1,7 +1,6 @@ import 'package:collection/collection.dart'; import 'package:sentry/sentry.dart'; import 'package:sentry/src/client_reports/discard_reason.dart'; -import 'package:sentry/src/client_reports/discarded_event.dart'; import 'package:sentry/src/transport/data_category.dart'; import 'package:test/test.dart'; @@ -11,7 +10,6 @@ import 'package:sentry/src/sentry_envelope_header.dart'; import '../mocks/mock_client_report_recorder.dart'; import '../mocks/mock_hub.dart'; -import 'breadcrumb_test.dart'; void main() { var fixture = Fixture(); From 077c21b181192a4d90329373ccf8347bf7118c1c Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Wed, 10 Jul 2024 09:51:09 +0200 Subject: [PATCH 08/15] Fix test --- dart/test/transport/http_transport_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dart/test/transport/http_transport_test.dart b/dart/test/transport/http_transport_test.dart index b3618393d3..a625603546 100644 --- a/dart/test/transport/http_transport_test.dart +++ b/dart/test/transport/http_transport_test.dart @@ -260,8 +260,8 @@ void main() { ); await sut.send(envelope); - expect(fixture.clientReportRecorder.discardedEvents.first.reason, null); - expect(fixture.clientReportRecorder.discardedEvents.first.category, null); + expect(fixture.clientReportRecorder.discardedEvents.isEmpty, isTrue); + expect(fixture.clientReportRecorder.discardedEvents.isEmpty, isTrue); }); test('does record lost event for error >= 500', () async { From d275793200abb50bf8d07fd2e2cb84e72b06bca9 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Wed, 10 Jul 2024 09:57:57 +0200 Subject: [PATCH 09/15] Improve comments --- dart/test/sentry_client_test.dart | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dart/test/sentry_client_test.dart b/dart/test/sentry_client_test.dart index 26fceaea42..fe63657255 100644 --- a/dart/test/sentry_client_test.dart +++ b/dart/test/sentry_client_test.dart @@ -1462,11 +1462,8 @@ void main() { await sut.captureTransaction(transaction); - // 1 for the transaction and 1 for the spans expect(fixture.recorder.discardedEvents.length, 2); - // we dropped the whole tracer and it has 3 span children so the span count should be 4 - // 3 children + 1 root span final spanCount = fixture.recorder.discardedEvents .firstWhere((element) => element.category == DataCategory.span && @@ -1475,8 +1472,7 @@ void main() { expect(spanCount, 4); }); - test( - 'transaction dropped partial spans by beforeSendTransaction is recorded', + test('partially dropped spans by beforeSendTransaction is recorded', () async { final sut = fixture.getSut(); final transaction = SentryTransaction(fixture.tracer); From 783e595c840c1e742065385978839aacf3b46081 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Wed, 10 Jul 2024 10:05:50 +0200 Subject: [PATCH 10/15] improvements --- dart/test/sentry_client_test.dart | 5 +++-- dart/test/transport/http_transport_test.dart | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dart/test/sentry_client_test.dart b/dart/test/sentry_client_test.dart index fe63657255..adb242e710 100644 --- a/dart/test/sentry_client_test.dart +++ b/dart/test/sentry_client_test.dart @@ -1446,7 +1446,8 @@ void main() { fixture.recorder.discardedEvents.first.category, DataCategory.error); }); - test('transaction dropped by beforeSendTransaction is recorded', () async { + test('beforeSendTransaction correctly records dropped transaction', + () async { final sut = fixture.getSut(); final transaction = SentryTransaction(fixture.tracer); fixture.tracer.startChild('child1'); @@ -1472,7 +1473,7 @@ void main() { expect(spanCount, 4); }); - test('partially dropped spans by beforeSendTransaction is recorded', + test('beforeSendTransaction correctly records partially dropped spans', () async { final sut = fixture.getSut(); final transaction = SentryTransaction(fixture.tracer); diff --git a/dart/test/transport/http_transport_test.dart b/dart/test/transport/http_transport_test.dart index a625603546..90065d89d3 100644 --- a/dart/test/transport/http_transport_test.dart +++ b/dart/test/transport/http_transport_test.dart @@ -261,7 +261,6 @@ void main() { await sut.send(envelope); expect(fixture.clientReportRecorder.discardedEvents.isEmpty, isTrue); - expect(fixture.clientReportRecorder.discardedEvents.isEmpty, isTrue); }); test('does record lost event for error >= 500', () async { From 701e56f1e127160605f7084d4a7f60bf10e039ed Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Wed, 10 Jul 2024 20:21:14 +0200 Subject: [PATCH 11/15] Apply same logic of beforeSend to event processor --- dart/lib/src/sentry_client.dart | 23 +++++++++++++++-- dart/test/mocks.dart | 19 ++++++++++++++ dart/test/sentry_client_test.dart | 42 ++++++++++++++++++++++++++++++- 3 files changed, 81 insertions(+), 3 deletions(-) diff --git a/dart/lib/src/sentry_client.dart b/dart/lib/src/sentry_client.dart index ccd841b995..566b86ec4f 100644 --- a/dart/lib/src/sentry_client.dart +++ b/dart/lib/src/sentry_client.dart @@ -475,6 +475,9 @@ class SentryClient { required List eventProcessors, }) async { SentryEvent? processedEvent = event; + int spanCountBeforeEventProcessors = + event is SentryTransaction ? event.spans.length : 0; + for (final processor in eventProcessors) { try { final e = processor.apply(processedEvent!, hint); @@ -496,9 +499,25 @@ class SentryClient { } if (processedEvent == null) { _options.recorder - .recordLostEvent(DiscardReason.eventProcessor, _getCategory(event)); + .recordLostEvent(DiscardReason.beforeSend, _getCategory(event)); + if (event is SentryTransaction) { + // We dropped the whole transaction, the dropped count includes all child spans + 1 root span + _options.recorder.recordLostEvent( + DiscardReason.beforeSend, DataCategory.span, + count: spanCountBeforeEventProcessors + 1); + } _options.logger(SentryLevel.debug, 'Event was dropped by a processor'); - break; + } else if (event is SentryTransaction && + processedEvent is SentryTransaction) { + // If beforeSend removed only some spans we still report them as dropped + final spanCountAfterEventProcessors = processedEvent.spans.length; + final droppedSpanCount = + spanCountBeforeEventProcessors - spanCountAfterEventProcessors; + if (droppedSpanCount > 0) { + _options.recorder.recordLostEvent( + DiscardReason.beforeSend, DataCategory.span, + count: droppedSpanCount); + } } } return processedEvent; diff --git a/dart/test/mocks.dart b/dart/test/mocks.dart index 7c960c8a07..70d0671106 100644 --- a/dart/test/mocks.dart +++ b/dart/test/mocks.dart @@ -137,6 +137,25 @@ class DropAllEventProcessor implements EventProcessor { } } +class DropNumberOfSpans implements EventProcessor { + DropNumberOfSpans(this.numberOfSpansToDrop); + + final int numberOfSpansToDrop; + + @override + SentryEvent? apply(SentryEvent event, Hint hint) { + if (event is SentryTransaction) { + if (numberOfSpansToDrop > event.spans.length) { + throw ArgumentError( + 'numberOfSpansToDrop must be less than the number of spans in the transaction'); + } + final droppedSpans = event.spans.take(numberOfSpansToDrop).toList(); + event.spans.removeWhere((element) => droppedSpans.contains(element)); + } + return event; + } +} + class FunctionEventProcessor implements EventProcessor { FunctionEventProcessor(this.applyFunction); diff --git a/dart/test/sentry_client_test.dart b/dart/test/sentry_client_test.dart index adb242e710..0a5645f570 100644 --- a/dart/test/sentry_client_test.dart +++ b/dart/test/sentry_client_test.dart @@ -1446,7 +1446,47 @@ void main() { fixture.recorder.discardedEvents.first.category, DataCategory.error); }); - test('beforeSendTransaction correctly records dropped transaction', + test('record event processor dropping transaction', () async { + final sut = fixture.getSut(eventProcessor: DropAllEventProcessor()); + final transaction = SentryTransaction(fixture.tracer); + fixture.tracer.startChild('child1'); + fixture.tracer.startChild('child2'); + fixture.tracer.startChild('child3'); + + await sut.captureTransaction(transaction); + + expect(fixture.recorder.discardedEvents.length, 2); + + final spanCount = fixture.recorder.discardedEvents + .firstWhere((element) => + element.category == DataCategory.span && + element.reason == DiscardReason.beforeSend) + .quantity; + expect(spanCount, 4); + }); + + test('record event processor dropping partially spans', () async { + final numberOfSpansDropped = 2; + final sut = fixture.getSut( + eventProcessor: DropNumberOfSpans(numberOfSpansDropped)); + final transaction = SentryTransaction(fixture.tracer); + fixture.tracer.startChild('child1'); + fixture.tracer.startChild('child2'); + fixture.tracer.startChild('child3'); + + await sut.captureTransaction(transaction); + + expect(fixture.recorder.discardedEvents.length, 1); + + final spanCount = fixture.recorder.discardedEvents + .firstWhere((element) => + element.category == DataCategory.span && + element.reason == DiscardReason.beforeSend) + .quantity; + expect(spanCount, numberOfSpansDropped); + }); + + test('beforeSendTransaction correctly records partially dropped spans', () async { final sut = fixture.getSut(); final transaction = SentryTransaction(fixture.tracer); From 4a4d2df14bd63be0e0319c2f15cf1bf31da2a406 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Wed, 10 Jul 2024 20:26:44 +0200 Subject: [PATCH 12/15] Fix test --- dart/lib/src/sentry_client.dart | 21 +++++++++------------ dart/test/sentry_client_test.dart | 4 ++-- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/dart/lib/src/sentry_client.dart b/dart/lib/src/sentry_client.dart index 566b86ec4f..aa210aa1d0 100644 --- a/dart/lib/src/sentry_client.dart +++ b/dart/lib/src/sentry_client.dart @@ -441,13 +441,12 @@ class SentryClient { } } + final discardReason = DiscardReason.beforeSend; if (processedEvent == null) { - _options.recorder - .recordLostEvent(DiscardReason.beforeSend, _getCategory(event)); + _options.recorder.recordLostEvent(discardReason, _getCategory(event)); if (event is SentryTransaction) { // We dropped the whole transaction, the dropped count includes all child spans + 1 root span - _options.recorder.recordLostEvent( - DiscardReason.beforeSend, DataCategory.span, + _options.recorder.recordLostEvent(discardReason, DataCategory.span, count: spanCountBeforeCallback + 1); } _options.logger( @@ -460,8 +459,7 @@ class SentryClient { final spanCountAfterCallback = processedEvent.spans.length; final droppedSpanCount = spanCountBeforeCallback - spanCountAfterCallback; if (droppedSpanCount > 0) { - _options.recorder.recordLostEvent( - DiscardReason.beforeSend, DataCategory.span, + _options.recorder.recordLostEvent(discardReason, DataCategory.span, count: droppedSpanCount); } } @@ -497,13 +495,13 @@ class SentryClient { rethrow; } } + + final discardReason = DiscardReason.eventProcessor; if (processedEvent == null) { - _options.recorder - .recordLostEvent(DiscardReason.beforeSend, _getCategory(event)); + _options.recorder.recordLostEvent(discardReason, _getCategory(event)); if (event is SentryTransaction) { // We dropped the whole transaction, the dropped count includes all child spans + 1 root span - _options.recorder.recordLostEvent( - DiscardReason.beforeSend, DataCategory.span, + _options.recorder.recordLostEvent(discardReason, DataCategory.span, count: spanCountBeforeEventProcessors + 1); } _options.logger(SentryLevel.debug, 'Event was dropped by a processor'); @@ -514,8 +512,7 @@ class SentryClient { final droppedSpanCount = spanCountBeforeEventProcessors - spanCountAfterEventProcessors; if (droppedSpanCount > 0) { - _options.recorder.recordLostEvent( - DiscardReason.beforeSend, DataCategory.span, + _options.recorder.recordLostEvent(discardReason, DataCategory.span, count: droppedSpanCount); } } diff --git a/dart/test/sentry_client_test.dart b/dart/test/sentry_client_test.dart index 0a5645f570..3ecc7569d8 100644 --- a/dart/test/sentry_client_test.dart +++ b/dart/test/sentry_client_test.dart @@ -1460,7 +1460,7 @@ void main() { final spanCount = fixture.recorder.discardedEvents .firstWhere((element) => element.category == DataCategory.span && - element.reason == DiscardReason.beforeSend) + element.reason == DiscardReason.eventProcessor) .quantity; expect(spanCount, 4); }); @@ -1481,7 +1481,7 @@ void main() { final spanCount = fixture.recorder.discardedEvents .firstWhere((element) => element.category == DataCategory.span && - element.reason == DiscardReason.beforeSend) + element.reason == DiscardReason.eventProcessor) .quantity; expect(spanCount, numberOfSpansDropped); }); From 8364dac7f28f23970a80e8a00cd2ef5780f887e8 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Wed, 10 Jul 2024 20:29:05 +0200 Subject: [PATCH 13/15] Formatting --- dart/lib/src/sentry_client.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/dart/lib/src/sentry_client.dart b/dart/lib/src/sentry_client.dart index aa210aa1d0..f000b6c46d 100644 --- a/dart/lib/src/sentry_client.dart +++ b/dart/lib/src/sentry_client.dart @@ -517,6 +517,7 @@ class SentryClient { } } } + return processedEvent; } From fddfed4698e67bd8fa1a204e591dc88f7cf99e97 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Wed, 10 Jul 2024 20:29:20 +0200 Subject: [PATCH 14/15] Comments --- dart/lib/src/sentry_client.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dart/lib/src/sentry_client.dart b/dart/lib/src/sentry_client.dart index f000b6c46d..57c1bd9326 100644 --- a/dart/lib/src/sentry_client.dart +++ b/dart/lib/src/sentry_client.dart @@ -507,7 +507,7 @@ class SentryClient { _options.logger(SentryLevel.debug, 'Event was dropped by a processor'); } else if (event is SentryTransaction && processedEvent is SentryTransaction) { - // If beforeSend removed only some spans we still report them as dropped + // If event processor removed only some spans we still report them as dropped final spanCountAfterEventProcessors = processedEvent.spans.length; final droppedSpanCount = spanCountBeforeEventProcessors - spanCountAfterEventProcessors; From 03a297de2d4bffeaf9a8dd800e6c4a42e773f6e7 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Wed, 10 Jul 2024 20:31:18 +0200 Subject: [PATCH 15/15] Rename mock --- dart/test/mocks.dart | 4 ++-- dart/test/sentry_client_test.dart | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dart/test/mocks.dart b/dart/test/mocks.dart index 70d0671106..b05843be8e 100644 --- a/dart/test/mocks.dart +++ b/dart/test/mocks.dart @@ -137,8 +137,8 @@ class DropAllEventProcessor implements EventProcessor { } } -class DropNumberOfSpans implements EventProcessor { - DropNumberOfSpans(this.numberOfSpansToDrop); +class DropSpansEventProcessor implements EventProcessor { + DropSpansEventProcessor(this.numberOfSpansToDrop); final int numberOfSpansToDrop; diff --git a/dart/test/sentry_client_test.dart b/dart/test/sentry_client_test.dart index 3ecc7569d8..92b6792fdf 100644 --- a/dart/test/sentry_client_test.dart +++ b/dart/test/sentry_client_test.dart @@ -1468,7 +1468,7 @@ void main() { test('record event processor dropping partially spans', () async { final numberOfSpansDropped = 2; final sut = fixture.getSut( - eventProcessor: DropNumberOfSpans(numberOfSpansDropped)); + eventProcessor: DropSpansEventProcessor(numberOfSpansDropped)); final transaction = SentryTransaction(fixture.tracer); fixture.tracer.startChild('child1'); fixture.tracer.startChild('child2');