flutter log 自定义log输出,保证你爱上它

小伙伴是否经常打印大一点的json,发现打印log地方,显示不完全 ?很影响调试代码吧;是不是还有其他不满意的地方?! 今天我们就来解决这个问题
首先我们来看一下系统的log输出,测试一下打印一个比较大点的json

 Map map = {
    "success": true,
    "message": "操作成功",
    "data": {
      "total": 7,
      "pageSize": 10,
      "pageNo": 1,
      "datas": [
        {
          "id": "5fe143c5b7ab083856e0e71d",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-01 00:00:00"
        },
        {
          "id": "5fe142f3b7ab083856e0e71b",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-02 00:00:00"
        },
        {
          "id": "5fe14297b7ab083856e0e719",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-03 00:00:00"
        },
        {
          "id": "5fe1423db7ab083856e0e717",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-04 00:00:00"
        },
        {
          "id": "5fe141e1b7ab083856e0e715",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-05 00:00:00"
        },
        {
          "id": "5fe13e97b7ab083856e0e713",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-06 00:00:00"
        },
        {
          "id": "5fe13e77b7ab083856e0e711",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-07 00:00:00"
        },
        {
          "id": "5fe143c5b7ab083856e0e71d",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-08 00:00:00"
        },
        {
          "id": "5fe142f3b7ab083856e0e71b",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-09 00:00:00"
        },
        {
          "id": "5fe14297b7ab083856e0e719",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-10 00:00:00"
        }
      ]
    }
  };

json里面是一个带10个字典的数组--->字典数组;为了方便测试,字典里面的time,对应的值,我调成了不同的日期,方便观看


datas.png

调用系统的print();

  _systemLoggerTestLongText() {
    print("$map");
  }

打印的结果如下


systemLog.png

好啦,我们来diss一下系统的log输出,当前flutter log输出的一些不太方便的地方

第一点, 日志输出时没有带上时间
第二点, 日志输出不支持自定义级别
第三点, 日志输出不支持长文本
...

重点来了,直接上干货,自定义log,完整代码如下
/// DateFormat.
enum DateFormat {
  DEFAULT, //yyyy-MM-dd HH:mm:ss.SSS
  NORMAL, //yyyy-MM-dd HH:mm:ss
  YEAR_MONTH_DAY_HOUR_MINUTE, //yyyy-MM-dd HH:mm
  YEAR_MONTH_DAY, //yyyy-MM-dd
  YEAR_MONTH, //yyyy-MM
  MONTH_DAY, //MM-dd
  MONTH_DAY_HOUR_MINUTE, //MM-dd HH:mm
  HOUR_MINUTE_SECOND, //HH:mm:ss
  HOUR_MINUTE_SECOND_MILLISECOND,//HH时mm分ss秒SSS毫秒
  HOUR_MINUTE, //HH:mm

  ZH_DEFAULT, //yyyy年MM月dd日 HH时mm分ss秒SSS毫秒
  ZH_NORMAL, //yyyy年MM月dd日 HH时mm分ss秒  /  timeSeparate: ":" --> yyyy年MM月dd日 HH:mm:ss
  ZH_YEAR_MONTH_DAY_HOUR_MINUTE, //yyyy年MM月dd日 HH时mm分  /  timeSeparate: ":" --> yyyy年MM月dd日 HH:mm
  ZH_YEAR_MONTH_DAY, //yyyy年MM月dd日
  ZH_YEAR_MONTH, //yyyy年MM月
  ZH_MONTH_DAY, //MM月dd日
  ZH_MONTH_DAY_HOUR_MINUTE, //MM月dd日 HH时mm分  /  timeSeparate: ":" --> MM月dd日 HH:mm
  ZH_HOUR_MINUTE_SECOND, //HH时mm分ss秒
  ZH_HOUR_MINUTE, //HH时mm分
}

class ZZLog {
  static const String _TAG_DEF = "";

  static bool debuggable = false; //是否是debug模式,true: log v 不输出.
  static String TAG = _TAG_DEF;

  static void init({bool isDebug = false, String tag = _TAG_DEF}) {
    debuggable = isDebug;
    TAG = tag;
  }

  static void e(Object object, {String tag}) {
    _printLog(tag, '  e=>', object);
  }

  static void v(Object object, {String tag}) {
    if (debuggable) {
      _printLog(tag, '  v=>', object);
    }
  }

  static void _printLog(String tag, String stag, Object object) {
    String da = object.toString();
    String _tag = (tag == null || tag.isEmpty) ? TAG : tag;
    while (da.isNotEmpty) {
      if (da.length > 512) {
        print("${getNowDateStr()}$_tag $stag${da.substring(0, 512)}");
        da = da.substring(512, da.length);
      } else {
        print("${getNowDateStr()}$_tag $stag $da");
        da = "";
      }
    }
  }

  /// get Now Date Str.(yyyy-MM-dd HH:mm:ss)
  static String getNowDateStr() {
    return getDateStrByDateTime(DateTime.now());
  }

  static String getDateStrByDateTime(DateTime dateTime,
      {DateFormat format = DateFormat.HOUR_MINUTE_SECOND_MILLISECOND,
      String dateSeparate,
      String timeSeparate}) {
    if (dateTime == null) return null;
    String dateStr = dateTime.toString();

    dateStr = formatDateTime(dateStr, format, dateSeparate, timeSeparate);
    return dateStr;
  }

