Flutter日志记录插件my_logger的使用

发布于 1周前 作者 itying888 来自 Flutter

Flutter日志记录插件my_logger的使用

1. 概述

MyLogger 是一个基于 Flogs 包改进的Flutter日志记录插件,提供了快速且简单的日志解决方案。所有日志都会保存到数据库中,并可以导出为文本文件。

MyLogger 使用Dart编写,日志会保存到Sembast数据库中,可以导出到文档目录并上传到服务器。日志对于开发者分析用户在应用中的活动非常有帮助,尤其是在生产环境中难以调试的问题时。

2. 功能特性

  • 日志级别:支持多种日志级别(DEBUG, TRACE, INFO, WARNING, ERROR, SEVERE, FATAL)
  • 数据库存储:日志保存到Sembast数据库
  • 日志导出:可以将日志导出为文件
  • 日志查询和删除:轻松获取或删除日志
  • 日志过滤:支持按条件过滤日志
  • 自定义时间戳:支持自定义时间戳格式
  • 自定义数据类型:支持记录自定义数据类型
  • 自定义日志格式:支持自定义日志输出格式
  • 加密支持:支持日志加密

3. 使用步骤

3.1 添加依赖

pubspec.yaml 文件中添加 my_logger 依赖:

dependencies:
  my_logger: ^1.0.2
3.2 安装依赖

通过命令行安装依赖:

$ flutter packages get
3.3 导入库

在 Dart 代码中导入 my_logger

import 'package:my_logger/logger.dart';

4. 权限设置

为了确保日志文件能够正确导出到存储目录,需要在项目的 AndroidManifest.xmlInfo.plist 文件中添加相应的权限。

4.1 Android 权限

AndroidManifest.xml 中添加以下权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
4.2 iOS 权限

Info.plist 中添加以下权限:

<key>NSPhotoLibraryAddUsageDescription</key>
<string>MyLogger希望将应用中的照片保存到您的相册</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>MyLogger希望访问您的相册以上传图片到应用</string>

5. 日志记录示例

5.1 初始化配置

在应用启动时初始化 MyLogger 配置:

void _init() {
  var config = MyLogger.config;
  config.isDevelopmentDebuggingEnabled = false; // 禁用开发调试
  config.timestampFormat = TimestampFormat.TIME_FORMAT_FULL_3; // 设置时间戳格式

  MyLogger.applyConfig(config); // 应用配置
}
5.2 记录不同级别的日志

可以通过调用不同的方法来记录不同级别的日志:

MyLogger.trace("My trace log"); 
MyLogger.debug("My debug log");
MyLogger.info("My info log");
MyLogger.warning("My warning log");
MyLogger.error("My error log");
MyLogger.severe("My severe log");
MyLogger.fatal("My fatal log");

// 记录带有异常和堆栈跟踪的日志
MyLogger.log(
  className: "HomePage",
  methodName: "_buildRow1",
  text: "My severe log with exception and stacktrace",
  type: LogLevel.SEVERE, 
  exception: Exception("This is an Exception!"),
  stacktrace: StackTrace.current,
);

// 记录带有自定义数据类型的日志
MyLogger.log(
  className: "HomePage",
  methodName: "_buildRow1",
  text: "My severe log with dataLogType",
  type: LogLevel.SEVERE,
  dataLogType: DataLogType.DEVICE,
);
5.3 获取日志

可以通过不同的方式获取已保存的日志:

// 获取所有日志
MyLogger.logs.getAll().then((logs) => logs.forEach(print));

// 获取最近一小时的日志
MyLogger.logs.getLastHour().then((logs) => logs.forEach(print));

// 按条件过滤日志
MyLogger.logs.getByFilter(
  LogFilter(
    startDateTime: DateTime(2019), 
    endDateTime: DateTime(2020), 
    dataLogsType: [DataLogType.NETWORK],
    logLevels: [LogLevel.ERROR, LogLevel.WARNING],
  ),  
).then((logs) => logs.forEach(print));

// 使用预定义的时间范围过滤日志
MyLogger.logs.getByFilter(LogFilter.last24Hours()).then((logs) => logs.forEach(print));
5.4 删除日志

可以通过不同的方式删除已保存的日志:

// 删除所有日志
MyLogger.logs.deleteAll();

// 删除最近一小时的日志
MyLogger.logs.deleteLastHour();

