Flutter - 打印好用的Debug日志

1、思考

iOS 开发时这个功能很经常使用, 在 OCSwift 中均可以很轻松实现,由于系统原本就提供了用于日志输出的预处理宏,只要咱们拿来拼接就能够了,可是在 Dart 中并不提供这些,那有什么办法实现它呢?git

咱们回想在开发过程当中,是否是发现只要一不当心抛异常,就能够看到相似以下的打印内容,并且还能清楚的知道异常是在哪一个文件和哪一行的代码形成的。 github

因此若是咱们能够在调用函数时拿到当前调用堆栈,就能够取到一系列想要的数据。函数

2、实践

dart:core 中提供了 堆栈跟踪(StackTrace),能够经过 StackTrace.current 取到当前的堆栈信息,打印以下图所示,会发现这很差拿到咱们想要的信息。ui

这里我用到了官方开发的一个包 stack_trace,它能够将堆栈信息变得更多人性化,并方便咱们查看堆栈信息和获取想要的数据。spa

ps: stack_traceFlutter 环境下直接导包便可使用,而在纯 Dart 下须要将其添加为依赖于pubspec.yaml中。debug

dependencies:
 stack_trace: ^1.9.3
复制代码

那下面咱们来试试 stack_trace 的威力吧3d

import 'package:stack_trace/stack_trace.dart';

// 将 StackTrace 对象转换成 Chain 对象
// 固然,这里也能够直接用 Chain.current();
final chain = Chain.forTrace(StackTrace.current);
// 拿出其中一条信息
final frames = chain.toTrace().frames;
final frame = frames[1];
// 打印
print("所在文件:${frame.uri} 所在行 ${frame.line} 所在列 ${frame.column}");

// 打印结果
// flutter: 所在文件:package:flutterlog/main.dart 所在行 55 所在列 23
复制代码

3、呈上代码

下面我作了一点封装,直接拿走便可使用,打印效果以下所示:日志

完整的代码和示例请到GitHub上【查看】code

打印效果

代码:cdn

// log.dart

enum FLogMode {
  debug,    // 💚 DEBUG
  warning,  // 💛 WARNING
  info,     // 💙 INFO
  error,    // ❤️ ERROR
}

void FLog(dynamic msg, { FLogMode mode = FLogMode.debug }) {
  if (kReleaseMode) { // release模式不打印
    return;
  }
  var chain = Chain.current(); // Chain.forTrace(StackTrace.current);
  // 将 core 和 flutter 包的堆栈合起来(即相关数据只剩其中一条)
  chain = chain.foldFrames((frame) => frame.isCore || frame.package == "flutter");
  // 取出全部信息帧
  final frames = chain.toTrace().frames;
  // 找到当前函数的信息帧
  final idx = frames.indexWhere((element) => element.member == "FLog");
  if (idx == -1 || idx+1 >= frames.length) {
    return;
  }
  // 调用当前函数的函数信息帧
  final frame = frames[idx+1];

  var modeStr = "";
  switch(mode) {
    case FLogMode.debug:
      modeStr = "💚 DEBUG";
      break;
    case FLogMode.warning:
      modeStr = "💛 WARNING";
      break;
    case FLogMode.info:
      modeStr = "💙 INFO";
      break;
    case FLogMode.error:
      modeStr = "❤️ ERROR";
      break;
  }

  print("$modeStr ${frame.uri.toString().split("/").last}(${frame.line}) - $msg ");
}
复制代码

相关文章
相关标签/搜索