flutter开发实战-日志logger写入文件及print_flutter logger-程序员宅基地

技术标签: flutter  flutter开发实战  移动开发  Logger  日志  

flutter开发实战-日志logger写入文件及print

在开发中,需要日志logger写入文件,方便日后查看出现的问题。这里记录之前的实现方案。
使用的日志插件是logger
在这里插入图片描述

一、引入日志插件

在工程中pubspec.yaml引入logger

logger: ^1.4.0

二、代码实现

使用比较简单,只需创建一个Logger实例并开始日志记录:

var logger = Logger();

logger.d("Logger is working!");

也可以传递其他对象,如List、Map或Set,而不是字符串消息。

2.1 日志logger_manager

  • 使用logger时候,配置logger
FileOutput fileOutPut = FileOutput();
    ConsoleOutput consoleOutput = ConsoleOutput();
    List<LogOutput> multiOutput = [fileOutPut, consoleOutput];
    logger = Logger(
      filter: DevelopmentFilter(),
      // Use the default LogFilter (-> only log in debug mode)
      // printer: SimplePrinter(
      //   colors: true,
      //   printTime: true,
      // ),
      printer: HybridPrinter(
        PrettyPrinter(
          noBoxingByDefault: false,
          methodCount: 2,
          // number of method calls to be displayed
          errorMethodCount: 8,
          // number of method calls if stacktrace is provided
          lineLength: 120,
          // width of the output
          colors: true,
          // Colorful log messages
          printEmojis: false,
          // Print an emoji for each log message
          printTime: true, // Should each log print contain a timestamp
        ),
        debug: SimplePrinter(),
      ),
  • 写入文件的FileOutPut,其中用到了IOSink

IOSink可以方便将字节和文本输出,IOSink将字节的StreamSsink与StringSink组合,并且允许容易地输出字节和文本。

/// Writes the log output to a file.
class FileOutput extends LogOutput {
    
  final bool overrideExisting;
  final Encoding encoding;
  IOSink? _sink;

  File? file;
  String? _currentDate;

  FileOutput({
    
    this.overrideExisting = false,
    this.encoding = utf8,
  });

  Future<void> getDirectoryForLogRecord() async {
    
    String currentDate = getCurrentDay();
    if (currentDate != _currentDate) {
    
      final String fileDir = await createDirectory();
      file = File('${
      fileDir}/${
      currentDate}.log');

      _sink = file!.openWrite(
        mode: overrideExisting ? FileMode.writeOnly : FileMode.writeOnlyAppend,
        encoding: encoding,
      );

      _currentDate = currentDate;
    }
  }

  String getCurrentDay() {
    
    String currentDate =
        DateUtil.formatDate(DateTime.now(), format: "yyyyMMdd");
    return currentDate;
  }

  
  void init() {
    
    directoryLogRecord(onCallback: () {
    });
  }

  void directoryLogRecord({
    required Function onCallback}) {
    
    getDirectoryForLogRecord().whenComplete(() {
    
      onCallback();
    });
  }

  
  void output(OutputEvent event) {
    
    directoryLogRecord(onCallback: () {
    
      if (_sink != null) {
    
        if (Level.info == event.level ||
            Level.warning == event.level ||
            Level.error == event.level) {
    
          _sink?.writeAll(event.lines, '\n');
        }
      }
    });
  }

  
  void destroy() async {
    
    await _sink?.flush();
    await _sink?.close();
  }
}
  • 实现使用logger_manager
Future<String> createDirectory() async {
    
  final Directory directory = await getApplicationDocumentsDirectory();
  var file = Directory(directory.path+"/"+"lyd");
  try {
    
    bool exist = await file.exists();
    if (exist == false) {
    
      await file.create();
    }
  } catch(e) {
    
    print("createDirectory error");
  }

  return file.path;
}

class LoggerManager {
    
  //私有构造函数
  LoggerManager._internal() {
    
    deleteLogsOfBefore7Day();
    initLogger();
  }

  //保存单例
  static LoggerManager _singleton = LoggerManager._internal();

  //工厂构造函数
  factory LoggerManager() => _singleton;

  late Logger logger;

  // log初始化设置
  Future<void> initLogger() async {
    
    FileOutput fileOutPut = FileOutput();
    ConsoleOutput consoleOutput = ConsoleOutput();
    List<LogOutput> multiOutput = [fileOutPut, consoleOutput];
    logger = Logger(
      filter: DevelopmentFilter(),
      // Use the default LogFilter (-> only log in debug mode)
      // printer: SimplePrinter(
      //   colors: true,
      //   printTime: true,
      // ),
      printer: HybridPrinter(
        PrettyPrinter(
          noBoxingByDefault: false,
          methodCount: 2,
          // number of method calls to be displayed
          errorMethodCount: 8,
          // number of method calls if stacktrace is provided
          lineLength: 120,
          // width of the output
          colors: true,
          // Colorful log messages
          printEmojis: false,
          // Print an emoji for each log message
          printTime: true, // Should each log print contain a timestamp
        ),
        debug: SimplePrinter(),
      ),

      // printer: PrefixPrinter(PrettyPrinter(
      //   noBoxingByDefault: true,
      //   methodCount: 2,
      //   // number of method calls to be displayed
      //   errorMethodCount: 8,
      //   // number of method calls if stacktrace is provided
      //   lineLength: 120,
      //   // width of the output
      //   colors: true,
      //   // Colorful log messages
      //   printEmojis: false,
      //   // Print an emoji for each log message
      //   printTime: true, // Should each log print contain a timestamp
      // )),

      // printer: PrettyPrinter(
      //   noBoxingByDefault: true,
      //   methodCount: 2,
      //   // number of method calls to be displayed
      //   errorMethodCount: 8,
      //   // number of method calls if stacktrace is provided
      //   lineLength: 120,
      //   // width of the output
      //   colors: true,
      //   // Colorful log messages
      //   printEmojis: false,
      //   // Print an emoji for each log message
      //   printTime: true, // Should each log print contain a timestamp
      // ),
      // Use the PrettyPrinter to format and print log
      output: MultiOutput(
        multiOutput,
      ), // Use the default LogOutput (-> send everything to console)
    );
  }

  // Debug
  void debug(String message) {
    
    logger.d(message);
  }

  // verbose
  void verbose(String message) {
    
    logger.v(message);
  }

  // info
  void info(String message) {
    
    logger.i(message);
  }

  // warning
  void warning(String message) {
    
    logger.w(message);
  }

  // error
  void error(String message) {
    
    logger.e(message);
  }

  // 每次启动只保留7天内的日志,删除7天前的日志
  Future<void> deleteLogsOfBefore7Day() async {
    
    final String fileDir = await createDirectory();

    // 获取目录的所有文件
    var dir = Directory(fileDir);
    Stream<FileSystemEntity> file = dir.list();
    await for (FileSystemEntity x in file) {
    
      // 获取文件的的名称
      List<String> paths = x.path.split('/');
      if (paths.isNotEmpty) {
    
        String logName = paths.last.replaceAll('.log', '');
        final logDate = DateUtil.getDateTime(logName);
        final currentDate = DateTime.now();
        //比较相差的天数
        if (logDate != null) {
    
          final difference = currentDate.difference(logDate!).inDays;
          print("deleteLogsOfBefore7Day logDate:${
      logDate}, currentDate:${
      currentDate}, difference:${
      difference}");
          if (difference > 7) {
    
            var file = File(x.path);
            // 删除文件
            file.delete();
          }
        }
      }
    }
  }
}

2.2 在main.dart初始化logger

// 配置logger
  await LoggerManager().initLogger();

2.3 使用LoggerManager

logger的level定义

enum Level {
    
  verbose,
  debug,
  info,
  warning,
  error,
  wtf,
  nothing,
}

可以在需要的地方使用LoggerManager

// verbose:
LoggerManager().verbose("App started at main.dart");

// debug:
LoggerManager().debug("App started at main.dart");

// info:
LoggerManager().info("App started at main.dart");

// warning:
LoggerManager().warning("App started at main.dart");

// error:
LoggerManager().error("App started at main.dart");

// wtf:
LoggerManager().wtf("App started at main.dart");

// nothing:
LoggerManager().nothing("App started at main.dart");

三、小结

flutter开发实战-日志logger写入文件及print,使用的是logger进行实现,输出日志logger的不同level:verbose、debug、info、warning、error、wtf、nothing。

学习记录,每天不停进步。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/gloryFlow/article/details/131654007

智能推荐

大一新生HTML期末作业个人介绍博客 使用html+css+javascript+jquery技术制作网页,含有动画,hover效果,含有表格布局_jquery网页期末作业-程序员宅基地

文章浏览阅读278次。个人网页设计、‍♂️个人简历制作、简单静态HTML个人网页作品、个人介绍网站模板 、等网站的设计与制作。个人网页设计网站模板采用DIV CSS布局制作,网页作品有多个页面,如 :个人介绍(文字页面)、我的作品(图片列表)、个人技能(图文页面)、在线留言(表单页面)CSS样式方面网页整体采用左右布局结构,制作了网页背景图片,导航区域每个导航背景色不同,导航背景色与页面背景呼应。 一套A+的网页应该包含 (具体可根据个人要求而定)网站布局方面:计划采用目前主流的、能兼容各大......_jquery网页期末作业

地形鞍部提取_提取鞍部点-程序员宅基地

文章浏览阅读4.5k次,点赞9次,收藏36次。1 流程图 利用水文分析提取山脊线及山谷线,山脊线相当于分水线,山谷线相当于山谷线。分水线是水流的起源点,这些栅格的水流方向只存在流出方向而不存在流入方向,所以汇流累积量为零。通过对零值的提取就可以得到山脊线。 山谷线相当于汇水线要用反地形求出,即用较大值减去DEM,DEM中山脊线就成为山谷线,山谷线变为山脊线,用求山脊线的方法求出山谷线,分别利用正反地形求交验证。 DEM进行填洼,利用水文分_提取鞍部点

Ansys中划分的网格导入MATLAB_ansys网格划分结果导出到matlab-程序员宅基地

文章浏览阅读7.8k次。本文的目的是将ANSYS中划分好的单元网格导入到MATLAB中,并显示。方法很简单(对三维实体单元不适用):在ANSYS中建立模型,进行网格划分,用命令"cdwrite,geom,filename,ans"将网格划分结果导出,filename是用户指定的文件名。该命令产生的filename.ans实际上是一个ASCII文本文件,用记事本打开,可以看到其中的数据记录格式,前四行是字符_ansys网格划分结果导出到matlab

boost asio io_context 没任务不退出_error: ‘class std::reference_wrapper<boost::asio::-程序员宅基地

文章浏览阅读694次。boost::asio::io_context ioc;auto work(boost::asio::make_work_guard(ioc)); //没用任务时,run 不退出_error: ‘class std::reference_wrapper’ has no memb

VLSI —— 运算模块设计_平方根进位选择加法器-程序员宅基地

文章浏览阅读2.9k次,点赞4次,收藏14次。二进制加法器1. 基础知识A、B为输入,Ci为进位输入,S为和,Co为进位输出基础的加法器:逐位进位加法器 或 行波进位加法器(ripple carry adder) , 进位路径为关键路径,critical path2. 加法器的反向特性3. 加法器们1. 静态加法器 —— 用互补CMOS2. 镜像加法器3. 传输门型加法器 —— S和Co有相同时间4. Manchester曼切斯特进位链加法器如果P(传播)=1,Ci直接传播到Co。动态实现更加简单,减少了Di_平方根进位选择加法器

PHP 之 微信公众号开发基本结构示例-程序员宅基地

文章浏览阅读302次。为什么80%的码农都做不了架构师?>>> ..._overtrue/wechat

随便推点

Ant Design Charts绘制中国地图并动态添加标记点_antd 地图-程序员宅基地

文章浏览阅读2.8k次。Ant Design Charts绘制中国地图并动态添加标记点_antd 地图

Python 金融量化 RSI相对强弱指标,看这里-程序员宅基地

文章浏览阅读713次,点赞22次,收藏17次。return rsi韦尔斯·威尔德(Wells Wilder)指出,通过运用月周期28天的一半来计算RSI的值进行预测是有效的,他推荐14日为时间跨度。一些常用的看盘软件设有6日RSI,12日RSI,24日RSI三个RSI指标。6日近似一周的时间周期12日近似半个月的时间周期24日近似一个月的时间周期此外也有人用RSI1表示6日相对强度指标,RSI2日表示12日相对强度指标,RSI3表示24日相对强度指标。4. python编写Rsi绘图函数。

最新成果展示:Ga2O3-SBD计算模型_ga2o3簇模型原子个数与闭壳-程序员宅基地

文章浏览阅读436次,点赞2次,收藏2次。近年来,Ga2O3材料凭借着优越的电学与光学特性,愈发引起了研究人员的强烈关注,同时被广泛地应用于各类高功率半导体器件与光电子器件。因此,借助于计算软件对其内部物理机制的研究便显得尤为重要,可帮助研究人员省时、省力、省财地制备高性能的半导体器件。近日,基于Crosslight公司先进的半导体仿真设计平台,我司技术团队不断突破技术瓶颈,完善材料性质及物理模型,创新性地开发出了Ga2O3-SBD计算模型。如上图所示,基于该模型计算输出的结果与实验结果高度吻合,对于SBD器件内部物理机制的研究极具重要的意义。_ga2o3簇模型原子个数与闭壳

JavaWeb Cookie的介绍和使用案例_hanyzz-程序员宅基地

文章浏览阅读184次。Cookie的特点和作用cookie存储数据在客户端浏览器浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20个)作用:3. cookie一般用于存出少量的不太敏感的数据4. 在不登录的情况下,完成服务器对客户端的身份识别案例:记住上一次访问时间1. 需求:5. 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您..._hanyzz

Linux/Windows下的静态库、动态库及.lib转.a文件方法-程序员宅基地

文章浏览阅读6.2k次。Linux的库文件是.a、.so、.o。Windows的库文件是.lib。_.lib转.a

Django笔记三十八之发送邮件_django中mail.send_mail-程序员宅基地

文章浏览阅读679次,点赞2次,收藏3次。这一篇笔记介绍如何在 Django 中发送邮件。在 Python 中,提供了 smtplib 的邮件模块,而 Django 在这个基础上对其进行了封装,我们可以通过来调用。_django中mail.send_mail

推荐文章

热门文章

相关标签