A, think

This is a common feature in iOS development, and can be easily implemented in BOTH OC and Swift because the system already provides pre-processing macros for logging output, which can be concatenated. Dart does not provide this, so how do you implement this?

If you think back to the development process, did you find that if you accidentally threw an exception, you could see something like the following print, and it was clear which file and line of code caused the exception?

So if we can get the current call stack when we call the function, we can get the set of data we want.

Second, the practice

Dart :core provides a StackTrace, which can be used to retrieve the current stack information from stacktrace.current, as shown in the figure below.

Here I use an official package, Stack_trace, that makes the stack information more personal and makes it easier to view the stack information and get the data you want.

ps: stack_traceFlutterThe environment direct guide package can be used while in pureDartYou need to add it to depend onpubspec.yamlIn the.

dependencies:
  stack_trace: ^ 1.9.3
Copy the code

Let’s try stack_trace

import 'package:stack_trace/stack_trace.dart';

// Convert StackTrace to Chain
// You can also use chain.current ();
final chain = Chain.forTrace(StackTrace.current);
// Take out one of the messages
final frames = chain.toTrace().frames;
final frame = frames[1];
/ / print
print("File:${frame.uri}Where the line${frame.line}In the column${frame.column}");

// Print the result
/ / flutter: file: package: flutterlog/main dart in line 55 in column 23
Copy the code

Third, present the code

I have made a little packaging below and can use it directly. The printing effect is as follows:

The complete code and examples can be found on GitHub.

Code:

// log.dart

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

void FLog(dynamic msg, { FLogMode mode = FLogMode.debug }) {
  if (kReleaseMode) { // Release mode does not print
    return;
  }
  var chain = Chain.current(); // Chain.forTrace(StackTrace.current);
  // Add the stack of the core and the flutter package together.
  chain = chain.foldFrames((frame) => frame.isCore || frame.package == "flutter");
  // Retrieve all information frames
  final frames = chain.toTrace().frames;
  // Find the information frame for the current function
  final idx = frames.indexWhere((element) => element.member == "FLog");
  if (idx == - 1 || idx+1 >= frames.length) {
    return;
  }
  // Call the current function information frame
  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 ");
}
Copy the code