Dart 日志封装

参考了 logger 和我之前的经验写了份简单易用的 Dart 日志,大家有需要的可以拿走。

先说下 logger 中存在的坑:

  • iOS 日志不支持五颜六色的颜色,会出现乱码,Android 正常;
  • 长日志的分割没有做的很好;
  • String 格式的 json 串没做格式化输出;

对于这几个问题,我这边五颜六色没有进行支持;长日志在对 LogCallback 继承的时候可设置 splitLen; String 格式的 json 串有做美化,以下便是源码,大家可以参考下:

```dart
import 'dart:convert';
import 'dart:developer' as dev;
import 'dart:math';

import 'package:intl/intl.dart';

enum LogLevel {
debug,
info,
warn,
error,
}

typedef ShouldLog = bool Function(LogLevel logLevel, String tag, dynamic msg);

class DLog {
static LogCallback _logCallback;
static LogDecorator _logDecorator;
static ShouldLog _shouldLog;
static bool _showStack;

static void init(
{LogCallback logCallback,
LogDecorator logDecorator,
ShouldLog shouldLog,
bool showStack = true}) {
_logCallback = logCallback ??= ConsoleLogCallback();
_logDecorator = logDecorator ??= BorderLogDecorator();
_shouldLog = shouldLog;
_showStack = showStack;
}

static void d(String tag, dynamic msg, {int stackStartIndex, int stackMaxFrames}) {
_print(LogLevel.debug, msg,
tag: tag, stackStartIndex: stackStartIndex, stackMaxFrames: stackMaxFrames);
}

static void i(String tag, dynamic msg, {int stackStartIndex, int stackMaxFrames}) {
_print(LogLevel.info, msg,
tag: tag, stackStartIndex: stackStartIndex, stackMaxFrames: stackMaxFrames);
}

static void w(String tag, dynamic msg, {int stackStartIndex, int stackMaxFrames}) {
_print(LogLevel.warn, msg,
tag: tag, stackStartIndex: stackStartIndex, stackMaxFrames: stackMaxFrames);
}

static void e(String tag, dynamic msg, {int stackStartIndex, int stackMaxFrames}) {
_print(LogLevel.error, msg,
tag: tag, stackStartIndex: stackStartIndex, stackMaxFrames: stackMaxFrames);
}

static void _print(LogLevel level, dynamic msg,
{String tag, int stackStartIndex, int stackMaxFrames}) {
if (_shouldLog != null && !_shouldLog(level, tag, msg)) {
return;
}
final realTag = _getSafeTag(tag);
final stack = _showStack ? _getStack(stackStartIndex, stackMaxFrames) : [];
final decorMsg = _logDecorator.decorate(level, realTag, stack, _getFormattedMsg(msg));
_logCallback?._log(level, realTag, decorMsg);
}
}

class BorderLogDecorator extends LogDecorator {
static const String topBorder =
'┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────';
static const String midBorder =
'├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄';
static const String botBorder =
'└────────────────────────────────────────────────────────────────────────────────────────────────────────────────';
static const String leftBorder = "│ ";

final bool showStack;

BorderLogDecorator({this.showStack = true});

@override
String decorate(LogLevel level, String tag, List stack, String msg) {
final flag = _logLevelFlag[level];
final time = _getNowTimeFormat();
final sb = StringBuffer('\n');
sb.writeln(topBorder);
sb.writeln('$leftBorder${flag.emoji} $time ${flag.str}/$tag');
if (showStack && stack.isNotEmpty) {
sb.writeln(_stack2Str(stack, true));
}
sb.writeln(midBorder);
final lines = msg.split('\n');
for (final line in lines) {
sb.writeln(leftBorder + line);
}
sb.write(botBorder);
return sb.toString();
}
}

class SimpleLogDecorator extends LogDecorator {
final bool showStack;
final int maxLen;

SimpleLogDecorator({this.showStack = true, this.maxLen = -1});

@override
String decorate(LogLevel level, String tag, List stack, String msg) {
final flag = _logLevelFlag[level];
final time = _getNowTimeFormat();
if (showStack && stack.isNotEmpty) {
if (stack.length == 1) {
return '${flag.emoji} $time ${_stack2Str(stack, false)} ${flag.str}/$tag: $msg';
} else {
return '${flag.emoji} $time \n${_stack2Str(stack, false)}\n${flag.str}/$tag: $msg';
}
}
return '${flag.emoji} $time ${flag.str}/$tag: $msg';
}
}

class ConsoleLogCallback extends LogCallback {
@override

top Created with Sketch.