feat: integrate Sentry Flutter and enable it if SENTRY_DSN is not empty (#5959)

* chore: add dart dependency validator

* feat: integrate sentry flutter

* chore: remove user info collection

* fix: flutter analyze

* fix: ios compile

* chore: add log
This commit is contained in:
Lucas.Xu 2024-08-15 10:00:27 +08:00 committed by GitHub
parent 7eb8ea347d
commit 88cc0caab7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 108 additions and 8 deletions

View File

@ -0,0 +1,12 @@
# dart_dependency_validator.yaml
allow_pins: true
include:
- "lib/**"
exclude:
- "packages/**"
ignore:
- analyzer

View File

@ -69,6 +69,11 @@ PODS:
- SDWebImage (5.14.2):
- SDWebImage/Core (= 5.14.2)
- SDWebImage/Core (5.14.2)
- Sentry/HybridSDK (8.33.0)
- sentry_flutter (8.7.0):
- Flutter
- FlutterMacOS
- Sentry/HybridSDK (= 8.33.0)
- share_plus (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
@ -101,6 +106,7 @@ DEPENDENCIES:
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- printing (from `.symlinks/plugins/printing/ios`)
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite (from `.symlinks/plugins/sqflite/darwin`)
@ -113,6 +119,7 @@ SPEC REPOS:
- DKPhotoGallery
- ReachabilitySwift
- SDWebImage
- Sentry
- SwiftyGif
- Toast
@ -149,6 +156,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/permission_handler_apple/ios"
printing:
:path: ".symlinks/plugins/printing/ios"
sentry_flutter:
:path: ".symlinks/plugins/sentry_flutter/ios"
share_plus:
:path: ".symlinks/plugins/share_plus/ios"
shared_preferences_foundation:
@ -181,6 +190,8 @@ SPEC CHECKSUMS:
printing: 233e1b73bd1f4a05615548e9b5a324c98588640b
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
SDWebImage: b9a731e1d6307f44ca703b3976d18c24ca561e84
Sentry: 8560050221424aef0bebc8e31eedf00af80f90a6
sentry_flutter: e26b861f744e5037a3faf9bf56603ec65d658a61
share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec

View File

@ -36,4 +36,11 @@ abstract class Env {
defaultValue: '',
)
static const String internalBuild = _Env.internalBuild;
@EnviedField(
obfuscate: false,
varName: 'SENTRY_DSN',
defaultValue: '',
)
static const String sentryDsn = _Env.sentryDsn;
}

View File

@ -12,12 +12,12 @@ class UserProfileBloc extends Bloc<UserProfileEvent, UserProfileState> {
UserProfileBloc() : super(const _Initial()) {
on<UserProfileEvent>((event, emit) async {
await event.when(
started: () async => _initalize(emit),
started: () async => _initialize(emit),
);
});
}
Future<void> _initalize(Emitter<UserProfileState> emit) async {
Future<void> _initialize(Emitter<UserProfileState> emit) async {
emit(const UserProfileState.loading());
final workspaceOrFailure =

View File

@ -22,6 +22,7 @@ import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart';
import 'package:sentry/sentry.dart';
class MobileHomeScreen extends StatelessWidget {
const MobileHomeScreen({super.key});
@ -59,6 +60,14 @@ class MobileHomeScreen extends StatelessWidget {
return const WorkspaceFailedScreen();
}
Sentry.configureScope(
(scope) => scope.setUser(
SentryUser(
id: userProfile.id.toString(),
),
),
);
return Scaffold(
body: SafeArea(
bottom: false,

View File

@ -110,6 +110,7 @@ class FlowyRunner {
// this task should be first task, for handling platform errors.
// don't catch errors in test mode
if (!mode.isUnitTest) const PlatformErrorCatcherTask(),
if (!mode.isUnitTest) const InitSentryTask(),
// this task should be second task, for handling memory leak.
// there's a flag named _enable in memory_leak_detector.dart. If it's false, the task will be ignored.
MemoryLeakDetectorTask(),

View File

@ -9,7 +9,8 @@ export 'localization.dart';
export 'memory_leak_detector.dart';
export 'platform_error_catcher.dart';
export 'platform_service.dart';
export 'recent_service_task.dart';
export 'rust_sdk.dart';
export 'sentry.dart';
export 'supabase_task.dart';
export 'windows.dart';
export 'recent_service_task.dart';

View File

@ -0,0 +1,31 @@
import 'package:appflowy/env/env.dart';
import 'package:appflowy_backend/log.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import '../startup.dart';
class InitSentryTask extends LaunchTask {
const InitSentryTask();
@override
Future<void> initialize(LaunchContext context) async {
const dsn = Env.sentryDsn;
if (dsn.isEmpty) {
Log.info('Sentry DSN is not set, skipping initialization');
return;
}
Log.info('Initializing Sentry');
await SentryFlutter.init(
(options) {
options.dsn = dsn;
options.tracesSampleRate = 1.0;
options.profilesSampleRate = 1.0;
},
);
}
@override
Future<void> dispose() async {}
}

View File

@ -26,6 +26,7 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
import 'package:flowy_infra_ui/style_widget/container.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:sentry/sentry.dart';
import 'package:sized_context/sized_context.dart';
import 'package:styled_widget/styled_widget.dart';
@ -55,6 +56,7 @@ class DesktopHomeScreen extends StatelessWidget {
(workspaceSettingPB) => workspaceSettingPB as WorkspaceSettingPB,
(error) => null,
);
final userProfile = snapshots.data?[1].fold(
(userProfilePB) => userProfilePB as UserProfilePB,
(error) => null,
@ -66,6 +68,14 @@ class DesktopHomeScreen extends StatelessWidget {
return const WorkspaceFailedScreen();
}
Sentry.configureScope(
(scope) => scope.setUser(
SentryUser(
id: userProfile.id.toString(),
),
),
);
return AFFocusManager(
child: MultiBlocProvider(
key: ValueKey(userProfile.id),

View File

@ -742,10 +742,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "4.0.0"
flutter_localizations:
dependency: transitive
description: flutter
@ -1215,10 +1215,10 @@ packages:
dependency: transitive
description:
name: lints
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
version: "4.0.0"
loading_indicator:
dependency: transitive
description:
@ -1747,6 +1747,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.3.8"
sentry:
dependency: "direct main"
description:
name: sentry
sha256: "0f787e27ff617e4f88f7074977240406a9c5509444bac64a4dfa5b3200fb5632"
url: "https://pub.dev"
source: hosted
version: "8.7.0"
sentry_flutter:
dependency: "direct main"
description:
name: sentry_flutter
sha256: fbbb47d72ccca48be25bf3c2ced6ab6e872991af3a0ba78e54be8d138f2e053f
url: "https://pub.dev"
source: hosted
version: "8.7.0"
share_plus:
dependency: "direct main"
description:

View File

@ -154,9 +154,11 @@ dependencies:
scroll_to_index: ^3.0.1
extended_text_field: ^15.0.0
extended_text_library: ^12.0.0
sentry_flutter: ^8.7.0
sentry: ^8.7.0
dev_dependencies:
flutter_lints: ^3.0.1
flutter_lints: ^4.0.0
flutter_test:
sdk: flutter