From 2c31057f2e2485c2bf08377c6cdc1905d5d357df Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Sun, 25 Oct 2020 18:11:08 +0100 Subject: [PATCH 1/2] feat: add breadcrumb --- dart/example/event_example.dart | 4 +- dart/lib/src/hub.dart | 25 ++++++++++++ dart/lib/src/noop_hub.dart | 5 +++ dart/lib/src/protocol/breadcrumb.dart | 6 +-- dart/lib/src/sentry.dart | 5 +++ dart/test/event_test.dart | 11 ++++-- dart/test/hub_test.dart | 11 ++++++ dart/test/mocks.dart | 4 +- dart/test/scope_test.dart | 55 +++++++++++++++++++++------ 9 files changed, 106 insertions(+), 20 deletions(-) diff --git a/dart/example/event_example.dart b/dart/example/event_example.dart index a02c92a9b3..8848782ed3 100644 --- a/dart/example/event_example.dart +++ b/dart/example/event_example.dart @@ -18,7 +18,9 @@ final event = SentryEvent( ipAddress: '127.0.0.1', extras: {'first-sign-in': '2020-01-01'}), breadcrumbs: [ - Breadcrumb('UI Lifecycle', DateTime.now().toUtc(), + Breadcrumb( + message: 'UI Lifecycle', + timestamp: DateTime.now().toUtc(), category: 'ui.lifecycle', type: 'navigation', data: {'screen': 'MainActivity', 'state': 'created'}, diff --git a/dart/lib/src/hub.dart b/dart/lib/src/hub.dart index 2244149fe3..ee6b5cf440 100644 --- a/dart/lib/src/hub.dart +++ b/dart/lib/src/hub.dart @@ -191,6 +191,31 @@ class Hub { return sentryId; } + /// Adds a breacrumb to the current Scope + void addBreadcrumb(Breadcrumb crumb, {dynamic hint}) { + if (!_isEnabled) { + _options.logger( + SentryLevel.warning, + "Instance is disabled and this 'addBreadcrumb' call is a no-op.", + ); + } else if (crumb == null) { + _options.logger( + SentryLevel.warning, + 'addBreadcrumb called with null parameter.', + ); + } else { + final item = _peek(); + if (item != null) { + item.scope.addBreadcrumb(crumb, hint: hint); + } else { + _options.logger( + SentryLevel.fatal, + 'Stack peek was null when addBreadcrumb', + ); + } + } + } + /// Binds a different client to the hub void bindClient(SentryClient client) { if (!_isEnabled) { diff --git a/dart/lib/src/noop_hub.dart b/dart/lib/src/noop_hub.dart index f8e528430e..3a79f71211 100644 --- a/dart/lib/src/noop_hub.dart +++ b/dart/lib/src/noop_hub.dart @@ -1,5 +1,7 @@ import 'dart:async'; +import 'package:sentry/src/protocol/breadcrumb.dart'; + import 'client.dart'; import 'hub.dart'; import 'protocol/sentry_event.dart'; @@ -54,4 +56,7 @@ class NoOpHub implements Hub { @override SentryId get lastEventId => SentryId.empty(); + + @override + void addBreadcrumb(Breadcrumb crumb, {dynamic hint}) {} } diff --git a/dart/lib/src/protocol/breadcrumb.dart b/dart/lib/src/protocol/breadcrumb.dart index a458ba7c69..7769cf33cb 100644 --- a/dart/lib/src/protocol/breadcrumb.dart +++ b/dart/lib/src/protocol/breadcrumb.dart @@ -19,14 +19,14 @@ import 'sentry_level.dart'; /// * https://docs.sentry.io/development/sdk-dev/event-payloads/breadcrumbs/ class Breadcrumb { /// Creates a breadcrumb that can be attached to an [Event]. - const Breadcrumb( + Breadcrumb({ this.message, - this.timestamp, { + DateTime timestamp, this.category, this.data, this.level = SentryLevel.info, this.type, - }) : assert(timestamp != null); + }) : timestamp = timestamp ?? getUtcDateTime(); /// Describes the breadcrumb. /// diff --git a/dart/lib/src/sentry.dart b/dart/lib/src/sentry.dart index 18856f6183..495c9d1db3 100644 --- a/dart/lib/src/sentry.dart +++ b/dart/lib/src/sentry.dart @@ -94,6 +94,11 @@ class Sentry { /// Check if the current Hub is enabled/active. static bool get isEnabled => currentHub.isEnabled; + /// Adds a breacrumb to the current Scope + static void addBreadcrumb(Breadcrumb crumb, {dynamic hint}) { + currentHub.addBreadcrumb(crumb, hint: hint); + } + static bool _setDefaultConfiguration(SentryOptions options) { if (options.dsn == null) { throw ArgumentError.notNull( diff --git a/dart/test/event_test.dart b/dart/test/event_test.dart index 9d4d76c804..e5aa283587 100644 --- a/dart/test/event_test.dart +++ b/dart/test/event_test.dart @@ -12,8 +12,8 @@ void main() { test('$Breadcrumb serializes', () { expect( Breadcrumb( - 'example log', - DateTime.utc(2019), + message: 'example log', + timestamp: DateTime.utc(2019), level: SentryLevel.debug, category: 'test', ).toJson(), @@ -63,8 +63,11 @@ void main() { extras: {'foo': 'bar'}); final breadcrumbs = [ - Breadcrumb('test log', timestamp, - level: SentryLevel.debug, category: 'test'), + Breadcrumb( + message: 'test log', + timestamp: timestamp, + level: SentryLevel.debug, + category: 'test'), ]; final error = StateError('test-error'); diff --git a/dart/test/hub_test.dart b/dart/test/hub_test.dart index 24527b7364..5c164f1d52 100644 --- a/dart/test/hub_test.dart +++ b/dart/test/hub_test.dart @@ -121,6 +121,17 @@ void main() { true, ); }); + + test('should add breadcrumb to current Scope', () { + hub.configureScope((Scope scope) { + expect(0, scope..breadcrumbs.length); + }); + hub.addBreadcrumb(Breadcrumb(message: 'test')); + hub.configureScope((Scope scope) { + expect(1, scope..breadcrumbs.length); + expect('test', scope..breadcrumbs.first.message); + }); + }); }); group('Hub Client', () { diff --git a/dart/test/mocks.dart b/dart/test/mocks.dart index 57ca1da64d..6d50a7ecb9 100644 --- a/dart/test/mocks.dart +++ b/dart/test/mocks.dart @@ -32,7 +32,9 @@ final fakeEvent = SentryEvent( ipAddress: '127.0.0.1', extras: {'first-sign-in': '2020-01-01'}), breadcrumbs: [ - Breadcrumb('UI Lifecycle', DateTime.now().toUtc(), + Breadcrumb( + message: 'UI Lifecycle', + timestamp: DateTime.now().toUtc(), category: 'ui.lifecycle', type: 'navigation', data: {'screen': 'MainActivity', 'state': 'created'}, diff --git a/dart/test/scope_test.dart b/dart/test/scope_test.dart index f539930405..f48152d07d 100644 --- a/dart/test/scope_test.dart +++ b/dart/test/scope_test.dart @@ -42,7 +42,10 @@ void main() { test('adds $Breadcrumb', () { final sut = fixture.getSut(); - final breadcrumb = Breadcrumb('test log', DateTime.utc(2019)); + final breadcrumb = Breadcrumb( + message: 'test log', + timestamp: DateTime.utc(2019), + ); sut.addBreadcrumb(breadcrumb); expect(sut.breadcrumbs.last, breadcrumb); @@ -53,7 +56,10 @@ void main() { beforeBreadcrumbCallback: fixture.beforeBreadcrumbCallback, ); - final breadcrumb = Breadcrumb('test log', DateTime.utc(2019)); + final breadcrumb = Breadcrumb( + message: 'test log', + timestamp: DateTime.utc(2019), + ); sut.addBreadcrumb(breadcrumb); expect(sut.breadcrumbs.length, 0); @@ -71,9 +77,18 @@ void main() { final maxBreadcrumbs = 2; final sut = fixture.getSut(maxBreadcrumbs: maxBreadcrumbs); - final breadcrumb1 = Breadcrumb('test log', DateTime.utc(2019)); - final breadcrumb2 = Breadcrumb('test log', DateTime.utc(2019)); - final breadcrumb3 = Breadcrumb('test log', DateTime.utc(2019)); + final breadcrumb1 = Breadcrumb( + message: 'test log', + timestamp: DateTime.utc(2019), + ); + final breadcrumb2 = Breadcrumb( + message: 'test log', + timestamp: DateTime.utc(2019), + ); + final breadcrumb3 = Breadcrumb( + message: 'test log', + timestamp: DateTime.utc(2019), + ); sut.addBreadcrumb(breadcrumb1); sut.addBreadcrumb(breadcrumb2); sut.addBreadcrumb(breadcrumb3); @@ -84,9 +99,18 @@ void main() { test('rotates $Breadcrumb', () { final sut = fixture.getSut(maxBreadcrumbs: 2); - final breadcrumb1 = Breadcrumb('test log', DateTime.utc(2019)); - final breadcrumb2 = Breadcrumb('test log', DateTime.utc(2019)); - final breadcrumb3 = Breadcrumb('test log', DateTime.utc(2019)); + final breadcrumb1 = Breadcrumb( + message: 'test log', + timestamp: DateTime.utc(2019), + ); + final breadcrumb2 = Breadcrumb( + message: 'test log', + timestamp: DateTime.utc(2019), + ); + final breadcrumb3 = Breadcrumb( + message: 'test log', + timestamp: DateTime.utc(2019), + ); sut.addBreadcrumb(breadcrumb1); sut.addBreadcrumb(breadcrumb2); sut.addBreadcrumb(breadcrumb3); @@ -100,7 +124,10 @@ void main() { final maxBreadcrumbs = 0; final sut = fixture.getSut(maxBreadcrumbs: maxBreadcrumbs); - final breadcrumb1 = Breadcrumb('test log', DateTime.utc(2019)); + final breadcrumb1 = Breadcrumb( + message: 'test log', + timestamp: DateTime.utc(2019), + ); sut.addBreadcrumb(breadcrumb1); expect(sut.breadcrumbs.length, maxBreadcrumbs); @@ -109,7 +136,10 @@ void main() { test('clears $Breadcrumb list', () { final sut = fixture.getSut(); - final breadcrumb1 = Breadcrumb('test log', DateTime.utc(2019)); + final breadcrumb1 = Breadcrumb( + message: 'test log', + timestamp: DateTime.utc(2019), + ); sut.addBreadcrumb(breadcrumb1); sut.clear(); @@ -153,7 +183,10 @@ void main() { test('clears $Scope', () { final sut = fixture.getSut(); - final breadcrumb1 = Breadcrumb('test log', DateTime.utc(2019)); + final breadcrumb1 = Breadcrumb( + message: 'test log', + timestamp: DateTime.utc(2019), + ); sut.addBreadcrumb(breadcrumb1); sut.level = SentryLevel.debug; From f354996353049f1800aa98bbf62e8e341e045c0d Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto Date: Sun, 25 Oct 2020 18:11:38 +0100 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1176fd873..bcf0a567b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ - Ref: added Transport #123 - Feat: apply sample rate - Ref: execute before send callback +- Feat: addBreadcrumb on Static API # `package:sentry` changelog