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 ");
}
複製代碼

相關文章
相關標籤/搜索