Flutter日志管理插件f_logs的使用

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

Flutter日志管理插件f_logs的使用

简介

banner

FLog 是一个高级的日志管理框架,专为 Flutter 开发者设计。它提供了快速且简单的日志解决方案,所有日志都会保存到数据库中,并可以导出为 ZIP 文件。

概述

FLogs 是用 Dart 编写的,主要包含两种类型的日志记录器(FLogDataLog),并具有许多高级功能。日志保存在数据库中,可以导出到 Android 或 iOS 设备的文档目录。这些日志有助于开发者分析用户在应用中的活动。日志可以轻松过滤和排序,并可以按过滤类型导出为 ZIP 文件,然后上传到服务器或本地使用。

很多时候,我们需要记录一组数据来分析某些活动,例如位置(GPS 坐标)、设备信息、网络请求等。这有助于我们快速识别和修复生产环境中难以调试的问题。FLogs 提供了将数据集记录到数据库的功能。这些日志可以通过应用不同的方便过滤器来获取。

特性

  • 每小时创建单独的日志文件(24 小时)
  • 可以按时间和日期过滤压缩和导出日志文件
  • 清除日志
  • 保存日志到自定义路径(仅支持 Android)
  • 导出日志到自定义路径作为 ZIP 文件(仅支持 Android)
  • 自定义日志格式
  • CSV 支持
  • 自定义时间戳支持
  • 自定义数据记录支持(使用 DataLogs 记录器)
  • 加密支持
  • 多目录结构
  • 以字符串形式打印日志
  • 导出所有或单个类型的日志
  • 高级自动化删除日志
  • 导出 HTML 格式的异常
  • 日志级别支持

使用方法

1. 依赖于它

在你的 pubspec.yaml 文件中添加以下依赖:

dependencies:
  f_logs: ^1.0.x

2. 安装它

你可以通过命令行安装包:

$ flutter packages get

或者,你的编辑器可能支持 flutter packages get,请查阅编辑器的文档以了解更多信息。

3. 导入它

现在,在你的 Dart 代码中可以使用:

import 'package:f_logs/f_logs.dart';

如何使用

日志文件会导出到存储目录,因此首先需要在项目的清单文件中添加以下权限:

Android

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

iOS

<key>NSPhotoLibraryAddUsageDescription</key>
<string>FLogs would like to save photos from the app to your gallery</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>FLogs would like to access your photo gallery for uploading images to the app</string>

要保存日志,只需调用以下方法之一:

1. 简单的 Trace 日志

FLog.trace(
  className: "HomePage",
  methodName: "_buildRow1",
  text: "My log",
);

2. 简单的 Debug 日志

FLog.debug(
  className: "HomePage",
  methodName: "_buildRow1",
  text: "My log",
);

3. 简单的 Info 日志

FLog.info(
  className: "HomePage",
  methodName: "_buildRow1",
  text: "My log",
);

4. 简单的 Warning 日志

FLog.warning(
  className: "HomePage",
  methodName: "_buildRow1",
  text: "My log",
);

5. 简单的 Error 日志

FLog.error(
  className: "HomePage",
  methodName: "_buildRow1",
  text: "My log",
);

6. 简单的 Severe 日志

FLog.severe(
  className: "HomePage",
  methodName: "_buildRow1",
  text: "My log",
);

7. Severe 日志带异常和堆栈跟踪

FLog.logThis(
  className: "HomePage",
  methodName: "_buildRow1",
  text: "My log",
  type: LogLevel.SEVERE, 
  exception: Exception("This is an Exception!"),
  stacktrace: StackTrace.current,
);

8. 简单的 Fatal 日志

FLog.fatal(
  className: "HomePage",
  methodName: "_buildRow1",
  text: "My log",
);

9. 数据类型日志

FLog.logThis(
  className: "HomePage",
  methodName: "_buildRow1",
  text: "My log",
  type: LogLevel.SEVERE,
  dataLogType: DataLogType.DEVICE.toString(),
);

