Skip to content

Commit

Permalink
feat: Attach console log in feedback email (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
mirland authored Sep 26, 2024
1 parent 1c26bde commit e587eb4
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 15 deletions.
30 changes: 26 additions & 4 deletions client/lib/core/common/logger.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
import 'dart:io';

import 'package:dartx/dartx_io.dart';
import 'package:logger/logger.dart' as dart_log;
import 'package:logger/logger.dart';
import 'package:path_provider/path_provider.dart';
import 'package:simon_ai/core/common/config.dart';
import 'package:simon_ai/core/common/crash_report_tool.dart';
import 'package:stack_trace/stack_trace.dart';

interface class Logger {
static const String logFilePath = '/logs/logs.txt';
static final CrashReportTool _crashReportTool = Config.crashlyticsEnabled
? CrashlyticsCrashReportTool()
: NoOpsCrashReportTool();

static final List<LogOutput> _outputList = [ConsoleOutput()];

static final dart_log.Logger _instance = dart_log.Logger(
printer: _CrashReportWrappedPrinter(_CustomDebugLogger(), _crashReportTool),
filter: _DisplayAllLogFilter(),
output: MultiOutput([ConsoleOutput()]),
output: MultiOutput(_outputList),
);

static Future init() => _crashReportTool.init();
static Future init() async {
await _crashReportTool.init();
await _initConsoleFileOutput();
i('Logger initialized, date: ${DateTime.now()}');
}

static Future<void> _initConsoleFileOutput() async {
final Directory output = await getTemporaryDirectory();
final logFile = File('${output.path}$logFilePath');
_outputList.add(
AdvancedFileOutput(
path: logFile.dirName,
latestFileName: logFile.name,
),
);
}

static void v(dynamic message, [dynamic error, StackTrace? stackTrace]) =>
_instance.log(Level.trace, message, error: error, stackTrace: stackTrace);
Expand Down Expand Up @@ -119,8 +141,8 @@ class _PrintableTrace extends Trace {
}

class _CustomDebugLogger extends LogPrinter {
final _simpleLogger = SimplePrinter();
final _prettyPrinter = PrettyPrinter();
final _simpleLogger = SimplePrinter(colors: false);
final _prettyPrinter = PrettyPrinter(colors: false);

@override
List<String> log(LogEvent event) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class GestureMobileProcessor implements GestureProcessor {
handCannedGestureClassifier = HandCannedGestureClassifier();
_fpsTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
final currentFrame = _currentFrame;
Logger.i('FPS: ${currentFrame - _lastCurrentFrame}!');
Logger.i('FPS: ${currentFrame - _lastCurrentFrame}');
_fpsStreamController.add(currentFrame - _lastCurrentFrame);
_lastCurrentFrame = currentFrame;
});
Expand Down
30 changes: 20 additions & 10 deletions client/lib/ui/common/app_feedback.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:package_info_plus/package_info_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shake/shake.dart';
import 'package:simon_ai/core/common/config.dart';
import 'package:simon_ai/core/common/logger.dart';

class AppFeedback {
static void init(BuildContext context) {
Expand All @@ -20,28 +21,37 @@ class AppFeedback {

static void _displayFeedbackWidget(BuildContext context) {
BetterFeedback.of(context).show((feedback) async {
final screenshotFilePath =
await _writeImageToStorage(feedback.screenshot);
final packageInfo = await PackageInfo.fromPlatform();
final appName = packageInfo.appName;
final version = packageInfo.version;
final buildNumber = packageInfo.buildNumber;
final Email email = Email(
body: feedback.text,
subject: 'Feedback $appName - v$version($buildNumber)',
subject: await _subject(),
recipients: [Config.feedbackEmail],
attachmentPaths: [screenshotFilePath],
attachmentPaths: await _attachmentFiles(feedback),
isHTML: false,
);
await FlutterEmailSender.send(email);
});
}

static Future<List<String>> _attachmentFiles(UserFeedback feedback) async {
final String cacheDirectory = (await getTemporaryDirectory()).path;
final screenshotFilePath =
await _writeImageToStorage(cacheDirectory, feedback.screenshot);
return [screenshotFilePath, cacheDirectory + Logger.logFilePath];
}

static Future<String> _subject() async {
final packageInfo = await PackageInfo.fromPlatform();
final appName = packageInfo.appName;
final version = packageInfo.version;
final buildNumber = packageInfo.buildNumber;
return 'Feedback $appName - v$version($buildNumber)';
}

static Future<String> _writeImageToStorage(
String path,
Uint8List feedbackScreenshot,
) async {
final Directory output = await getTemporaryDirectory();
final String screenshotFilePath = '${output.path}/feedback.png';
final String screenshotFilePath = '$path/feedback.png';
final File screenshotFile = File(screenshotFilePath);
await screenshotFile.writeAsBytes(feedbackScreenshot);
return screenshotFilePath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:simon_ai/core/common/logger.dart';

part 'global_event_handler_cubit.freezed.dart';

Expand All @@ -17,6 +18,7 @@ class GlobalEventHandlerCubit extends Cubit<GlobalEventHandlerState>
StackTrace? stackTrace,
VoidCallback? retry,
]) {
Logger.w('Handled error', error, stackTrace);
if (error is DioException &&
(error.type == DioExceptionType.connectionTimeout ||
error.type == DioExceptionType.sendTimeout ||
Expand Down

0 comments on commit e587eb4

Please sign in to comment.