  /// format DateTime.
  /// time            time string.
  /// format          DateFormat type.
  /// dateSeparate    date separate.
  /// timeSeparate    time separate.
  static String formatDateTime(String time, DateFormat format,
      String dateSeparate, String timeSeparate) {
    switch (format) {
      case DateFormat.NORMAL: //yyyy-MM-dd HH:mm:ss
        time = time.substring(0, "yyyy-MM-dd HH:mm:ss".length);
        break;
      case DateFormat.YEAR_MONTH_DAY_HOUR_MINUTE: //yyyy-MM-dd HH:mm
        time = time.substring(0, "yyyy-MM-dd HH:mm".length);
        break;
      case DateFormat.YEAR_MONTH_DAY: //yyyy-MM-dd
        time = time.substring(0, "yyyy-MM-dd".length);
        break;
      case DateFormat.YEAR_MONTH: //yyyy-MM
        time = time.substring(0, "yyyy-MM".length);
        break;
      case DateFormat.MONTH_DAY: //MM-dd
        time = time.substring("yyyy-".length, "yyyy-MM-dd".length);
        break;
      case DateFormat.MONTH_DAY_HOUR_MINUTE: //MM-dd HH:mm
        time = time.substring("yyyy-".length, "yyyy-MM-dd HH:mm".length);
        break;
      case DateFormat.HOUR_MINUTE_SECOND: //HH:mm:ss
        time =
            time.substring("yyyy-MM-dd ".length, "yyyy-MM-dd HH:mm:ss".length);
        break;
      case DateFormat.HOUR_MINUTE: //HH:mm
        time = time.substring("yyyy-MM-dd ".length, "yyyy-MM-dd HH:mm".length);
        break;
      default:
        break;
    }
    time = dateTimeSeparate(time, dateSeparate, timeSeparate);
    return time;
  }


  /// date Time Separate.
  static String dateTimeSeparate(
      String time, String dateSeparate, String timeSeparate) {
    if (dateSeparate != null) {
      time = time.replaceAll("-", dateSeparate);
    }
    if (timeSeparate != null) {
      time = time.replaceAll(":", timeSeparate);
    }
    return time;
  }
}

#####Round 1

现在来调用我们封装好的log工具来输出上面长文本,结果如下:

 _myLoggerTestLongText() {
    ZZLog.e("$map");
  }
log.png

大家看一下,自定义的log,是不是把10个字典都打印出来了!!! 此时应该有掌声.

Round 2

我们再来测试一下,正常的文本输出,测试代码及结果如下图

  _myLoggerTestShortTextTagV() {
    ZZLog.v("v object 1 ");
    ZZLog.v("v object 2 ");

    ZZLog.v("v object 3 ");

    ZZLog.v("v object 4 ");
  }

  _myLoggerTestShortTextTagE() {
    ZZLog.e("e object 1 ");
    ZZLog.e("e object 2 ");

    ZZLog.e("e object 3 ");

    ZZLog.e("e object 4 ");
  }
logShort.png
补充一下,还有些小技巧

**自定义的log还可以 定义在生产环境,与开发环境,可以自由切换
**自定义的log,如果你觉得上面本人的打印格式你不满意,还可以自己去简单改一下代码,就可以生成你满意的格式,

测试的完整代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_app_log_test/zz_log.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _myLoggerTestShortTextTagE();
          _myLoggerTestShortTextTagV();
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  Map map = {
    "success": true,
    "message": "操作成功",
    "data": {
      "total": 7,
      "pageSize": 10,
      "pageNo": 1,
      "datas": [
        {
          "id": "5fe143c5b7ab083856e0e71d",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-01 00:00:00"
        },
        {
          "id": "5fe142f3b7ab083856e0e71b",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-02 00:00:00"
        },
        {
          "id": "5fe14297b7ab083856e0e719",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-03 00:00:00"
        },
        {
          "id": "5fe1423db7ab083856e0e717",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-04 00:00:00"
        },
        {
          "id": "5fe141e1b7ab083856e0e715",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-05 00:00:00"
        },
        {
          "id": "5fe13e97b7ab083856e0e713",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-06 00:00:00"
        },
        {
          "id": "5fe13e77b7ab083856e0e711",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-07 00:00:00"
        },
        {
          "id": "5fe143c5b7ab083856e0e71d",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-08 00:00:00"
        },
        {
          "id": "5fe142f3b7ab083856e0e71b",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-09 00:00:00"
        },
        {
          "id": "5fe14297b7ab083856e0e719",
          "devName": "Sensor-2E9599",
          "roomName": null,
          "statusName": "触发报警",
          "time": "2020-12-10 00:00:00"
        }
      ]
    }
  };
  _myLoggerTestShortTextTagV() {
    ZZLog.v("v object 1 ");
    ZZLog.v("v object 2 ");

    ZZLog.v("v object 3 ");

    ZZLog.v("v object 4 ");
  }

  _myLoggerTestShortTextTagE() {
    ZZLog.e("e object 1 ");
    ZZLog.e("e object 2 ");

    ZZLog.e("e object 3 ");

    ZZLog.e("e object 4 ");
  }

  _myLoggerTestLongText() {
    ZZLog.e("$map");
  }

  _systemLoggerTestLongText() {
    print("$map");
  }
}

结尾

今天的分享先到这里了,后续会分享更多的干货,欢迎点赞,评论,加关注啦,祝君好运!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352

推荐阅读更多精彩内容