feat: more logging for wallet groups

This commit is contained in:
Czarek Nakamoto 2025-05-08 12:20:25 +02:00
parent e457481108
commit a8f3dd7710
10 changed files with 162 additions and 4 deletions

View file

@ -1,9 +1,20 @@
import 'dart:io';
import 'dart:math';
import 'package:flutter/foundation.dart';
String? printVLogFilePath;
void printV(dynamic content) {
CustomTrace programInfo = CustomTrace(StackTrace.current);
print("${programInfo.fileName}#${programInfo.lineNumber}:${programInfo.columnNumber} ${programInfo.callerFunctionName}: $content");
final logMsg = "${programInfo.fileName}#${programInfo.lineNumber}:${programInfo.columnNumber} ${programInfo.callerFunctionName}: $content";
if (printVLogFilePath != null) {
try {
File(printVLogFilePath!).writeAsStringSync("$logMsg\n", mode: FileMode.append);
} catch (e) {
print("Unable to write to log file (printV): $e");
}
}
print(logMsg);
}
// https://stackoverflow.com/a/59386101

View file

@ -85,6 +85,7 @@ class WalletLoadingService {
// try opening another wallet that is not corrupted to give user access to the app
final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
printV("WalletInfoSource length (wallet loading service): ${walletInfoSource.length}");
WalletBase? wallet;
for (var walletInfo in walletInfoSource.values) {
try {

View file

@ -28,6 +28,7 @@ import 'package:cake_wallet/store/authentication_store.dart';
import 'package:cake_wallet/themes/utils/theme_provider.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/exception_handler.dart';
import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/view_model/link_view_model.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cw_core/address_info.dart';
@ -74,6 +75,12 @@ Future<void> runAppWithZone({Key? topLevelKey}) async {
return true;
};
final date = DateTime.now().toIso8601String().replaceAll(':', '-');
final dir = '${(await getAppDir()).path}/print_v';
if (!Directory(dir).existsSync()) {
Directory(dir).createSync(recursive: true);
}
printVLogFilePath = FeatureFlag.hasDevOptions ? '$dir/$date.log' : null;
await FlutterDaemon().unmarkBackgroundSync();
await initializeAppAtRoot();
@ -199,6 +206,7 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
final trades = await CakeHive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
final orders = await CakeHive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
printV("WalletInfoSource length (initializeAppConfigs): ${walletInfoSource.length}");
final templates = await CakeHive.openBox<Template>(Template.boxName);
final exchangeTemplates = await CakeHive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
final anonpayInvoiceInfo = await CakeHive.openBox<AnonpayInvoiceInfo>(AnonpayInvoiceInfo.boxName);
@ -428,6 +436,12 @@ Future<void> backgroundSync() async {
WidgetsFlutterBinding.ensureInitialized();
printV("- DartPluginRegistrant.ensureInitialized()");
DartPluginRegistrant.ensureInitialized();
final date = DateTime.now().toIso8601String().replaceAll(':', '-');
final dir = '${(await getAppDir()).path}/print_v';
if (!Directory(dir).existsSync()) {
Directory(dir).createSync(recursive: true);
}
printVLogFilePath = FeatureFlag.hasDevOptions ? '$dir/$date.log' : null;
printV("- FlutterDaemon.markBackgroundSync()");
final val = await FlutterDaemon().markBackgroundSync();
if (val) {

View file

@ -39,6 +39,7 @@ import 'package:cake_wallet/src/screens/dashboard/sign_page.dart';
import 'package:cake_wallet/src/screens/dev/hash_change_logs_page.dart';
import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart';
import 'package:cake_wallet/src/screens/dev/print_verbose_logs_page.dart';
import 'package:cake_wallet/src/screens/dev/secure_preferences_page.dart';
import 'package:cake_wallet/src/screens/dev/shared_preferences_page.dart';
import 'package:cake_wallet/src/screens/dev/background_sync_logs_page.dart';
@ -924,6 +925,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.devHashChangeLogs:
return MaterialPageRoute<void>(builder: (_) => HashChangeLogsPage());
case Routes.devPrintVerbose:
return MaterialPageRoute<void>(builder: (_) => PrintVerboseLogsPage());
default:
return MaterialPageRoute<void>(
builder: (_) => Scaffold(

View file

@ -119,7 +119,8 @@ class Routes {
static const devSecurePreferences = '/dev/secure_preferences';
static const devBackgroundSyncLogs = '/dev/background_sync_logs';
static const devHashChangeLogs = '/dev/hash_change_logs';
static const devPrintVerbose = '/dev/print_verbose';
static const signPage = '/sign_page';
static const connectDevices = '/device/connect';
static const urqrAnimatedPage = '/urqr/animated_page';

View file

@ -53,7 +53,7 @@ class HashChangeLogsPage extends BasePage {
}
return SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Text(
child: SelectableText(
text,
style: TextStyle(fontFamily: 'monospace', fontSize: 14),
),

View file

@ -0,0 +1,104 @@
import 'dart:io';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/utils/share_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/view_model/dev/print_verbose_view_model.dart';
class PrintVerboseLogsPage extends BasePage {
final PrintVerboseViewModel viewModel = PrintVerboseViewModel();
PrintVerboseLogsPage();
@override
String? get title => "[dev] print verbose logs";
@override
Widget? trailing(BuildContext context) {
return IconButton(
icon: Icon(Icons.download, size: 20),
onPressed: () => _shareLog(context),
);
}
Future<void> _shareLog(BuildContext context) async {
if (viewModel.logFilePath == null) {
return;
}
final file = File(viewModel.logFilePath!);
if (await file.exists()) {
await ShareUtil.shareFile(
filePath: file.path,
fileName: 'Print verbose log',
context: context,
);
}
}
Future<String?> _loadLog() async {
if (viewModel.logFilePath == null) {
return null;
}
final file = File(viewModel.logFilePath!);
if (!await file.exists()) return null;
return await file.readAsString();
}
List<String> _logFiles() {
final dir = Directory(viewModel.logDirecoryPath);
if (!dir.existsSync()) {
return [];
}
return dir.listSync().map((e) => e.path).toList();
}
Widget logSelector() {
return ListView.builder(
itemCount: _logFiles().length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_logFiles()[index]),
onTap: () {
viewModel.logFilePath = _logFiles()[index];
},
);
},
);
}
@override
Widget body(BuildContext context) {
return Observer(builder: (context) {
return actualBody(context);
});
}
Widget actualBody(BuildContext context) {
if (viewModel.logFilePath == null) {
return logSelector();
}
return Scaffold(
body: FutureBuilder<String?>(
future: _loadLog(),
builder: (context, snap) {
if (snap.connectionState != ConnectionState.done) {
return Center(child: CircularProgressIndicator());
}
final text = snap.data;
if (text == null || text.isEmpty) {
return Center(child: Text('No log records found.'));
}
return SingleChildScrollView(
padding: EdgeInsets.all(16),
child: SelectableText(
text,
style: TextStyle(fontFamily: 'monospace', fontSize: 8),
),
);
},
),
);
}
}

View file

@ -99,6 +99,12 @@ class OtherSettingsPage extends BasePage {
handler: (BuildContext context) =>
Navigator.of(context).pushNamed(Routes.devHashChangeLogs),
),
if (FeatureFlag.hasDevOptions)
SettingsCellWithArrow(
title: '[dev] print verbose',
handler: (BuildContext context) =>
Navigator.of(context).pushNamed(Routes.devPrintVerbose),
),
Spacer(),
SettingsVersionCell(
title: S.of(context).version(_otherSettingsViewModel.currentVersion)),

View file

@ -1032,6 +1032,7 @@ abstract class DashboardViewModelBase with Store {
Future<List<String>> checkForHavenWallets() async {
final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
printV("WalletInfoSource length (checkForHavenWallets): ${walletInfoSource.length}");
return walletInfoSource.values
.where((element) => element.type == WalletType.haven)
.map((e) => e.name)
@ -1046,7 +1047,8 @@ abstract class DashboardViewModelBase with Store {
final vulnerableSeeds = vulnerableSeedsString.split("\n");
final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
printV("WalletInfoSource length (checkAffectedWallets): ${walletInfoSource.length}");
List<String> affectedWallets = [];
for (var walletInfo in walletInfoSource.values) {
if (walletInfo.type == WalletType.bitcoin) {

View file

@ -0,0 +1,15 @@
import 'package:cw_core/utils/print_verbose.dart';
import 'package:mobx/mobx.dart';
import 'package:path/path.dart' as p;
part 'print_verbose_view_model.g.dart';
class PrintVerboseViewModel = PrintVerboseViewModelBase with _$PrintVerboseViewModel;
abstract class PrintVerboseViewModelBase with Store {
PrintVerboseViewModelBase();
@observable
String? logFilePath;
final logDirecoryPath = p.dirname(printVLogFilePath!);
}