Flutter日志追踪插件log_tracking的使用

Flutter日志追踪插件log_tracking的使用

Log Tracking 是一个用于管理和存储项目中使用的日志的库。它能够记录你的日志并将其同步到自己的服务器。此库可以与流行的日志库(如 Firebase Crashlytics 和 Sentry)一起工作,使应用程序的日志处理过程更加简单有效。通过 Log Tracking,你可以详细监控应用程序中的错误和事件,立即响应,并将日志数据收集到中央服务器。其易用性和灵活性为应用开发者提供了强大的日志解决方案。

如果服务器提交功能处于激活状态,Log Tracking 在没有互联网连接时会将日志存储在设备的本地数据库中。这一特性允许你的应用程序即使在离线状态下也能继续记录日志,并且一旦恢复网络连接,就会将累积的日志同步到服务器。

开始使用

1. 添加依赖到pubspec.yaml

dependencies:
  log_tracking: ^0.3.6

2. 初始化log_tracking

我们初始化我们的日志库如下:

如果你想要将日志集成到像 Firebase Crashlytics 这样的日志结构中,我们可以使用以下结构。

import 'package:log_tracking/log_tracking.dart';
///...

Future<void> initializeLog() {
  return Log.init(
      saveToLocal: true,
      onInfo: (log) {
        /// 如果你想要将日志集成到 FirebaseCrashlytics 中,可以这样做
        // FirebaseCrashlytics.instance.log("INFO:  ${log.text ?? ""}");
      },
      onWarning: (log) {
        /// 如果你想要将日志集成到 FirebaseCrashlytics 中,可以这样做
        // FirebaseCrashlytics.instance.recordFlutterError(
        //   FlutterErrorDetails(
        //     exception: "WARNING:  ${log.text}",
        //     stack: log.stackTrace,
        //   ),
        //   fatal: false,
        // );
      },
      onError: (log) {
        /// 如果你想要将日志集成到 FirebaseCrashlytics 中,可以这样做
        // FirebaseCrashlytics.instance.recordFlutterError(
        //   FlutterErrorDetails(exception: log.error, stack: log.stackTrace),
        //   fatal: true,
        // );
      },
      onDebug: (log) {
        /// 如果你需要处理调试日志
      },
      onSendToServer: (LogInfoRequest request) async {
        /// 如果你想要将日志发送到自己的服务器,可以使用此方法。
        /// 当捕获到错误日志时调用此方法。
        /// 错误日志之前的信息和警告日志也会作为列表出现。
        bool isSuccess = await postLogs(request);
        return isSuccess;
      });
}

/// 当发生错误时,你可以以这种方式将日志连同之前的错误信息和警告发送到自己的服务器。
Future<bool> postLogs(LogInfoRequest request) async {
  var dio = Dio();
  var url = 'https://your.log.url';
  var data = request.toJson();

  Response response = await dio.post(url, data: data);
  if (response.statusCode == HttpStatus.ok) {
    return true;
  }
  return false;
}

main方法中调用initializeLog()方法:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // await Firebase.initializeApp();
  // FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;

  await initializeLog();

  runApp(const MyApp());
}

你可以打印日志如下:

try {
  Log.i("Test Info"); // 如果发送到服务器的功能是活动的,第一个到达的错误会被发送到服务器。
  Log.w("Test Warning"); // 如果发送到服务器的功能是活动的,第一个到达的错误会被发送到服务器。
  Log.d("Test Debug"); // 只打印屏幕
  if (1 == 1) {
    throw Exception("Test Error");
  }
} catch (e) {
  Log.e(e, message: "catch in build method (test)"); // 如果有互联网连接,它会立即发送到服务器,或者当有互联网连接时,与之前的错误信息和警告日志一起发送。
}

结果,日志看起来像这样: Image not found

每个日志由日志类型(INFO, WARNING, ERROR)、日期、类名、方法名和描述组成。 在错误日志中,错误详情和错误的堆栈跟踪出现在最后一行。

示例代码

import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:log_tracking/log_tracking.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // await Firebase.initializeApp();
  // FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;

  await initializeLog();

  runApp(const MyApp());
}

Future<void> initializeLog() {
  return Log.init(
      saveToLocal: true,
      onInfo: (log) {
        /// 如果你想要将日志集成到 FirebaseCrashlytics 中,可以这样做
        // FirebaseCrashlytics.instance.log("INFO:  ${log.text ?? ""}");
      },
      onWarning: (log) {
        /// 如果你想要将日志集成到 FirebaseCrashlytics 中,可以这样做
        // FirebaseCrashlytics.instance.recordFlutterError(
        //   FlutterErrorDetails(
        //     exception: "WARNING:  ${log.text}",
        //     stack: log.stackTrace,
        //   ),
        //   fatal: false,
        // );
      },
      onError: (log) {
        /// 如果你想要将日志集成到 FirebaseCrashlytics 中,可以这样做
        // FirebaseCrashlytics.instance.recordFlutterError(
        //   FlutterErrorDetails(exception: log.error, stack: log.stackTrace),
        //   fatal: true,
        // );
      },
      onDebug: (log) {
        /// 如果你需要处理调试日志
      },
      onSendToServer: (LogInfoRequest request) async {
        /// 如果你想要将日志发送到自己的服务器,可以使用此方法。
        /// 当捕获到错误日志时调用此方法。
        /// 错误日志之前的信息和警告日志也会作为列表出现。
        bool isSuccess = await postLogs(request);
        return isSuccess;
      });
}