可用的方法

1. logThis

static logThis({
  String className,
  String methodName,
  @required String text,
  @required LogLevel type,
  Exception exception,
  String dataLogType,
  StackTrace stacktrace,
}) {}

2. trace

static trace({
  String className,
  String methodName,
  @required String text,
  Exception exception,
  String dataLogType,
  StackTrace stacktrace,
}) {}

3. debug

static debug({
  String className,
  String methodName,
  @required String text,
  Exception exception,
  String dataLogType,
  StackTrace stacktrace,
}) {}

4. info

static info({
  String className,
  String methodName,
  @required String text,
  Exception exception,
  String dataLogType,
  StackTrace stacktrace,
}) {}

5. warning

static warning({
  String className,
  String methodName,
  @required String text,
  Exception exception,
  String dataLogType,
  StackTrace stacktrace,
}) {}

6. error

static error({
  String className,
  String methodName,
  @required String text,
  Exception exception,
  String dataLogType,
  StackTrace stacktrace,
}) {}

7. severe

static severe({
  String className,
  String methodName,
  @required String text,
  Exception exception,
  String dataLogType,
  StackTrace stacktrace,
}) {}

8. fatal

static fatal({
  String className,
  String methodName,
  @required String text,
  Exception exception,
  String dataLogType,
  StackTrace stacktrace,
}) {}

9. printLogs

static printLogs() async {}

10. getAllLogsByCustomFilter

List<Filter> filters = [Filter.greaterThan('[FieldName]', '[Value]')]

static Future<List<Log>> getAllLogsByCustomFilter(
  {List<Filter> filters}
) async {}

11. getAllLogsByFilter

static Future<List<Log>> getAllLogsByFilter(
  {List<String> dataLogsType,
  List<String> logLevels,
  int startTimeInMillis,
  int endTimeInMillis,
  FilterType filterType}
) async {}

12. getAllLogs

static Future<List<Log>> getAllLogs() async {}

13. exportLogs

static exportLogs() async {}

14. clearLogs

static clearLogs() {}

15. applyConfigurations

static applyConfigurations(LogsConfig config) {}

16. deleteAllLogsByFilter

List<Filter> filters = [Filter.greaterThan('[FieldName]', '[Value]')]

static deleteAllLogsByFilter(
  {List<Filter> filters}
) async {}

Wiki

更多详细信息请查阅 wiki

示例代码

import 'package:f_logs/f_logs.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:sembast/sembast.dart';

void main() {
  init();
  runApp(HomePage());
}

init() {
  /// 配置示例 1
//  LogsConfig config = LogsConfig()
//    ..isDebuggable = true
//    ..isDevelopmentDebuggingEnabled = true
//    ..customClosingDivider = "|"
//    ..customOpeningDivider = "|"
//    ..csvDelimiter = ", "
//    ..isLogsEnabled = true
//    ..encryptionEnabled = false
//    ..encryptionKey = "123"
//    ..formatType = FormatType.FORMAT_CURLY
//    ..logLevelsEnabled = [LogLevel.INFO, LogLevel.ERROR]
//    ..dataLogTypes = [
//      DataLogType.DEVICE.toString(),
//      DataLogType.NETWORK.toString(),
//      "Zubair"
//    ]
//    ..stackTraceFormatter = CustomFormatter.formatStackTrace
//    ..timestampFormat = TimestampFormat.TIME_FORMAT_FULL_1;

  /// 配置示例 2
//  LogsConfig config = FLog.getDefaultConfigurations()
//    ..isDevelopmentDebuggingEnabled = true
//    ..timestampFormat = TimestampFormat.TIME_FORMAT_FULL_2;

  /// 配置示例 3 自定义格式
  LogsConfig config = FLog.getDefaultConfigurations()
    ..isDevelopmentDebuggingEnabled = true
    ..timestampFormat = TimestampFormat.TIME_FORMAT_FULL_3
    ..formatType = FormatType.FORMAT_CUSTOM
    ..fieldOrderFormatCustom = [
      FieldName.TIMESTAMP,
      FieldName.LOG_LEVEL,
      FieldName.CLASSNAME,
      FieldName.METHOD_NAME,
      FieldName.TEXT,
      FieldName.EXCEPTION,
      FieldName.STACKTRACE
    ]
    ..customOpeningDivider = "{"
    ..customClosingDivider = "}";

  FLog.applyConfigurations(config);
}

