flutter开发实战-日志logger写入文件及print

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。

学习记录,每天不停进步。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
Flutter开发实战详解PDF》是一本介绍如何使用Flutter进行实际开发的书籍。Flutter是由谷歌开发的一款跨平台框架,可以用来开发iOS、Android、Web和桌面应用程序。这本书涵盖了从Flutter基础知识到高级开发技巧的各个方面。 《Flutter开发实战详解PDF》首先介绍了Flutter的基本概念和工具,帮助读者快速入门。接着,书中详细讲解了Flutter的布局和UI组件,包括文本、按钮、图片等常用控件的使用方法。读者可以通过学习这些内容,了解如何构建一个漂亮、流畅的用户界面。 在基础知识介绍之后,书中通过实例介绍了如何进行网络请求、与后台进行数据交互。读者可以学习到如何使用Flutter的Http库来进行网络请求,并将获取到的数据展示在应用程序中。此外,书中还介绍了如何使用Flutter与数据库进行交互,以及如何处理用户输入和使用设备传感器。 《Flutter开发实战详解PDF》还提供了一些高级开发技巧和实践经验,例如如何进行状态管理、如何优化性能等。这些内容对于有一定Flutter开发经验的开发者来说尤为重要。 总的来说,这本书通过实例和案例的方式,详细讲解了Flutter开发实践。无论是初学者还是有一定经验的开发者,都可以从中学到很多实用的技巧和知识。如果你想深入学习Flutter开发,这本书是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值