Sentry是一款多平台支持的异常信息收集解决方案。sentry_flutter可以在Flutter项目中收集异常信息。
https://docs.sentry.io/platforms/flutter/可以查阅其Flutter项目的集成文档。
sentry_dart_plugin可以自动上传mapping.txt文件和debug的动态库,方便后续直接在sentry后台查看异常信息。
基本用法
- pubspec.yaml配置,sentry_dart_plugin配置参数参考https://github.com/getsentry/sentry-dart-plugin/blob/main/README.md
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| dependencies: sentry_flutter: ^7.16.0
sentry: upload_debug_symbols: true upload_source_maps: false upload_sources: false project: ... org: ... auth_token: ... url: ... wait_for_processing: false log_level: error release: ... dist: ... web_build_path: ... commits: auto ignore_missing: true
|
- 代码中初始化相关配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import 'package:flutter/widgets.dart'; import 'package:sentry_flutter/sentry_flutter.dart';
Future<void> main() async { await SentryFlutter.init( (options) { options.dsn = 'https://example@sentry.io/add-your-dsn-here'; }, appRunner: () => runApp(MyApp()), ); }
|
- 打包脚本中配置上传mapping.txt文件和debug的动态库
1
| flutter packages pub run sentry_dart_plugin
|
性能分析
Sentry可以通过“性能”模块来监控整个页面的加载性能,网络请求监控。监控dio可以参考sentry_dio这个库。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| Dio dio = Dio(options); dio.interceptors.add(SentryDioInterceptor()); dio.addSentry();
class SentryDioInterceptor extends BaseInterceptor { @override Future<void> onRequest( RequestOptions options, RequestInterceptorHandler handler, ) async { final transaction = Sentry.startTransaction( 'dio-web-request', 'request', bindToScope: true, ); options.extra['sentryTransaction'] = transaction; final span = transaction.startChild( 'dio-request', description: 'Sending request to ${options.uri}', ); options.extra['sentrySpan'] = span; super.onRequest(options, handler); }
@override Future<void> onResponse( Response response, ResponseInterceptorHandler handler, ) async { final span = response.requestOptions.extra['sentrySpan'] as SentrySpan?; final transaction = response.requestOptions.extra['sentryTransaction'] as ISentrySpan?; if (span != null) { span.status = const SpanStatus.ok(); await span.finish(); } if (transaction != null) { await transaction.finish(); } super.onResponse(response, handler); }
@override Future<void> onError( DioException err, ErrorInterceptorHandler handler, ) async { final span = err.requestOptions.extra['sentrySpan'] as SentrySpan?; final transaction = err.requestOptions.extra['sentryTransaction'] as ISentrySpan?; if (span != null) { span.throwable = err; span.status = const SpanStatus.internalError(); await span.finish(); } if (transaction != null) { await transaction.finish(); } await Sentry.captureException(err); super.onError(err, handler); } }
|
注意本地版本与服务端版本的对应关系,否则某些功能可能无法使用。(比如transaction_info: Discarded unknown attribute)
参考