Skip to content

Commit

Permalink
Send dropped event as well for rate limit and network error
Browse files Browse the repository at this point in the history
  • Loading branch information
buenaflor committed Jul 10, 2024
1 parent dccede3 commit 1e0eafe
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 34 deletions.
34 changes: 22 additions & 12 deletions dart/lib/src/sentry_envelope_item.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'dart:async';
import 'dart:convert';

import 'package:meta/meta.dart';

Check warning on line 4 in dart/lib/src/sentry_envelope_item.dart

View workflow job for this annotation

GitHub Actions / analyze / analyze

Unused import: 'package:meta/meta.dart'.

Try removing the import directive. See https://dart.dev/diagnostics/unused_import to learn more about this problem.

import 'client_reports/client_report.dart';
import 'metrics/metric.dart';
import 'protocol.dart';
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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].
Expand All @@ -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.
Expand All @@ -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.
Expand All @@ -80,6 +88,7 @@ class SentryEnvelopeItem {
contentType: 'application/json',
),
cachedItem.getData,
originalObject: clientReport,
);
}

Expand All @@ -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.
Expand Down
21 changes: 20 additions & 1 deletion dart/lib/src/transport/data_category.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
35 changes: 14 additions & 21 deletions dart/lib/src/transport/rate_limiter.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import 'dart:convert';

Check warning on line 1 in dart/lib/src/transport/rate_limiter.dart

View workflow job for this annotation

GitHub Actions / analyze / analyze

Unused import: 'dart:convert'.

Try removing the import directive. See https://dart.dev/diagnostics/unused_import to learn more about this problem.

import '../../sentry.dart';
import '../transport/rate_limit_parser.dart';
import '../sentry_options.dart';

Check notice on line 5 in dart/lib/src/transport/rate_limiter.dart

View workflow job for this annotation

GitHub Actions / analyze / analyze

The import of '../sentry_options.dart' is unnecessary because all of the used elements are also provided by the import of '../../sentry.dart'.

Try removing the import directive. See https://dart.dev/diagnostics/unnecessary_import to learn more about this problem.
import '../sentry_envelope.dart';

Check notice on line 6 in dart/lib/src/transport/rate_limiter.dart

View workflow job for this annotation

GitHub Actions / analyze / analyze

The import of '../sentry_envelope.dart' is unnecessary because all of the used elements are also provided by the import of '../../sentry.dart'.

Try removing the import directive. See https://dart.dev/diagnostics/unnecessary_import to learn more about this problem.
Expand Down Expand Up @@ -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,
);
}
}
}

Expand Down Expand Up @@ -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);

Expand All @@ -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];

Expand Down
15 changes: 15 additions & 0 deletions dart/lib/src/utils/transport_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit 1e0eafe

Please sign in to comment.