class CustomFormatter {
  static String formatStackTrace(StackTrace stackTrace) {
    // 你可以在这里处理堆栈跟踪并返回你自己的自定义字符串
    // 作为一个例子,这里返回默认的堆栈跟踪
    return stackTrace.toString();
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // 运行时权限
  final Permission _permissionGroup = Permission.storage;

  @override
  void initState() {
    super.initState();
    requestPermission(_permissionGroup);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              _buildTextField(),
              _buildRow1(context),
              _buildRow2(),
              _buildRow3(),
              _buildRow4(),
            ],
          ),
        ),
      ),
    );
  }

  _buildTextField() {
    return CircularProgressIndicator();
//    return TextFormField(
//      decoration: InputDecoration(hintText: "Enter text"),
//    );
  }

  _buildRow1(BuildContext context) {
    return Row(
      children: <Widget>[
        _buildButton("Log Event", () {
          logInfo();
          logException();
          logError();
          logWarning();
          logTrace();
        }),
        Padding(padding: EdgeInsets.symmetric(horizontal: 5.0)),
        _buildButton("Print Logs", () {
          FLog.printLogs();
        }),
      ],
    );
  }

  _buildRow2() {
    return Row(
      children: <Widget>[
        _buildButton("Export Logs", () {
          FLog.exportLogs();
        }),
        Padding(padding: EdgeInsets.symmetric(horizontal: 5.0)),
        _buildButton("Clear Logs", () {
          FLog.clearLogs();
        }),
      ],
    );
  }

  _buildRow3() {
    return Row(
      children: <Widget>[
        _buildButton("Print File Logs", () {
          FLog.printFileLogs();
        }),
        Padding(padding: EdgeInsets.symmetric(horizontal: 5.0)),
        _buildButton("Print Data Logs", () {
          FLog.printDataLogs(
            dataLogsType: [
              DataLogType.DEVICE.toString(),
              "Zubair",
              "Jawad"
            ],
            logLevels: [
              LogLevel.ERROR.toString(),
              LogLevel.WARNING.toString()
            ],
            filterType: FilterType.WEEK
//            startTimeInMillis: 1556132400000,
//            endTimeInMillis: 1556650800000,
          );
        }),
      ],
    );
  }

  _buildRow4() {
    return Row(
      children: <Widget>[
        _buildButton("Log Event with StackTrace", () {
          FLog.error(
            text: "My log",
            dataLogType: "Zubair",
            className: "Home",
            exception: Exception("Exception and StackTrace"),
            stacktrace: StackTrace.current,
          );
        }),
        Padding(padding: EdgeInsets.symmetric(horizontal: 5.0)),
        _buildButton("Delete Logs by Filter (older than 10 seconds)", () {
          FLog.deleteAllLogsByFilter(
            filters: [
              Filter.lessThan(DBConstants.FIELD_TIME_IN_MILLIS,
                  DateTime.now().millisecondsSinceEpoch - 1000 * 10)
            ]
          );
        }),
      ],
    );
  }

  _buildButton(String title, VoidCallback onPressed) {
    return Expanded(
      child: MaterialButton(
        onPressed: onPressed,
        child: Text(title),
        textColor: Colors.white,
        color: Colors.blueAccent,
      ),
    );
  }

  // 通用方法 -----------------------------------------------------------
  void logInfo() {
    FLog.info(
      text: 'LogLevel set to: ${FLog.getDefaultConfigurations().activeLogLevel}.'
    );
  }

  void logException() {
    try {
      var result = 9 ~/ 0;
      print(result);
    } on Exception catch (exception) {
      FLog.error(
        text: "Exception text/description goes here",
        dataLogType: "Exception (the type could be anything)",
        className: "Home",
        exception: exception,
      );
    }
  }

  void logError() {
    try {
      var string = "Zubair";
      var index = string[-1];
      debugPrint(index.toString());
    } on Error catch (error) {
      FLog.error(
        text: "Error text/description goes here",
        dataLogType: "Error (the type could be anything)",
        className: "Home",
        exception: error,
      );
    }
  }

  void logWarning() {
    FLog.warning(
      className: "HomePage",
      methodName: "_buildRow1",
      text: "Log text/description goes here",
      dataLogType: "Warning (the type could be anything)",
    );
  }

  void logTrace() {
    FLog.trace(
      className: "HomePage",
      methodName: "_buildRow1",
      text: "Log text/description goes here",
      dataLogType: "Trace (the type could be anything)",
    );
  }

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

