Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- new Dart code file structure #96
- Base the sdk name on the platform (`sentry.dart` for io & flutter, `sentry.dart.browser` in a browser context) #103
- Single changelog and readme for both packages #105
- new static API : Sentry.init(), Sentry.captureEvent() #108
- expect a sdkName based on the test platform #105

# `package:sentry` changelog
Expand Down
73 changes: 73 additions & 0 deletions dart/example/event_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import 'package:sentry/src/protocol.dart';

final event = Event(
loggerName: 'main',
serverName: 'server.dart',
release: '1.4.0-preview.1',
environment: 'Test',
message: Message(formatted: 'This is an example Dart event.'),
transaction: '/example/app',
level: SeverityLevel.warning,
tags: const <String, String>{'project-id': '7371'},
extra: const <String, String>{'company-name': 'Dart Inc'},
fingerprint: const <String>['example-dart'],
userContext: const User(
id: '800',
username: 'first-user',
email: '[email protected]',
ipAddress: '127.0.0.1',
extras: <String, String>{'first-sign-in': '2020-01-01'}),
breadcrumbs: [
Breadcrumb('UI Lifecycle', DateTime.now().toUtc(),
category: 'ui.lifecycle',
type: 'navigation',
data: {'screen': 'MainActivity', 'state': 'created'},
level: SeverityLevel.info)
],
contexts: Contexts(
operatingSystem: const OperatingSystem(
name: 'Android',
version: '5.0.2',
build: 'LRX22G.P900XXS0BPL2',
kernelVersion:
'Linux version 3.4.39-5726670 (dpi@SWHC3807) (gcc version 4.8 (GCC) ) #1 SMP PREEMPT Thu Dec 1 19:42:39 KST 2016',
rooted: false),
runtimes: [const Runtime(name: 'ART', version: '5')],
app: App(
name: 'Example Dart App',
version: '1.42.0',
identifier: 'HGT-App-13',
build: '93785',
buildType: 'release',
deviceAppHash: '5afd3a6',
startTime: DateTime.now().toUtc()),
browser: const Browser(name: 'Firefox', version: '42.0.1'),
device: Device(
name: 'SM-P900',
family: 'SM-P900',
model: 'SM-P900 (LRX22G)',
modelId: 'LRX22G',
arch: 'armeabi-v7a',
batteryLevel: 99,
orientation: Orientation.landscape,
manufacturer: 'samsung',
brand: 'samsung',
screenResolution: '2560x1600',
screenDensity: 2.1,
screenDpi: 320,
online: true,
charging: true,
lowMemory: true,
simulator: false,
memorySize: 1500,
freeMemory: 200,
usableMemory: 4294967296,
storageSize: 4294967296,
freeStorage: 2147483648,
externalStorageSize: 8589934592,
externalFreeStorage: 2863311530,
bootTime: DateTime.now().toUtc(),
timezone: 'America/Toronto',
),
),
);
101 changes: 16 additions & 85 deletions dart/example/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import 'dart:io';

import 'package:sentry/sentry.dart';

import 'event_example.dart';

