flutter开发实战-日志logger写入文件及print
在开发中,需要日志logger写入文件,方便日后查看出现的问题。这里记录之前的实现方案。
使用的日志插件是logger
一、引入日志插件
在工程中pubspec.yaml引入logger
logger: ^1.4.0
二、代码实现
使用比较简单,只需创建一个Logger实例并开始日志记录:
var logger = Logger();logger.d("Logger is working!");
也可以传递其他对象,如List、Map或Set,而不是字符串消息。
2.1 日志logger_manager
- 使用logger时候,配置logger
FileOutput fileOutPut = FileOutput(); ConsoleOutput consoleOutput = ConsoleOutput(); List<LogOutput> multiOutput = [fileOutPut, consoleOutput]; logger = Logger( filter: DevelopmentFilter(), // Use the default LogFilter (-> only log in debug mode) // printer: SimplePrinter( // colors: true, // printTime: true, // ), printer: HybridPrinter( PrettyPrinter( noBoxingByDefault: false, methodCount: 2, // number of method calls to be displayed errorMethodCount: 8, // number of method calls if stacktrace is provided lineLength: 120, // width of the output colors: true, // Colorful log messages printEmojis: false, // Print an emoji for each log message printTime: true, // Should each log print contain a timestamp ), debug: SimplePrinter(), ),
- 写入文件的FileOutPut,其中用到了IOSink
IOSink可以方便将字节和文本输出,IOSink将字节的StreamSsink与StringSink组合,并且允许容易地输出字节和文本。
/// Writes the log output to a file.class FileOutput extends LogOutput { final bool overrideExisting; final Encoding encoding; IOSink? _sink; File? file; String? _currentDate; FileOutput({ this.overrideExisting = false, this.encoding = utf8, }); Future<void> getDirectoryForLogRecord() async { String currentDate = getCurrentDay(); if (currentDate != _currentDate) { final String fileDir = await createDirectory(); file = File('${fileDir}/${currentDate}.log'); _sink = file!.openWrite( mode: overrideExisting ? FileMode.writeOnly : FileMode.writeOnlyAppend, encoding: encoding, ); _currentDate = currentDate; } } String getCurrentDay() { String currentDate = DateUtil.formatDate(DateTime.now(), format: "yyyyMMdd"); return currentDate; } void init() { directoryLogRecord(onCallback: () {}); } void directoryLogRecord({required Function onCallback}) { getDirectoryForLogRecord().whenComplete(() { onCallback(); }); } void output(OutputEvent event) { directoryLogRecord(onCallback: () { if (_sink != null) { if (Level.info == event.level || Level.warning == event.level || Level.error == event.level) { _sink?.writeAll(event.lines, '\n'); } } }); } void destroy() async { await _sink?.flush(); await _sink?.close(); }}
- 实现使用logger_manager
Future<String> createDirectory() async { final Directory directory = await getApplicationDocumentsDirectory(); var file = Directory(directory.path+"/"+"lyd"); try { bool exist = await file.exists(); if (exist == false) { await file.create(); } } catch(e) { print("createDirectory error"); } return file.path;}class LoggerManager { //私有构造函数 LoggerManager._internal() { deleteLogsOfBefore7Day(); initLogger(); } //保存单例 static LoggerManager _singleton = LoggerManager._internal(); //工厂构造函数 factory LoggerManager() => _singleton; late Logger logger; // log初始化设置 Future<void> initLogger() async { FileOutput fileOutPut = FileOutput(); ConsoleOutput consoleOutput = ConsoleOutput(); List<LogOutput> multiOutput = [fileOutPut, consoleOutput]; logger = Logger( filter: DevelopmentFilter(), // Use the default LogFilter (-> only log in debug mode) // printer: SimplePrinter( // colors: true, // printTime: true, // ), printer: HybridPrinter( PrettyPrinter( noBoxingByDefault: false, methodCount: 2, // number of method calls to be displayed errorMethodCount: 8, // number of method calls if stacktrace is provided lineLength: 120, // width of the output colors: true, // Colorful log messages printEmojis: false, // Print an emoji for each log message printTime: true, // Should each log print contain a timestamp ), debug: SimplePrinter(), ), // printer: PrefixPrinter(PrettyPrinter( // noBoxingByDefault: true, // methodCount: 2, // // number of method calls to be displayed // errorMethodCount: 8, // // number of method calls if stacktrace is provided // lineLength: 120, // // width of the output // colors: true, // // Colorful log messages // printEmojis: false, // // Print an emoji for each log message // printTime: true, // Should each log print contain a timestamp // )), // printer: PrettyPrinter( // noBoxingByDefault: true, // methodCount: 2, // // number of method calls to be displayed // errorMethodCount: 8, // // number of method calls if stacktrace is provided // lineLength: 120, // // width of the output // colors: true, // // Colorful log messages // printEmojis: false, // // Print an emoji for each log message // printTime: true, // Should each log print contain a timestamp // ), // Use the PrettyPrinter to format and print log output: MultiOutput( multiOutput, ), // Use the default LogOutput (-> send everything to console) ); } // Debug void debug(String message) { logger.d(message); } // verbose void verbose(String message) { logger.v(message); } // info void info(String message) { logger.i(message); } // warning void warning(String message) { logger.w(message); } // error void error(String message) { logger.e(message); } // 每次启动只保留7天内的日志,删除7天前的日志 Future<void> deleteLogsOfBefore7Day() async { final String fileDir = await createDirectory(); // 获取目录的所有文件 var dir = Directory(fileDir); Stream<FileSystemEntity> file = dir.list(); await for (FileSystemEntity x in file) { // 获取文件的的名称 List<String> paths = x.path.split('/'); if (paths.isNotEmpty) { String logName = paths.last.replaceAll('.log', ''); final logDate = DateUtil.getDateTime(logName); final currentDate = DateTime.now(); //比较相差的天数 if (logDate != null) { final difference = currentDate.difference(logDate!).inDays; print("deleteLogsOfBefore7Day logDate:${logDate}, currentDate:${currentDate}, difference:${difference}"); if (difference > 7) { var file = File(x.path); // 删除文件 file.delete(); } } } } }}
2.2 在main.dart初始化logger
// 配置logger await LoggerManager().initLogger();
2.3 使用LoggerManager
logger的level定义
enum Level { verbose, debug, info, warning, error, wtf, nothing,}
可以在需要的地方使用LoggerManager
// verbose:LoggerManager().verbose("App started at main.dart");// debug:LoggerManager().debug("App started at main.dart");// info:LoggerManager().info("App started at main.dart");// warning:LoggerManager().warning("App started at main.dart");// error:LoggerManager().error("App started at main.dart");// wtf:LoggerManager().wtf("App started at main.dart");// nothing:LoggerManager().nothing("App started at main.dart");
三、小结
flutter开发实战-日志logger写入文件及print,使用的是logger进行实现,输出日志logger的不同level:verbose、debug、info、warning、error、wtf、nothing。
学习记录,每天不停进步。
来源地址:https://blog.csdn.net/gloryFlow/article/details/131654007