Skip to content

Commit e549b8e

Browse files
committed
add logger
1 parent 996eedb commit e549b8e

File tree

4 files changed

+276
-1
lines changed

4 files changed

+276
-1
lines changed

lib/presentation/screens/message/bloc/message_bloc.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ class MessageBloc extends Bloc<MessageEvent, MessageState> {
120120
automaticMessage,
121121
);
122122
}
123-
_automacticReply();
124123
} catch (e) {
125124
print(e);
126125
}

lib/utils/logger.dart

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
import 'dart:io';
2+
import 'package:stack_trace/stack_trace.dart';
3+
import 'package:path_provider/path_provider.dart';
4+
5+
enum LogLevel {
6+
DEBUG,
7+
INFO,
8+
WARNING,
9+
ERROR,
10+
}
11+
12+
enum StorageOptions {
13+
SD_CARD,
14+
LOCAL_STORAGE,
15+
ENABLE_ALL,
16+
}
17+
18+
class Logger {
19+
static bool isLog = true;
20+
static LogLevel level = LogLevel.DEBUG;
21+
static String tag = 'Reader ConsoleLog';
22+
static StorageOptions storageOption = StorageOptions.LOCAL_STORAGE;
23+
static LogsStorage logsStorage = LogsStorage();
24+
25+
Logger({
26+
bool? isLog,
27+
LogLevel? level,
28+
String? tag,
29+
StorageOptions? storageOption,
30+
}) {
31+
Logger.isLog = isLog ?? Logger.isLog;
32+
Logger.level = level ?? Logger.level;
33+
Logger.tag = tag ?? Logger.tag;
34+
Logger.storageOption = storageOption ?? Logger.storageOption;
35+
}
36+
37+
static debug(String msg) {
38+
_log(LogLevel.DEBUG, msg);
39+
}
40+
41+
static info(String msg) {
42+
_log(LogLevel.INFO, msg);
43+
}
44+
45+
static warning(String msg) {
46+
_log(LogLevel.WARNING, msg);
47+
}
48+
49+
static error(String msg) {
50+
_log(LogLevel.ERROR, msg);
51+
}
52+
53+
static Future<List<LogEntity>?> getLogs() async {
54+
return await logsStorage.readLogsFromFile(StorageOptions.LOCAL_STORAGE);
55+
}
56+
57+
static Future<List<LogEntity>?> getLogsByType(LogLevel level) async {
58+
var logs = await logsStorage.readLogsFromFile(StorageOptions.LOCAL_STORAGE);
59+
var filterLogs =
60+
logs!.where((log) => log.level.index >= level.index).toList();
61+
return filterLogs;
62+
}
63+
64+
static void clearLogs() {
65+
logsStorage.clearLogsInFile();
66+
}
67+
68+
static _log(LogLevel level, String msg) {
69+
try {
70+
if (isLog && level.index >= level.index) {
71+
Frame frame = Trace.current().frames[2];
72+
final log = LogEntity(
73+
time: DateTime.now(),
74+
level: level,
75+
filePath: frame.uri.toString(),
76+
screen: frame.member!.split(".")[0],
77+
method: frame.member!.split(".")[1],
78+
line: frame.line!,
79+
message: msg,
80+
);
81+
82+
print('$tag - ${log.toString()}'); // Console log option
83+
84+
switch (storageOption) {
85+
case StorageOptions.LOCAL_STORAGE:
86+
case StorageOptions.SD_CARD:
87+
logsStorage.writeLogsToFile(storageOption, log);
88+
break;
89+
case StorageOptions.ENABLE_ALL:
90+
logsStorage.writeLogsToFile(StorageOptions.SD_CARD, log);
91+
logsStorage.writeLogsToFile(StorageOptions.LOCAL_STORAGE, log);
92+
break;
93+
}
94+
}
95+
} catch (error) {
96+
print(error);
97+
}
98+
}
99+
}
100+
101+
class LogsStorage {
102+
FileMode _writeMode = FileMode.write;
103+
String _startSign = "Reader ConsoleLog ";
104+
105+
Future<File> get _localFile async {
106+
const DIRECTORY_NAME = "logger";
107+
const FILE_NAME = "logs.txt";
108+
109+
Directory? directory;
110+
111+
if (Platform.isIOS) {
112+
directory = await getApplicationDocumentsDirectory();
113+
} else {
114+
directory = await getExternalStorageDirectory();
115+
}
116+
117+
final path = "${directory!.path}/$DIRECTORY_NAME";
118+
119+
Directory(path).create();
120+
121+
var file = File("$path/$FILE_NAME");
122+
var isExist = await file.exists();
123+
124+
_writeMode = isExist ? FileMode.append : FileMode.write;
125+
126+
return file;
127+
}
128+
129+
Future<File> get _sdCardFile async {
130+
return File("");
131+
}
132+
133+
void writeLogsToFile(StorageOptions storageOption, LogEntity log) async {
134+
File file;
135+
if (storageOption == StorageOptions.LOCAL_STORAGE) {
136+
file = await _localFile;
137+
} else {
138+
file = await _sdCardFile;
139+
}
140+
final logString = "$_startSign${log.toString()}\n";
141+
await file.writeAsString(logString, mode: _writeMode);
142+
}
143+
144+
void clearLogsInFile() async {
145+
final file = await _localFile;
146+
await file.writeAsString("");
147+
}
148+
149+
Future<List<LogEntity>?> readLogsFromFile(
150+
StorageOptions storageOption,
151+
) async {
152+
try {
153+
File file;
154+
if (storageOption == StorageOptions.LOCAL_STORAGE) {
155+
file = await _localFile;
156+
} else {
157+
file = await _sdCardFile;
158+
}
159+
160+
String content = await file.readAsString();
161+
162+
List<String> logs = content.split(_startSign);
163+
164+
logs.removeAt(0);
165+
List<LogEntity> results =
166+
logs.map((log) => LogEntity.fromString(log)).toList();
167+
return results;
168+
} catch (e) {
169+
return null;
170+
}
171+
}
172+
}
173+
174+
class LogEntity {
175+
final DateTime time;
176+
final LogLevel level;
177+
final String filePath;
178+
final String screen;
179+
final String method;
180+
final int line;
181+
final String message;
182+
183+
static String _messageIndicator = " ::: ";
184+
static String _infoIndicator = " - ";
185+
186+
LogEntity({
187+
required this.time,
188+
this.level = LogLevel.DEBUG,
189+
this.filePath = "",
190+
this.screen = "",
191+
this.method = "",
192+
this.line = 0,
193+
this.message = "",
194+
});
195+
196+
@override
197+
String toString() {
198+
return '${dateTimeToString(time)}$_infoIndicator${_logLevelToString(level)}$_infoIndicator$filePath$_infoIndicator$screen$_infoIndicator$method$_infoIndicator$line$_messageIndicator$message';
199+
}
200+
201+
factory LogEntity.fromString(String log) {
202+
List<String> logInfos =
203+
log.split(_messageIndicator)[0].split(_infoIndicator);
204+
String message = log.split(_messageIndicator)[1];
205+
return LogEntity(
206+
time: stringToDateTime(logInfos[0]),
207+
level: _stringToLogLevel(logInfos[1]),
208+
filePath: logInfos[2],
209+
screen: logInfos[3],
210+
method: logInfos[4],
211+
line: int.parse(logInfos[5]),
212+
message: message,
213+
);
214+
}
215+
216+
String _logLevelToString(LogLevel level) {
217+
switch (level) {
218+
case LogLevel.DEBUG:
219+
return "DEBUG";
220+
case LogLevel.INFO:
221+
return "INFO";
222+
case LogLevel.ERROR:
223+
return "ERROR";
224+
case LogLevel.WARNING:
225+
return "WARNING";
226+
default:
227+
return "DEBUG";
228+
}
229+
}
230+
231+
static _stringToLogLevel(String level) {
232+
switch (level) {
233+
case "DEBUG":
234+
return LogLevel.DEBUG;
235+
case "INFO":
236+
return LogLevel.INFO;
237+
case "ERROR":
238+
return LogLevel.ERROR;
239+
case "WARNING":
240+
return LogLevel.WARNING;
241+
default:
242+
return LogLevel.DEBUG;
243+
}
244+
}
245+
246+
static String dateTimeToString(DateTime date) {
247+
final year = "${date.year}";
248+
final month = date.month < 10 ? "0${date.month}" : "${date.month}";
249+
final day = date.day < 10 ? "0${date.day}" : "${date.day}";
250+
final hour = date.hour < 10 ? "0${date.hour}" : "${date.hour}";
251+
final minute = date.minute < 10 ? "0${date.minute}" : "${date.minute}";
252+
final second = date.second < 10 ? "0${date.second}" : "${date.second}";
253+
String time = '$year-$month-$day $hour:$minute:$second';
254+
return time;
255+
}
256+
257+
static DateTime stringToDateTime(String time) {
258+
return DateTime.parse(time);
259+
}
260+
}