/// 当发生错误时,你可以以这种方式将日志连同之前的错误信息和警告发送到自己的服务器。
Future<bool> postLogs(LogInfoRequest request) async {
  var dio = Dio();
  var url = 'https://your.log.url';
  var data = request.toJson();

  Response response = await dio.post(url, data: data);
  if (response.statusCode == HttpStatus.ok) {
    return true;
  }
  return false;
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  [@override](/user/override)
  Widget build(BuildContext context) {
    try {
      Log.i("Test Info"); // 如果发送到服务器的功能是活动的,第一个到达的错误会被发送到服务器。
      Log.w("Test Warning"); // 如果发送到服务器的功能是活动的,第一个到达的错误会被发送到服务器。
      Log.d("Test Debug"); // 只打印屏幕
      if (1 == 1) {
        throw Exception("Test Error");
      }
    } catch (e) {
      Log.e(e, message: "catch in build method (test)"); // 如果有互联网连接,它会立即发送到服务器,或者当有互联网连接时,与之前的错误信息和警告日志一起发送。
    }

    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // TRY THIS: Try running your application with "flutter run". You'll see
        // the application has a blue toolbar. Then, without quitting the app,
        // try changing the seedColor in the colorScheme below to Colors.green
        // and then invoke "hot reload" (save your changes or press the "hot
        // reload" button in a Flutter-supported IDE, or press "r" if you used
        // the command line to start the app).
        //
        // Notice that the counter didn't reset back to zero; the application
        // state is not lost during the reload. To reset the state, use hot
        // restart instead.
        //
        // This works for code too, not just values: Most code changes can be
        // tested with just a hot reload.
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

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

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // TRY THIS: Try changing the color here to a specific color (to
        // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
        // change color while the other colors stay the same.
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also a layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          //
          // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
          // action in the IDE, or press "p" in the console), to see the
          // wireframe for each widget.
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用log_tracking插件进行日志追踪的代码示例。请注意,由于log_tracking可能不是一个广为人知的官方插件(Flutter生态系统中插件众多,且变化较快),我将假设这是一个自定义的或第三方插件,并且会展示如何集成和使用一个假设的日志追踪插件。如果log_tracking插件确实存在,但API有所不同,请根据具体文档进行调整。

步骤 1: 添加依赖

首先,在你的pubspec.yaml文件中添加log_tracking插件的依赖。如果这是一个假设的插件,依赖项可能看起来像这样:

dependencies:
  flutter:
    sdk: flutter
  log_tracking: ^x.y.z  # 替换为实际版本号

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

步骤 2: 初始化插件

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

import 'package:flutter/material.dart';
import 'package:log_tracking/log_tracking.dart';  // 假设的导入路径

void main() {
  // 初始化日志追踪插件
  LogTracking.instance.init();

  runApp(MyApp());
}

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

步骤 3: 使用日志追踪功能

在你的应用中,你可以使用LogTracking实例来记录日志。这里是一个简单的例子,展示如何在按钮点击事件中记录日志。

import 'package:flutter/material.dart';
import 'package:log_tracking/log_tracking.dart';  // 假设的导入路径

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  void _logEvent() {
    // 记录一个自定义事件日志
    LogTracking.instance.logEvent(
      eventName: 'button_clicked',
      parameters: <String, dynamic>{
        'button_label': 'Click Me',
        'timestamp': DateTime.now().toIso8601String(),
      },
    );

    // 输出日志到控制台(假设插件支持)
    LogTracking.instance.log(message: 'Button was clicked');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Log Tracking Demo'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: _logEvent,
          child: Text('Click Me'),
        ),
      ),
    );
  }
}

步骤 4: 配置(可选)

根据log_tracking插件的文档,你可能需要在AndroidManifest.xmlInfo.plist文件中添加一些配置,或者设置一些初始化参数。由于这是一个假设的插件,具体的配置需求请参考插件的官方文档。

注意

  • 由于log_tracking可能不是一个真实存在的插件,上述代码是基于假设的API设计的。
  • 如果log_tracking是一个真实存在的插件,请参考其官方文档以获取准确的集成和使用指南。
  • 日志追踪通常涉及敏感数据,确保在处理和传输日志时遵守隐私政策和数据保护法规。

希望这个示例能帮助你理解如何在Flutter项目中使用日志追踪插件。如果有任何具体的问题或需要进一步的帮助,请随时提问。

回到顶部