Flutter 集成 Sentry Dart 的实践|Fluter

1,278 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

前言

pub.dev/ 中 Sentry 有 Sentry-Flutter 和 Sentry-dart。

Sentry-Flutter 包 功能全面,包含 Flutter 和原生部分。

Sentry-dart 包功能简单,只包含 dart。

很多现有项目 Android 和 iOS 都已经集成了崩溃收集功能,与 Sentry-Flutter 功能重复,这种场景只需要集成 Sentry-dart即可。

本文主要叙述在 Flutter 中集成 Sentry-dart 的过程。

初始化

Future<void> _initSentry(Function runApp) async {
  PackageInfo packageInfo = await PackageInfo.fromPlatform();
  String version = packageInfo.version;
  String buildNumber = packageInfo.buildNumber;
  String packageName = packageInfo.packageName;
  await Sentry.init((options) {
    options.dsn =
        '***';
    options.release = '$packageName@$version+$buildNumber';
    options.enablePrintBreadcrumbs = false;
  }, appRunner: runApp);
}

options.release 的设置格式为 $packageName@$version+$buildNumber 。这种格式在 sentry 后台才可以搜索到对应的版本号。

options.enablePrintBreadcrumbs 可以控制是否上传 print 的内容。

Sentry 初始化之后调用 runApp 才能收集到异常。

Flutter 自带库中没有获取 APP 版本信息的方法,获取版本信息可以集成 pub.dev/packages/pa…

捕获异常

只能 catch 到 未被 catch 的异常。UI 异常会被 UI 框架 catch,所以这里收集不到。

FlutterError.onError = (FlutterErrorDetails details) async {
    sentryCaptureException(details.exception, details.stack);
};

runZonedGuarded(() async {
    handleFlutterException();
    WidgetsFlutterBinding.ensureInitialized();
		runApp(const MyApp());
  }, (Object obj, StackTrace stack) async {
      sentryCaptureException(obj, stack);
  });

设置 Tag

Untitled.png

Sentry.configureScope((Scope scope) async {
      scope.setTag('os', 'Android 12');
      ...
});

设置tag 不仅可以设置 设备型号,也可以设置设备id,这样可以查找到单一设备上的所有异常信息。 关于设备id的经验是建议 app 第一次安装时初始化一个 uuid,用户不卸载应用,这个 uuid 能一直保存,能基本唯一标识一个设备了。为啥不用真实的id,因为可能引起用户隐私风险,所以建议使用随机 uuid 能满足抓取异常的需要了。

需要说明的一个是初始化时设置的 release 也属于 tag,在 scope 中设置了 release 会不生效。

Flutter 没有获得 设备信息的方法,可以集成 pub.dev/packages/de… 来获取。

BreadCrumbs 面包屑

Untitled 1.png

可以监听路由修改从而得到异常发生前的用户路由变化,推理出异常出现路径。

添加面包屑的方法

Sentry.addBreadcrumb(Breadcrumb(message: 'some'));

监听路由变化 Navigator

MaterialApp(
  navigatorObservers: [
    SentryNavigatorObserver(),
  ],
  // other parameters
)

SentryNavigatorObserver是 Sentry flutter 中的方法,在 Sentry-dart 中没有实现。可以自己监听路由变化然后调用 Sentry.addBreadCrumb() 来传递路由信息

SentryNavigatorObserver 可以参考 sentry-dart/flutter/lib/src/navigation/sentry_navigator_observer.dart

监听路由变化 FlutterBoost

如果项目使用了 FlutterBoost,会拦截 Flutter 自带的 Navigator 变化方法,导致 navigatorObservers 接收不到路由变化。可以通过监听 FlutterBoost 的路由变化来添加页面变化事件。

flutter_boost/lifecycle.md at master · alibaba/flutter_boost

Sentry 免费账户的限制

Untitled 2.png

Sentry 是开源的,但是 Sentry 的服务 Sentry.io 是 收费的。sentry.io 免费账户使用有容量限制。一旦 超过限制服务器就会把收到的报错丢掉。sentry.io 后台就看不到新上传的报错了。

自建 Sentry 服务

github.com/getsentry/s…

在 服务器终端运行 ./install.sh 若网好 十分钟内可以部署上。

之后在后台 web 页创建账号,创建项目拿到 DSN 即可使用。 Sentry 服务器的硬件要求 是 4核8G。我在 2核4G的轻量主机上部署后,也可以简单实用。满足测试期间需要了。

最后

如有问题请指正,谢谢