Provide option to opt in to crash analytics

This commit is contained in:
vishnukvmd 2022-11-22 14:59:25 +05:30
parent 21b139687d
commit b20139f3b8
2 changed files with 65 additions and 24 deletions

View file

@ -17,6 +17,8 @@ import 'package:package_info_plus/package_info_plus.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:uuid/uuid.dart';
typedef FutureOrVoidCallback = FutureOr<void> Function();
@ -144,54 +146,51 @@ class SuperLogging {
/// The current super logging configuration
static LogConfig config;
static SharedPreferences _preferences;
static const keyShouldReportErrors = "should_report_errors";
static const keyAnonymousUserID = "anonymous_user_id";
static Future<void> main([LogConfig config]) async {
config ??= LogConfig();
SuperLogging.config = config;
WidgetsFlutterBinding.ensureInitialized();
appVersion ??= await getAppVersion();
final isFDroidClient = await isFDroidBuild();
if (isFDroidClient) {
config.sentryDsn = null;
config.tunnel = null;
}
_preferences = await SharedPreferences.getInstance();
final enable = config.enableInDebugMode || kReleaseMode;
sentryIsEnabled = enable && config.sentryDsn != null && !isFDroidClient;
fileIsEnabled = enable && config.logDirPath != null;
appVersion ??= await getAppVersion();
final loggingEnabled = config.enableInDebugMode || kReleaseMode;
sentryIsEnabled =
loggingEnabled && config.sentryDsn != null && shouldReportErrors();
fileIsEnabled = loggingEnabled && config.logDirPath != null;
if (fileIsEnabled) {
await setupLogDir();
}
if (sentryIsEnabled) {
setupSentry();
}
Logger.root.level = Level.ALL;
Logger.root.onRecord.listen(onLogRecord);
if (isFDroidClient) {
assert(
sentryIsEnabled == false,
"sentry dsn should be disabled for "
"f-droid config ${config.sentryDsn} & ${config.tunnel}",
);
if (sentryIsEnabled) {
setupSentry();
} else {
$.info("Sentry is disabled");
}
if (!enable) {
if (!loggingEnabled) {
$.info("detected debug mode; sentry & file logging disabled.");
}
if (fileIsEnabled) {
$.info("log file for today: $logFile with prefix ${config.prefix}");
}
if (sentryIsEnabled) {
$.info("sentry uploader started");
}
if (config.body == null) return;
if (enable && sentryIsEnabled) {
if (loggingEnabled && sentryIsEnabled) {
await SentryFlutter.init(
(options) {
options.dsn = config.sentryDsn;
@ -296,6 +295,8 @@ class SuperLogging {
static bool sentryIsEnabled;
static Future<void> setupSentry() async {
$.info("Setting up sentry");
SuperLogging.setUserID(await _getOrCreateAnonymousUserID());
await for (final error in sentryQueueControl.stream.asBroadcastStream()) {
try {
Sentry.captureException(
@ -315,6 +316,26 @@ class SuperLogging {
sentryQueueControl.add(error);
}
static bool shouldReportErrors() {
if (_preferences.containsKey(keyShouldReportErrors)) {
return _preferences.getBool(keyShouldReportErrors);
} else {
return false;
}
}
static Future<void> setShouldReportErrors(bool value) {
return _preferences.setBool(keyShouldReportErrors, value);
}
static Future<String> _getOrCreateAnonymousUserID() async {
if (!_preferences.containsKey(keyAnonymousUserID)) {
//ignore: prefer_const_constructors
await _preferences.setString(keyAnonymousUserID, Uuid().v4());
}
return _preferences.getString(keyAnonymousUserID);
}
/// The log file currently in use.
static File logFile;

View file

@ -1,17 +1,24 @@
// @dart=2.9
import 'package:ente_auth/core/constants.dart';
import 'package:ente_auth/core/logging/super_logging.dart';
import 'package:ente_auth/theme/ente_theme.dart';
import 'package:ente_auth/ui/components/captioned_text_widget.dart';
import 'package:ente_auth/ui/components/expandable_menu_item_widget.dart';
import 'package:ente_auth/ui/components/menu_item_widget.dart';
import 'package:ente_auth/ui/components/toggle_switch_widget.dart';
import 'package:ente_auth/ui/settings/common_settings.dart';
import 'package:ente_auth/utils/email_util.dart';
import 'package:flutter/material.dart';
class SupportSectionWidget extends StatelessWidget {
class SupportSectionWidget extends StatefulWidget {
const SupportSectionWidget({Key key}) : super(key: key);
@override
State<SupportSectionWidget> createState() => _SupportSectionWidgetState();
}
class _SupportSectionWidgetState extends State<SupportSectionWidget> {
@override
Widget build(BuildContext context) {
return ExpandableMenuItemWidget(
@ -53,6 +60,19 @@ class SupportSectionWidget extends StatelessWidget {
},
),
sectionOptionSpacing,
MenuItemWidget(
captionedTextWidget: const CaptionedTextWidget(
title: "Crash analytics",
),
trailingSwitch: ToggleSwitchWidget(
value: SuperLogging.shouldReportErrors(),
onChanged: (value) async {
await SuperLogging.setShouldReportErrors(value);
setState(() {});
},
),
),
sectionOptionSpacing,
],
);
}