// 按条件删除日志
MyLogger.logs.deleteByFilter(
  LogFilter(
    startDateTime: DateTime(2019), 
    endDateTime: DateTime(2020), 
    dataLogsType: [DataLogType.NETWORK],
    logLevels: [LogLevel.ERROR, LogLevel.WARNING],
  ),  
);
5.5 导出日志

可以将日志导出为文件:

File fileExport = await MyLogger.logs.export(
  fileName: "export-all-logs",
  exportType: FileType.TXT,
  filter: LogFilter.last24Hours(),
);
print("日志已导出到: $fileExport");
5.6 修改配置

可以根据需要修改 MyLogger 的配置:

LogConfig config = MyLogger.config
  ..outputFormat = "{{level}} {{time}} - {{message}}" // 自定义日志输出格式
  ..dataLogTypeValues = DataLogType.values // 设置可记录的数据类型
  ..encryption = EncryptionType.XXTEA // 设置加密类型
  ..encryptionKey = encryptionKey // 设置加密密钥
  ..timestampFormat = TimestampFormat.DEFAULT; // 设置时间戳格式

MyLogger.applyConfig(config); // 应用配置

6. 完整示例代码

以下是一个完整的示例代码,展示了如何在Flutter应用中使用 MyLogger 插件:

import 'package:flutter/material.dart';
import 'package:my_logger/logger.dart';
import 'package:permission_handler/permission_handler.dart';

void main() {
  _init();
  runApp(MaterialApp(home: HomePage()));
}

_init() {
  var config = MyLogger.config;
  config.isDevelopmentDebuggingEnabled = false;
  config.timestampFormat = TimestampFormat.TIME_FORMAT_FULL_3;

  MyLogger.applyConfig(config);
}

class HomePage extends StatefulWidget {
  [@override](/user/override)
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final Permission _permissionGroup = Permission.storage;

  [@override](/user/override)
  void initState() {
    super.initState();
    requestPermission(_permissionGroup);
  }

  _showLogs() => Navigator.push(
        context,
        MaterialPageRoute(
          builder: (_) => Scaffold(
            appBar: AppBar(
              title: Text("日志列表"),
              centerTitle: true,
            ),
            body: LogsWidget(),
          ),
        ),
      );

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("MyLogger 示例"),
        centerTitle: true,
        actions: [IconButton(onPressed: _showLogs, icon: Icon(Icons.list_alt))],
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _buildRow1(context),
            SizedBox(height: 8),
            _buildRow2(),
            SizedBox(height: 8),
            _buildRow3(),
            SizedBox(height: 8),
            _buildRow4(),
          ],
        ),
      ),
    );
  }

  _buildRow1(BuildContext context) {
    return Row(
      children: <Widget>[
        _buildButton("记录事件", () {
          logInfo();
          logException();
          logWarning();
          logTrace();
        }),
        Padding(padding: EdgeInsets.symmetric(horizontal: 5.0)),
        _buildButton("打印所有日志", () async {
          print("\n打印所有日志:");
          MyLogger.logs.getAll().then((logs) => logs.forEach(print));
        }),
      ],
    );
  }

  _buildRow2() {
    return Row(
      children: <Widget>[
        _buildButton("导出日志", () async {
          final exportedFile = await MyLogger.logs.export();
          print("日志已导出到: $exportedFile");
        }),
        Padding(padding: EdgeInsets.symmetric(horizontal: 5.0)),
        _buildButton("清除日志", () {
          MyLogger.logs.deleteAll();
        }),
      ],
    );
  }

  _buildRow3() {
    return Row(
      children: <Widget>[
        _buildButton("打印最近一小时日志", () async {
          print("\n打印最近一小时日志:");
          MyLogger.logs.getLastHour().then((logs) => logs.forEach(print));
        }),
        Padding(padding: EdgeInsets.symmetric(horizontal: 5.0)),
        _buildButton("打印最近10分钟日志", () async {
          print("\n打印最近10分钟日志:");
          final dateTime = DateTime.now().subtract(Duration(minutes: 10));
          final filter = LogFilter(startDateTime: dateTime);
          MyLogger.logs.getByFilter(filter).then((logs) => logs.forEach(print));
        }),
      ],
    );
  }

  _buildRow4() {
    return Row(
      children: <Widget>[
        _buildButton("记录带有堆栈跟踪的事件", () {
          MyLogger.error(
            "我的日志",
            dataLogType: DataLogType.DEVICE,
            className: "Home",
            exception: Exception("异常和堆栈跟踪"),
            stacktrace: StackTrace.current,
          );
        }),
        Padding(padding: EdgeInsets.symmetric(horizontal: 5.0)),
        _buildButton("删除超过10分钟的日志", () {
          final dateTime = DateTime.now().subtract(Duration(minutes: 10));
          final filter = LogFilter(endDateTime: dateTime);
          MyLogger.logs.deleteByFilter(filter).then((_) => print("已删除"));
        }),
      ],
    );
  }

  _buildButton(String title, VoidCallback onPressed) {
    return Expanded(
      child: SizedBox(
        height: 60,
        child: ElevatedButton(
          onPressed: onPressed,
          child: Text(title),
        ),
      ),
    );
  }

  // 通用方法 -----------------------------------------------------------
  void logInfo() {
    MyLogger.log(
      className: "HomePage",
      methodName: "_buildRow1",
      text: "日志描述",
      type: LogLevel.INFO,
      dataLogType: DataLogType.DEVICE,
    );

    MyLogger.config..activeLogLevel = LogLevel.DEBUG;
    MyLogger.info('日志级别设置为: ${MyLogger.config.activeLogLevel}.');
  }

  void logException() {
    try {
      var result = 9 ~/ 0;
      print(result);
    } on Exception catch (exception) {
      MyLogger.error(
        "异常描述",
        dataLogType: DataLogType.ERRORS,
        className: "Home",
        exception: exception,
      );
    }
  }

  void logWarning() {
    MyLogger.warning(
      "日志描述",
      className: "HomePage",
      methodName: "_buildRow1",
      dataLogType: DataLogType.DEFAULT,
    );
  }

  void logTrace() {
    MyLogger.trace(
      "日志描述",
      className: "HomePage",
      methodName: "_buildRow1",
      dataLogType: DataLogType.DEFAULT,
    );
  }

  // 权限相关方法 ---------------------------------------------------------
  Future<void> requestPermission(Permission permission) => permission.request();
}