以上是一个完整的示例,展示了如何在 Flutter 应用中使用 f_logs 插件进行日志记录和管理。希望对你有所帮助!


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

1 回复

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


当然,以下是一个关于如何在Flutter项目中使用f_logs插件来进行日志管理的示例代码。f_logs是一个用于Flutter的日志管理插件,它允许你记录、过滤和输出日志信息,以便于调试和监控应用。

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

dependencies:
  flutter:
    sdk: flutter
  f_logs: ^最新版本号  # 请替换为实际发布的最新版本号

然后运行flutter pub get来获取依赖。

接下来,你可以在你的Flutter项目中配置和使用f_logs。以下是一个简单的示例,展示了如何初始化日志管理器、设置日志级别,并记录不同级别的日志信息。

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

void main() {
  // 初始化日志管理器
  Logs.instance
    ..init(
      // 设置日志输出级别(例如:DEBUG, INFO, WARN, ERROR)
      level: LogLevel.DEBUG,
      // 可选:设置日志文件路径(在生产环境中,你可能想要记录日志到文件)
      // logFilePath: '/path/to/logfile.log',
      // 可选:设置日志输出格式
      logFormatter: (log) => '${log.timestamp} [${log.level}] ${log.message}',
    )
    ..addOutput(ConsoleLogOutput()); // 将日志输出到控制台

  // 记录一些日志信息
  Logs.instance.d('这是一条调试信息');
  Logs.instance.i('这是一条信息日志');
  Logs.instance.w('这是一条警告日志');
  Logs.instance.e('这是一条错误日志');

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter 日志管理示例'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              // 在按钮点击时记录一条日志
              Logs.instance.i('按钮被点击了');
            },
            child: Text('点击我'),
          ),
        ),
      ),
    );
  }
}

在这个示例中,我们完成了以下步骤:

  1. 初始化日志管理器:通过调用Logs.instance.init()方法,并传递一个配置对象来初始化日志管理器。你可以设置日志级别、日志文件路径和日志输出格式。

  2. 添加日志输出:通过调用Logs.instance.addOutput()方法,并传递一个日志输出对象(例如ConsoleLogOutput()),来指定日志的输出目标。在这个例子中,我们将日志输出到控制台。

  3. 记录日志信息:通过调用Logs.instance.d()Logs.instance.i()Logs.instance.w()Logs.instance.e()方法来记录不同级别的日志信息。

  4. 在Flutter应用中展示:创建了一个简单的Flutter应用,其中包含一个按钮。当按钮被点击时,会记录一条信息日志。

请注意,f_logs插件提供了更多的配置选项和功能,例如将日志输出到文件、远程服务器等。你可以根据实际需求进行进一步的配置和使用。详细的信息可以参考f_logs的官方文档或GitHub仓库。

回到顶部