Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions lib/sentry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ class Event {
this.release,
this.environment,
this.message,
this.transaction,
this.exception,
this.stackTrace,
this.level,
Expand All @@ -314,6 +315,7 @@ class Event {
this.extra,
this.fingerprint,
this.userContext,
this.breadcrumbs,
});

/// The logger that logged the event.
Expand Down Expand Up @@ -344,6 +346,10 @@ class Event {
/// Can be `null`, a [String], or a [StackTrace].
final dynamic stackTrace;

/// The name of the transaction which generated this event,
/// for example, the route name: `"/users/<username>/"`.
final String transaction;

/// How important this event is.
final SeverityLevel level;

Expand All @@ -359,6 +365,12 @@ class Event {
/// they must be JSON-serializable.
final Map<String, dynamic> extra;

/// List of breadcrumbs for this event.
///
/// See also:
/// * https://docs.sentry.io/enriching-error-data/breadcrumbs/?platform=javascript
final List<Breadcrumb> breadcrumbs;

/// Information about the current user.
///
/// The value in this field overrides the user context
Expand Down Expand Up @@ -401,6 +413,8 @@ class Event {

if (message != null) json['message'] = message;

if (transaction != null) json['transaction'] = transaction;

if (exception != null) {
json['exception'] = [
<String, dynamic>{
Expand Down Expand Up @@ -433,6 +447,12 @@ class Event {
if (fingerprint != null && fingerprint.isNotEmpty)
json['fingerprint'] = fingerprint;

if (breadcrumbs != null && breadcrumbs.isNotEmpty) {
json['breadcrumbs'] = <String, List<Map<String, dynamic>>>{
'values': breadcrumbs.map((b) => b.toJson()).toList(growable: false)
};
}

return json;
}
}
Expand Down Expand Up @@ -494,3 +514,64 @@ class User {
};
}
}

/// Structed data to describe more information pior to the event [captured][SentryClient.capture].
///
/// The outgoing JSON representation is:
///
/// ```
/// {
/// "timestamp": 1000
/// "message": "message",
/// "category": "category",
/// "data": {"key": "value"},
/// "level": "info",
/// "type": "default"
/// }
/// ```
/// See also:
/// * https://docs.sentry.io/development/sdk-dev/event-payloads/breadcrumbs/
class Breadcrumb {
final String message;
final String category;
final Map<String, String> data;
final SeverityLevel level;

/// Describes what type of breadcrumb this is.
///
/// Possible values: "default", "http", "navigation".
///
/// See also:
///
/// * https://docs.sentry.io/development/sdk-dev/event-payloads/breadcrumbs/#breadcrumb-types
final String type;

/// The time the breadcrumb was recorded.
///
/// The value is submitted to Sentry with second precision.
final DateTime timestamp;
const Breadcrumb(this.message, this.timestamp,
{this.category, this.data, this.level = SeverityLevel.info, this.type});

Map<String, dynamic> toJson() {
var json = <String, dynamic>{
'timestamp': formatDateAsIso8601WithSecondPrecision(timestamp),
};
if (message != null) {
json['message'] = message;
}
if (category != null) {
json['category'] = category;
}
if (data != null && data.isNotEmpty) {
json['data'] = Map.of(data);
}
if (level != null) {
json['level'] = level.name;
}
if (type != null) {
json['type'] = type;
}
return json;
}
}
35 changes: 35 additions & 0 deletions test/sentry_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -308,16 +308,39 @@ void main() {
});

group('$Event', () {
test('$Breadcrumb serializes', () {
expect(
Breadcrumb(
"example log",
DateTime.utc(2019),
level: SeverityLevel.debug,
category: "test",
).toJson(),
<String, dynamic>{
'timestamp': '2019-01-01T00:00:00',
'message': 'example log',
'category': 'test',
'level': 'debug',
},
);
});
test('serializes to JSON', () {
final user = new User(
id: "user_id",
username: "username",
email: "[email protected]",
ipAddress: "127.0.0.1",
extras: {"foo": "bar"});

final breadcrumbs = [
Breadcrumb("test log", DateTime.utc(2019),
level: SeverityLevel.debug, category: "test"),
];

expect(
new Event(
message: 'test-message',
transaction: '/test/1',
exception: new StateError('test-error'),
level: SeverityLevel.debug,
culprit: 'Professor Moriarty',
Expand All @@ -331,11 +354,13 @@ void main() {
},
fingerprint: <String>[Event.defaultFingerprint, 'foo'],
userContext: user,
breadcrumbs: breadcrumbs,
).toJson(),
<String, dynamic>{
'platform': 'dart',
'sdk': {'version': sdkVersion, 'name': 'dart'},
'message': 'test-message',
'transaction': '/test/1',
'exception': [
{'type': 'StateError', 'value': 'Bad state: test-error'}
],
Expand All @@ -351,6 +376,16 @@ void main() {
'ip_address': '127.0.0.1',
'extras': {'foo': 'bar'}
},
'breadcrumbs': {
'values': [
{
'timestamp': '2019-01-01T00:00:00',
'message': 'test log',
'category': 'test',
'level': 'debug',
},
]
},
},
);
});
Expand Down