From 57bbb80a0188d3bed9ca70846a89df6a3c2c0953 Mon Sep 17 00:00:00 2001 From: Jagandeep Brar Date: Thu, 1 Sep 2022 15:51:54 -0400 Subject: [PATCH] feat(logging): integrate Sentry logging support for all platforms --- .github/workflows/prepare.yml | 3 ++ .github/workflows/release.yml | 1 + environment_config.yaml | 5 ++++ ios/Podfile.lock | 17 +++++++++-- ios/Runner.xcodeproj/project.pbxproj | 4 +++ lib/main.dart | 4 ++- lib/router/router.dart | 6 ++-- lib/system/logger.dart | 29 +++++++++++++------ lib/system/sentry.dart | 18 ++++++++++++ linux/flutter/generated_plugin_registrant.cc | 4 +++ linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 ++ macos/Podfile.lock | 17 +++++++++-- pubspec.lock | 14 +++++++++ pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 3 ++ windows/flutter/generated_plugins.cmake | 1 + 17 files changed, 113 insertions(+), 17 deletions(-) create mode 100644 lib/system/sentry.dart diff --git a/.github/workflows/prepare.yml b/.github/workflows/prepare.yml index 1cd6f8f9..e4ac627b 100644 --- a/.github/workflows/prepare.yml +++ b/.github/workflows/prepare.yml @@ -27,6 +27,8 @@ on: secrets: FIREBASE_TOKEN: required: true + SENTRY_DSN: + required: true jobs: build-details: @@ -131,6 +133,7 @@ jobs: export FLAVOR=${{ needs.build-details.outputs.build-flavor }} export COMMIT=${{ github.sha }} export BUILD=${{ needs.build-details.outputs.build-number }} + export SENTRY_DSN=${{ secrets.SENTRY_DSN }} flutter packages pub run environment_config:generate - name: Generate Localization diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2269e0b..9b55eb64 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,6 +25,7 @@ jobs: flavor: ${{ inputs.flavor }} secrets: FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} + SENTRY_DSN: ${{ secrets.SENTRY_DSN }} build-android: name: Build Android diff --git a/environment_config.yaml b/environment_config.yaml index f5ff7b02..3ed72d9c 100644 --- a/environment_config.yaml +++ b/environment_config.yaml @@ -15,3 +15,8 @@ environment_config: type: String default: edge env_var: FLAVOR + sentryDSN: + type: String + default: "" + env_var: SENTRY_DSN + diff --git a/ios/Podfile.lock b/ios/Podfile.lock index eb7ab2d6..92280a59 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -58,7 +58,7 @@ PODS: - firebase_core (1.21.1): - Firebase/CoreOnly (= 9.4.0) - Flutter - - firebase_messaging (12.0.1): + - firebase_messaging (12.0.3): - Firebase/Messaging (= 9.4.0) - firebase_core - Flutter @@ -163,6 +163,13 @@ PODS: - SDWebImage (5.13.2): - SDWebImage/Core (= 5.13.2) - SDWebImage/Core (5.13.2) + - Sentry (7.23.0): + - Sentry/Core (= 7.23.0) + - Sentry/Core (7.23.0) + - sentry_flutter (0.0.1): + - Flutter + - FlutterMacOS + - Sentry (~> 7.23.0) - share_plus (0.0.1): - Flutter - shared_preferences_ios (0.0.1): @@ -189,6 +196,7 @@ DEPENDENCIES: - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) - quick_actions_ios (from `.symlinks/plugins/quick_actions_ios/ios`) + - sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`) @@ -217,6 +225,7 @@ SPEC REPOS: - nanopb - PromisesObjC - SDWebImage + - Sentry - SwiftyGif EXTERNAL SOURCES: @@ -247,6 +256,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/path_provider_ios/ios" quick_actions_ios: :path: ".symlinks/plugins/quick_actions_ios/ios" + sentry_flutter: + :path: ".symlinks/plugins/sentry_flutter/ios" share_plus: :path: ".symlinks/plugins/share_plus/ios" shared_preferences_ios: @@ -269,7 +280,7 @@ SPEC CHECKSUMS: Firebase: 7703fc4022824b6d6db1bf7bea58d13b8e17ec46 firebase_auth: 74cfbf7be1e3e7fdaac9e7f117cefd89155251a9 firebase_core: 8e500850dd138c269d197c8dfca3ae886fa3b6f2 - firebase_messaging: 2a3412ef5e30b84adfb66ae358e7a8fdebcd7462 + firebase_messaging: b65dacd4de1b469893dea0d754b1947f45ef4f7a firebase_storage: 846832b7f2d22238678dc9abc513f2151f102462 FirebaseAppCheckInterop: 8e95b4329809e3c06fb425acb3839dcadfe23673 FirebaseAuth: ae5d4402e1516497357d909162b091b3ca2a2e9c @@ -296,6 +307,8 @@ SPEC CHECKSUMS: PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb quick_actions_ios: 5ec8f5f1ae81512ac803fe10c197ebb875767a9e SDWebImage: 72f86271a6f3139cc7e4a89220946489d4b9a866 + Sentry: a0d4563fa4ddacba31fdcc35daaa8573d87224d6 + sentry_flutter: 8bde7d0e57a721727fe573f13bb292c497b5a249 share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index f2a6d0e6..4aab71b6 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -424,6 +424,7 @@ "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", "${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework", "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", + "${BUILT_PRODUCTS_DIR}/Sentry/Sentry.framework", "${BUILT_PRODUCTS_DIR}/SwiftyGif/SwiftyGif.framework", "${BUILT_PRODUCTS_DIR}/file_picker/file_picker.framework", "${BUILT_PRODUCTS_DIR}/flutter_native_splash/flutter_native_splash.framework", @@ -432,6 +433,7 @@ "${BUILT_PRODUCTS_DIR}/package_info_plus/package_info_plus.framework", "${BUILT_PRODUCTS_DIR}/path_provider_ios/path_provider_ios.framework", "${BUILT_PRODUCTS_DIR}/quick_actions_ios/quick_actions_ios.framework", + "${BUILT_PRODUCTS_DIR}/sentry_flutter/sentry_flutter.framework", "${BUILT_PRODUCTS_DIR}/share_plus/share_plus.framework", "${BUILT_PRODUCTS_DIR}/shared_preferences_ios/shared_preferences_ios.framework", "${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework", @@ -458,6 +460,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sentry.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyGif.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_picker.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_native_splash.framework", @@ -466,6 +469,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_ios.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/quick_actions_ios.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sentry_flutter.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_ios.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework", diff --git a/lib/main.dart b/lib/main.dart index 0c3bf125..7d58bdc7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -10,6 +10,7 @@ import 'package:lunasea/system/cache/image/image_cache.dart'; import 'package:lunasea/system/in_app_purchase/in_app_purchase.dart'; import 'package:lunasea/system/localization.dart'; import 'package:lunasea/system/network/network.dart'; +import 'package:lunasea/system/sentry.dart'; import 'package:lunasea/system/window_manager/window_manager.dart'; import 'package:lunasea/system/platform.dart'; @@ -21,9 +22,10 @@ Future main() async { runZonedGuarded( () async { //LunaSea initialization + await LunaSentry().initialize(); await LunaDatabase().initialize(); - if (LunaFirebase.isSupported) await LunaFirebase().initialize(); LunaLogger().initialize(); + if (LunaFirebase.isSupported) await LunaFirebase().initialize(); LunaTheme().initialize(); if (LunaWindowManager.isSupported) await LunaWindowManager().initialize(); if (LunaNetwork.isSupported) LunaNetwork().initialize(); diff --git a/lib/router/router.dart b/lib/router/router.dart index d05d1e58..f1b40871 100644 --- a/lib/router/router.dart +++ b/lib/router/router.dart @@ -1,5 +1,6 @@ import 'package:flutter/foundation.dart'; import 'package:lunasea/system/logger.dart'; +import 'package:lunasea/system/sentry.dart'; import 'package:lunasea/widgets/pages/error_route.dart'; import 'package:lunasea/router/routes.dart'; import 'package:lunasea/vendor.dart'; @@ -10,11 +11,10 @@ class LunaRouter { void initialize() { router = GoRouter( debugLogDiagnostics: kDebugMode, + errorBuilder: (_, state) => ErrorRoutePage(exception: state.error), initialLocation: LunaRoutes.initialLocation, + observers: [LunaSentry().navigatorObserver], routes: LunaRoutes.values.map((r) => r.root.routes).toList(), - errorBuilder: (_, state) { - return ErrorRoutePage(exception: state.error); - }, ); } diff --git a/lib/system/logger.dart b/lib/system/logger.dart index 41935f89..fd621d94 100644 --- a/lib/system/logger.dart +++ b/lib/system/logger.dart @@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:lunasea/core.dart'; import 'package:lunasea/database/models/log.dart'; +import 'package:lunasea/system/sentry.dart'; import 'package:lunasea/types/exception.dart'; import 'package:lunasea/types/log_type.dart'; @@ -53,34 +54,44 @@ class LunaLogger { } void error(String message, dynamic error, StackTrace? stackTrace) { + if (kDebugMode) { + print(message); + print(error); + print(stackTrace); + } + if (error is! NetworkImageLoadException) { + if (error is! DioError) { + LunaSentry().captureException(error, stackTrace); + } + LunaLog log = LunaLog.withError( type: LunaLogType.ERROR, message: message, error: error, stackTrace: stackTrace, ); - if (kDebugMode) { - print(message); - print(error); - print(stackTrace); - } LunaBox.logs.create(log); } } void critical(dynamic error, StackTrace stackTrace) { + if (kDebugMode) { + print(error); + print(stackTrace); + } + if (error is! NetworkImageLoadException) { + if (error is! DioError) { + LunaSentry().captureException(error, stackTrace); + } + LunaLog log = LunaLog.withError( type: LunaLogType.CRITICAL, message: error?.toString() ?? LunaUI.TEXT_EMDASH, error: error, stackTrace: stackTrace, ); - if (kDebugMode) { - print(error); - print(stackTrace); - } LunaBox.logs.create(log); } } diff --git a/lib/system/sentry.dart b/lib/system/sentry.dart new file mode 100644 index 00000000..b75107f7 --- /dev/null +++ b/lib/system/sentry.dart @@ -0,0 +1,18 @@ +import 'package:lunasea/system/environment.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + +class LunaSentry { + Future initialize() async { + await SentryFlutter.init((options) { + options.dsn = LunaEnvironment.sentryDSN; + options.environment = LunaEnvironment.flavor; + options.release = LunaEnvironment.commit; + }); + } + + Future captureException(dynamic error, StackTrace? stackTrace) async { + await Sentry.captureException(error, stackTrace: stackTrace); + } + + SentryNavigatorObserver get navigatorObserver => SentryNavigatorObserver(); +} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 0cacc750..76c9a952 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,6 +7,7 @@ #include "generated_plugin_registrant.h" #include +#include #include #include @@ -14,6 +15,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) screen_retriever_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); + g_autoptr(FlPluginRegistrar) sentry_flutter_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "SentryFlutterPlugin"); + sentry_flutter_plugin_register_with_registrar(sentry_flutter_registrar); g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 62f151fd..7194bb72 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST screen_retriever + sentry_flutter url_launcher_linux window_manager ) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 12c86fc0..f4ba0647 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -13,6 +13,7 @@ import firebase_storage import package_info_plus_macos import path_provider_macos import screen_retriever +import sentry_flutter import share_plus_macos import shared_preferences_macos import sqflite @@ -28,6 +29,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) + SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index a6ac5ac0..e31d4dc4 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -26,7 +26,7 @@ PODS: - firebase_core (1.21.1): - Firebase/CoreOnly (~> 9.4.0) - FlutterMacOS - - firebase_messaging (12.0.1): + - firebase_messaging (12.0.3): - Firebase/CoreOnly (~> 9.4.0) - Firebase/Messaging (~> 9.4.0) - firebase_core @@ -126,6 +126,13 @@ PODS: - PromisesObjC (2.1.1) - screen_retriever (0.0.1): - FlutterMacOS + - Sentry (7.23.0): + - Sentry/Core (= 7.23.0) + - Sentry/Core (7.23.0) + - sentry_flutter (0.0.1): + - Flutter + - FlutterMacOS + - Sentry (~> 7.23.0) - share_plus_macos (0.0.1): - FlutterMacOS - shared_preferences_macos (0.0.1): @@ -149,6 +156,7 @@ DEPENDENCIES: - package_info_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus_macos/macos`) - path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`) - screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`) + - sentry_flutter (from `Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos`) - share_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos`) - shared_preferences_macos (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos`) - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) @@ -175,6 +183,7 @@ SPEC REPOS: - GTMSessionFetcher - nanopb - PromisesObjC + - Sentry EXTERNAL SOURCES: cloud_firestore: @@ -198,6 +207,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos screen_retriever: :path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos + sentry_flutter: + :path: Flutter/ephemeral/.symlinks/plugins/sentry_flutter/macos share_plus_macos: :path: Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos shared_preferences_macos: @@ -219,7 +230,7 @@ SPEC CHECKSUMS: Firebase: 7703fc4022824b6d6db1bf7bea58d13b8e17ec46 firebase_auth: d73121234b93a92fa130c1595c59afd37cbfcce8 firebase_core: 822a1076483bf9764284322c9310daa98e1e6817 - firebase_messaging: 564a55c225276ba69412e29557c8d280916aa22f + firebase_messaging: b76079f26d7a22470b2de423198a0cabf98ebf03 firebase_storage: 5e4de184fe773a22f4c65875d1e71c009a4cc7b0 FirebaseAppCheckInterop: 8e95b4329809e3c06fb425acb3839dcadfe23673 FirebaseAuth: ae5d4402e1516497357d909162b091b3ca2a2e9c @@ -243,6 +254,8 @@ SPEC CHECKSUMS: path_provider_macos: 3c0c3b4b0d4a76d2bf989a913c2de869c5641a19 PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38 + Sentry: a0d4563fa4ddacba31fdcc35daaa8573d87224d6 + sentry_flutter: 8bde7d0e57a721727fe573f13bb292c497b5a249 share_plus_macos: 853ee48e7dce06b633998ca0735d482dd671ade4 shared_preferences_macos: a64dc611287ed6cbe28fd1297898db1336975727 sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea diff --git a/pubspec.lock b/pubspec.lock index fc42704f..13197c64 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1029,6 +1029,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" + sentry: + dependency: transitive + description: + name: sentry + url: "https://pub.dartlang.org" + source: hosted + version: "6.9.1" + sentry_flutter: + dependency: "direct main" + description: + name: sentry_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "6.9.1" share_plus: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index eaad6143..1f886bd4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -44,6 +44,7 @@ dependencies: percent_indicator: ^4.2.2 quick_actions: ^1.0.0 retrofit: ^3.0.1+1 + sentry_flutter: ^6.9.1 share_plus: ^4.0.10+1 shimmer: ^2.0.0 simple_icons: ^7.1.0 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index fe7ec1cb..43d19d1b 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,12 +7,15 @@ #include "generated_plugin_registrant.h" #include +#include #include #include void RegisterPlugins(flutter::PluginRegistry* registry) { ScreenRetrieverPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); + SentryFlutterPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SentryFlutterPlugin")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); WindowManagerPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index fb2dea6b..a929f0c8 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST screen_retriever + sentry_flutter url_launcher_windows window_manager )