更多关于Flutter日志记录插件my_logger的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter日志记录插件my_logger的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用my_logger插件进行日志记录的代码案例。my_logger是一个轻量级的日志记录库,它允许你在Flutter应用中轻松地记录日志信息。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加my_logger依赖:

dependencies:
  flutter:
    sdk: flutter
  my_logger: ^2.0.0  # 请确保使用最新版本

然后,运行flutter pub get来安装依赖。

2. 初始化Logger

在你的应用入口文件(通常是main.dart)中初始化Logger。

import 'package:flutter/material.dart';
import 'package:my_logger/my_logger.dart';

void main() {
  // 初始化Logger,设置日志级别
  var logger = Logger(
    printToConsole: true, // 是否打印到控制台
    logFile: 'app_log.txt', // 日志文件名
    maxLogFileSize: 1024 * 1024, // 日志文件最大大小(字节)
    level: LogLevel.verbose, // 日志级别
  );

  // 设置全局Logger
  Log.logger = logger;

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Logger Demo'),
        ),
        body: Center(
          child: MyHomePage(),
        ),
      ),
    );
  }
}

3. 使用Logger记录日志

现在,你可以在你的应用中的任何地方使用Log对象来记录日志。

import 'package:flutter/material.dart';
import 'package:my_logger/my_logger.dart';

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        ElevatedButton(
          onPressed: () {
            Log.verbose('This is a verbose log message.');
            Log.debug('This is a debug log message.');
            Log.info('This is an info log message.');
            Log.warning('This is a warning log message.');
            Log.error('This is an error log message.');
          },
          child: Text('Log Messages'),
        ),
      ],
    );
  }
}

4. 日志输出

当你点击按钮时,日志信息会根据你设置的日志级别输出到控制台,并且如果启用了日志文件,它们也会被写入到指定的日志文件中。

5. 自定义日志格式(可选)

如果你需要自定义日志格式,你可以通过实现LogFormatter接口来自定义。例如:

class CustomLogFormatter implements LogFormatter {
  @override
  String format(LogRecord record) {
    return '${record.level.name} - ${record.time}: ${record.message}';
  }
}

然后在初始化Logger时使用这个自定义格式化器:

var logger = Logger(
  printToConsole: true,
  logFile: 'app_log.txt',
  maxLogFileSize: 1024 * 1024,
  level: LogLevel.verbose,
  formatter: CustomLogFormatter(),
);

这样,你的日志输出就会按照你自定义的格式来显示。

以上就是在Flutter项目中使用my_logger插件进行日志记录的基本步骤和代码案例。希望这对你有所帮助!

回到顶部