/// Sends a test exception report to Sentry.io using this Dart client.
Future<void> main(List<String> rawArgs) async {
if (rawArgs.length != 1) {
Expand All @@ -16,18 +18,26 @@ Future<void> main(List<String> rawArgs) async {
}

final dsn = rawArgs.single;
final client = SentryClient(dsn: dsn);
Sentry.init((options) => options.dsn = dsn);

print('\nReporting a complete event example: ');

// Sends a full Sentry event payload to show the different parts of the UI.
await captureCompleteExampleEvent(client);
final response = await Sentry.captureEvent(event);

if (response.isSuccessful) {
print('SUCCESS\nid: ${response.eventId}');
} else {
print('FAILURE: ${response.error}');
}

try {
await foo();
} catch (error, stackTrace) {
print('\nReporting the following stack trace: ');
print(stackTrace);
final response = await client.captureException(
exception: error,
final response = await Sentry.captureException(
error,
stackTrace: stackTrace,
);

Expand All @@ -37,89 +47,10 @@ Future<void> main(List<String> rawArgs) async {
print('FAILURE: ${response.error}');
}
} finally {
await client.close();
await Sentry.close();
}
}

Future<void> captureCompleteExampleEvent(SentryClient client) async {
final event = Event(
loggerName: 'main',
serverName: 'server.dart',
release: '1.4.0-preview.1',
environment: 'Test',
message: Message(formatted: 'This is an example Dart event.'),
transaction: '/example/app',
level: SeverityLevel.warning,
tags: const <String, String>{'project-id': '7371'},
extra: const <String, String>{'company-name': 'Dart Inc'},
fingerprint: const <String>['example-dart'],
userContext: const User(
id: '800',
username: 'first-user',
email: '[email protected]',
ipAddress: '127.0.0.1',
extras: <String, String>{'first-sign-in': '2020-01-01'}),
breadcrumbs: [
Breadcrumb('UI Lifecycle', DateTime.now().toUtc(),
category: 'ui.lifecycle',
type: 'navigation',
data: {'screen': 'MainActivity', 'state': 'created'},
level: SeverityLevel.info)
],
contexts: Contexts(
operatingSystem: const OperatingSystem(
name: 'Android',
version: '5.0.2',
build: 'LRX22G.P900XXS0BPL2',
kernelVersion:
'Linux version 3.4.39-5726670 (dpi@SWHC3807) (gcc version 4.8 (GCC) ) #1 SMP PREEMPT Thu Dec 1 19:42:39 KST 2016',
rooted: false),
runtimes: [const Runtime(name: 'ART', version: '5')],
app: App(
name: 'Example Dart App',
version: '1.42.0',
identifier: 'HGT-App-13',
build: '93785',
buildType: 'release',
deviceAppHash: '5afd3a6',
startTime: DateTime.now().toUtc()),
browser: const Browser(name: 'Firefox', version: '42.0.1'),
device: Device(
name: 'SM-P900',
family: 'SM-P900',
model: 'SM-P900 (LRX22G)',
modelId: 'LRX22G',
arch: 'armeabi-v7a',
batteryLevel: 99,
orientation: Orientation.landscape,
manufacturer: 'samsung',
brand: 'samsung',
screenResolution: '2560x1600',
screenDensity: 2.1,
screenDpi: 320,
online: true,
charging: true,
lowMemory: true,
simulator: false,
memorySize: 1500,
freeMemory: 200,
usableMemory: 4294967296,
storageSize: 4294967296,
freeStorage: 2147483648,
externalStorageSize: 8589934592,
externalFreeStorage: 2863311530,
bootTime: DateTime.now().toUtc(),
timezone: 'America/Toronto',
)));

final response = await client.captureEvent(event: event);

print('\nReporting a complete event example: ');
if (response.isSuccessful) {
print('SUCCESS\nid: ${response.eventId}');
} else {
print('FAILURE: ${response.error}');
}
/* TODO(rxlabz) Sentry CaptureMessage(message, level) */
}

Future<void> foo() async {
Expand Down
2 changes: 2 additions & 0 deletions dart/lib/sentry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
/// A pure Dart client for Sentry.io crash reporting.
export 'src/client.dart';
export 'src/protocol.dart';
export 'src/sentry.dart';
export 'src/sentry_options.dart';
export 'src/version.dart';
54 changes: 54 additions & 0 deletions dart/lib/src/sentry.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import 'dart:async';

import 'package:meta/meta.dart';

import 'client.dart';
import 'protocol.dart';
import 'sentry_options.dart';

/// Configuration options callback
typedef OptionsConfiguration = void Function(SentryOptions);

/// Sentry SDK main entry point
///
class Sentry {
static SentryClient _client;

Sentry._();

static void init(OptionsConfiguration optionsConfiguration) {
final options = SentryOptions();
optionsConfiguration(options);
_client = SentryClient(
dsn: options.dsn,
environmentAttributes: options.environmentAttributes,
compressPayload: options.compressPayload,
httpClient: options.httpClient,
clock: options.clock,
uuidGenerator: options.uuidGenerator,
);
}

/// Reports an [event] to Sentry.io.
static Future<SentryResponse> captureEvent(Event event) async {
return _client.captureEvent(event: event);
}

/// Reports the [exception] and optionally its [stackTrace] to Sentry.io.
static Future<SentryResponse> captureException(
dynamic error, {
dynamic stackTrace,
}) async {
return _client.captureException(
exception: error,
stackTrace: stackTrace,
);
}

/// Close the client SDK
static Future<void> close() async => _client.close();

/// client injector only use for testing
@visibleForTesting
static void initClient(SentryClient client) => _client = client;
}
53 changes: 53 additions & 0 deletions dart/lib/src/sentry_options.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import 'package:http/http.dart';

import 'protocol.dart';
import 'utils.dart';

/// Sentry SDK options
class SentryOptions {
/// Default Log level if not specified Default is DEBUG
static final SeverityLevel defaultDiagnosticLevel = SeverityLevel.debug;

/// The DSN tells the SDK where to send the events to. If this value is not provided, the SDK will
/// just not send any events.
String dsn;

/// Contains [Event] attributes that are automatically mixed into all events
/// captured through this client.
///
/// This event is designed to contain static values that do not change from
/// event to event, such as local operating system version, the version of
/// Dart/Flutter SDK, etc. These attributes have lower precedence than those
/// supplied in the even passed to [capture].
Event environmentAttributes;

/// If [compressPayload] is `true` the outgoing HTTP payloads are compressed
/// using gzip. Otherwise, the payloads are sent in plain UTF8-encoded JSON
/// text. If not specified, the compression is enabled by default.
bool compressPayload;

/// If [httpClient] is provided, it is used instead of the default client to
/// make HTTP calls to Sentry.io. This is useful in tests.
Client httpClient;

/// If [clock] is provided, it is used to get time instead of the system
/// clock. This is useful in tests. Should be an implementation of [ClockProvider].
/// This parameter is dynamic to maintain backwards compatibility with
/// previous use of [Clock](https://pub.dartlang.org/documentation/quiver/latest/quiver.time/Clock-class.html)
/// from [`package:quiver`](https://pub.dartlang.org/packages/quiver).
dynamic clock;

/// If [uuidGenerator] is provided, it is used to generate the "event_id"
/// field instead of the built-in random UUID v4 generator. This is useful in
/// tests.
UuidGenerator uuidGenerator;

SentryOptions({
this.dsn,
this.environmentAttributes,
this.compressPayload,
this.httpClient,
this.clock,
this.uuidGenerator,
});
}
Loading