-
Notifications
You must be signed in to change notification settings - Fork 41
/
log.dart
120 lines (104 loc) · 3.17 KB
/
log.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// This source code is a part of Project Violet.
// Copyright (C) 2020-2024. violet-team. Licensed under the Apache-2.0 License.
import 'dart:io';
import 'package:intl/intl.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:synchronized/synchronized.dart' as sync;
class LogEvent {
DateTime? dateTime;
bool isError;
bool isWarning;
String title;
String message;
String? detail;
LogEvent({
this.dateTime,
this.isError = false,
this.isWarning = false,
required this.title,
required this.message,
this.detail,
}) {
dateTime ??= DateTime.now();
}
LogEvent copy() => LogEvent(
dateTime: dateTime,
isError: isError,
isWarning: isWarning,
title: title,
message: message,
detail: detail,
);
}
class Logger {
// Since isolates handle all asynchronous operations linearly,
// there is no need for mutual exclusion.
static sync.Lock lock = sync.Lock();
static late File logFile;
static List<LogEvent> events = <LogEvent>[];
static Future<void> init() async {
if (Platform.environment.containsKey('FLUTTER_TEST')) {
logFile = File('log.txt');
} else {
final dir = await getApplicationDocumentsDirectory();
logFile = File(join(dir.path, 'log.txt'));
}
if (!await logFile.exists()) {
await logFile.create();
}
}
static Future<void> log(String msg) async {
print(msg);
if (!Platform.environment.containsKey('FLUTTER_TEST')) {
await lock.synchronized(() async {
await logFile.writeAsString('[${DateTime.now().toUtc()}] $msg\n',
mode: FileMode.append);
});
}
}
static Future<void> _logMessage(
String msg,
String prefix,
bool isError,
bool isWarning,
) async {
var message =
(msg.startsWith('[') ? msg.substring(msg.indexOf(']') + 1) : msg)
.trim();
events.add(LogEvent(
dateTime: DateTime.now().toUtc(),
isError: isError,
isWarning: isWarning,
message:
message.length > 500 ? '${message.substring(0, 500)}...' : message,
detail: message.length > 500 ? message : null,
title:
'[$prefix] (${DateFormat('kk:mm').format(DateTime.now())}) ${msg.startsWith('[') ? msg.split('[')[1].split(']')[0] : ''}',
));
await log('[$prefix] $msg');
}
static Future<void> info(String msg) async {
await _logMessage(msg, 'Info', false, false);
}
static Future<void> error(String msg) async {
await _logMessage(msg, 'Error', true, false);
}
static Future<void> warning(String msg) async {
await _logMessage(msg, 'Warning', false, true);
}
static Future<void> showLogs() async {
for (var element in (await logFile.readAsLines())) {
print(element);
}
}
static Future<void> exportLog() async {
final ext = Platform.isIOS
? await getApplicationSupportDirectory()
: await getExternalStorageDirectory();
// final dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
// final extpath = '${ext.path}/log-${dateFormat.format(DateTime.now())}.log';
final extpath = '${ext!.path}/log.txt';
await logFile.copy(extpath);
}
}