Log Color
Setting Up Colored Logs and Saving Logs to Device Storage
Step 1: Add Dependencies
dependencies:
flutter:
sdk: flutter
logger: ^2.3.0Step 2: Create a Logging Class
import 'dart:async';
import 'dart:convert';
import 'dart:developer' as developer;
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:logger/logger.dart';
bool enviIsDevelop = true;
class MyLog {
bool isLogging = true;
Logger logger = Logger(
filter: kReleaseMode ? PermissiveFilter() : DevelopmentFilter(),
printer: PrettyPrinter(
methodCount: 3,
printEmojis: false,
printTime: true, // Log sẽ chứa thời gian
),
);
Future<void> setUp({
String? path,
bool printTime = true,
bool isLogging = true,
String? noteInfoFileLog,
}) async {
if (this.isLogging != isLogging) this.isLogging = isLogging;
if (path != null) {
final file = File(path);
if (noteInfoFileLog != null) {
await file.writeAsString(
noteInfoFileLog,
mode: FileMode.writeOnlyAppend,
);
}
final FileOutput2 fileOutPut = FileOutput2(
file: file,
);
final ConsoleOutput consoleOutput = ConsoleOutput();
final List<LogOutput> multiOutput = [fileOutPut, consoleOutput];
logger = Logger(
printer: PrettyPrinter(
methodCount: 3,
errorMethodCount: 12,
lineLength: 150,
printEmojis: false,
printTime: printTime,
),
filter: kReleaseMode ? PermissiveFilter() : DevelopmentFilter(),
output: MultiOutput(multiOutput),
);
} else {
logger = Logger(
printer: PrettyPrinter(
methodCount: 3,
errorMethodCount: 12,
lineLength: 150,
printEmojis: false,
printTime: printTime,
),
filter: kReleaseMode ? PermissiveFilter() : DevelopmentFilter(),
);
}
}
void trace(Object? object, {String? tag, String? flag, Object? error}) {
if (kDebugMode || isLogging) {
logger.t(
_print(
object,
tag: tag ?? _getParentMethodName(),
flag: flag,
),
time: DateTime.now(),
error: error,
);
}
}
void debug(Object? object, {String? tag, String? flag, Object? error}) {
if (kDebugMode || isLogging) {
logger.d(
_print(
object,
tag: tag ?? _getParentMethodName(),
flag: flag,
),
time: DateTime.now(),
error: error,
);
}
}
void info(Object? object, {String? tag, String? flag, Object? error}) {
if (kDebugMode || isLogging) {
logger.i(
_print(
object,
tag: tag ?? _getParentMethodName(),
flag: flag,
),
time: DateTime.now(),
error: error,
);
}
}
void warning(Object? object, {String? tag, String? flag, Object? error}) {
if (kDebugMode || isLogging) {
logger.w(
_print(
object,
tag: tag ?? _getParentMethodName(),
flag: flag,
),
time: DateTime.now(),
error: error,
);
}
}
void error(Object? object, {String? tag, String? flag}) {
if (kDebugMode || isLogging) {
logger.e(
_print(
object,
tag: tag ?? _getParentMethodName(),
flag: flag,
),
time: DateTime.now(),
error: object,
);
}
}
void fatal(Object? object, {String? tag, String? flag, required Object error, StackTrace? stackTrace}) {
if (kDebugMode || isLogging) {
logger.f(
_print(
object,
tag: tag ?? _getParentMethodName(),
flag: flag,
),
time: DateTime.now(),
error: error,
stackTrace: stackTrace,
);
}
}
}
String? _getParentMethodName() {
try {
throw Exception();
} catch (e, stackTrace) {
final frames = stackTrace.toString().split('\n');
var father = "";
var grandfather = "";
try {
final fatherFrame = frames[3];
father = fatherFrame.split(' ').last;
} catch (_) {}
try {
final grandfatherFrame = frames[4];
grandfather = grandfatherFrame.split(' ').last;
} catch (_) {}
return father == "" && grandfather == "" ? null : "$father${grandfather == "" ? grandfather : "\n$grandfather"}\n";
}
}
String _print(Object? object, {String? tag, String? flag}) =>
(tag == null || tag == "") && (flag == null || flag == "")
? object.toString()
: tag != null && tag != "" && flag != null && flag != ""
? "$tag | ${flag.toUpperCase()} | $object"
: (tag == null || tag == "") && flag != null && flag != ""
? "${flag.toUpperCase()} | $object"
: "$tag | $object";
class FileOutput2 extends LogOutput {
final File file;
final bool overrideExisting;
final Encoding encoding;
late IOSink _sink;
FileOutput2({
required this.file,
this.overrideExisting = false,
this.encoding = utf8,
});
@override
Future<void> init() async {
_sink = file.openWrite(
mode: overrideExisting ? FileMode.writeOnly : FileMode.writeOnlyAppend,
encoding: encoding,
);
}
@override
void output(OutputEvent event) {
try {
if (event.origin.level != Level.trace) _sink.writeAll(["${event.origin.level.name} | ${event.origin.time} | ${event.origin.error} \n${event.origin.message} \n\n"], '\n');
} catch (e) {
print(e);
}
}
@override
Future<void> destroy() async {
await _sink.flush();
await _sink.close();
}
}
void myDebugger(Object? object, {String? tag, String? flag, bool when = true}) {
developer.debugger(
when: when,
message: _print(
object,
tag: tag ?? _getParentMethodName(),
flag: flag,
),
);
}
Explanation

Step 3: Initialize Logging in Your App
Step 4: Use Logging Methods
Check Logs on the Device
Last updated