pubspec.lock

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,13 +462,27 @@ packages:
462462
url: "https://pub.dartlang.org"
463463
source: hosted
464464
version: "0.2.0-nullsafety.0"
465+
path_provider:
466+
dependency: "direct main"
467+
description:
468+
name: path_provider
469+
url: "https://pub.dartlang.org"
470+
source: hosted
471+
version: "2.0.1"
465472
path_provider_linux:
466473
dependency: transitive
467474
description:
468475
name: path_provider_linux
469476
url: "https://pub.dartlang.org"
470477
source: hosted
471478
version: "2.0.0"
479+
path_provider_macos:
480+
dependency: transitive
481+
description:
482+
name: path_provider_macos
483+
url: "https://pub.dartlang.org"
484+
source: hosted
485+
version: "2.0.0"
472486
path_provider_platform_interface:
473487
dependency: transitive
474488
description:

pubspec.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,13 @@ dependencies:
4848
fluttertoast: ^8.0.3
4949
dio: ^4.0.0
5050
url_launcher: ^6.0.3
51+
5152
# The following adds the Cupertino Icons font to your application.
5253
# Use with the CupertinoIcons class for iOS style icons.
5354
cupertino_icons: ^1.0.0
5455
flutter_svg: ^0.21.0-nullsafety.0 # Help us to use svg in our app
5556
flutter_launcher_icons: ^0.9.0
57+
path_provider: ^2.0.1
5658
dev_dependencies:
5759
flutter_test:
5860
sdk: flutter

0 commit comments

Comments
 (0)