Flutter性能监控插件tingyun_flutter_plugin的使用

Flutter性能监控插件tingyun_flutter_plugin的使用

环境要求

  • Dart Version: >= 2.4.0
  • Flutter Version: >= 1.12.0

嵌码步骤

1、原生项目嵌码

请确保嵌码 APP 原生部分已集成 TingYun_SDK,如未集成可参照原生项目部署文档完成嵌码。


2、Flutter 插件嵌码
2.1、添加依赖

在项目的「pubspec.yaml」文件中添加「TingYun Flutter」插件,目前支持【远程依赖】及【本地依赖】两种部署方式。

  • 远程依赖
dependencies:
	tingyun_flutter_plugin: ^1.0.0 
  • 本地依赖
dependencies:
    tingyun_flutter_plugin:
        path: tingyun_flutter_plugin //tingyun_flutter_plugin 需替换为本地 TingYun flutter 插件的目录

添加后需要在项目「根目录下」执行 flutter packages get 命令。
注意:iOS 添加依赖需在项目 ios 目录下执行 pod install


2.2、Flutter 插件初始化

需在 <code>runApp()</code> 方法前添加 <code>Tingyun().startWithoutWidget()</code> 方法,为了采集 zone 的错误,需在外层包裹 <code>runZonedGuarded</code>,并传入 <code>Tingyun().reportZoneStacktrace</code>

import 'package:tingyun_flutter_plugin/tingyun_flutter_plugin.dart';

void main() {
  runZonedGuarded(() async {
    Tingyun().startWithoutWidget();
    runApp(MyApp());
  }, Tingyun().reportZoneStacktrace);
}

运行项目工程后控制台会显示以下日志:

tingyun flutter impl start
get configure from tingyun:xxx //xxx 为从 native 端 SDK 获取到的功能开关配置情况
//初始化成功时候显示
tingyun flutter plugin success!
//初始化失败时显示
tingyun flutter plugin failed to initialize. Error: xxx //xxx 为错误描述

2.3、兼容异常数据

由于 Flutter 只允许单一 handler 收集 error 数据,听云提供了相关参数以便兼容 App 自身采集 error 的场景。

  • 控制参数
/**
因为flutter error 的捕获机制原因,需要提供2个不同的函数来进行处理,
onError 是flutter框架没有捕获到的异常的时候,通过runZoned来捕获的error的回调函数
flutterOnError 是flutter框架通过Flutter.onError来捕获异常的回调函数

@onError: 需要传入原型为 void FunctiononError(Object, StackTrace)的函数, 
@flutterOnError: 需要传入原型为 void FunctionFlutterError(FlutterErrorDetails details)的函数
*/
Tingyun().startWithoutWidget(onError: onCustomError, flutterOnError: onCustomFlutterError);
  • 代码示例
void main() {
  runZonedGuarded(() async {
    Tingyun().startWithoutWidget(onError: onCustomError, flutterOnError: onCustomFlutterError);
    runApp(MyApp());
  }, Tingyun().reportZoneStacktrace);
}

void onCustomError(Object object, StackTrace stackTrace){
  print('onCustomError happened');
}

void onCustomFlutterError(FlutterErrorDetails details){
  print('onCustomFlutterError happened');
}

3、Android WebView 数据采集

由于操作系统差异,TIngYun_iOS_SDK 默认支持自动采集 WebView 数据,Android 则需按以下步骤添加相关设置。

设置 WebChromeClient

Android 采集 WebView 数据需要设置 WebChromeClient,并在 onProgressChanged() 中调用 TingYun_Android_SDK 提供的 initJSMonitor() 方法。

举例

以【webview_flutter-0.3.24】为例:

  • 打开 webview_flutter-0.3.24 android 目录下的 build.gradle 文件并添加 TingYun_Android_SDK 依赖:
dependencies {
    compileOnly "com.networkbench:tingyun-ea-agent-android:2.17.4"   
}
  • WebChromeClient 中重写 onProgressChanged(),并添加 TingYun_SDK 的 initJSMonitor() 方法:
private class FlutterWebChromeClient extends WebChromeClient {

  @Override
  public void onProgressChanged(WebView view, int newProgress) {
    try {
      Class.forName("com.networkbench.agent.impl.instrumentation.NBSWebChromeClient");
      com.networkbench.agent.impl.instrumentation.NBSWebChromeClient.initJSMonitor(view, newProgress);
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
    super.onProgressChanged(view, newProgress);
  }
  ... ...
}

API接口

1、自定义网络请求

TingYun_SDK 通过设置 HttpOverrides.global 自动采集网络数据,目前支持「httpClient」以及基于 HttpClient 封装的「dio、http」等网络库。

  • 相关接口
/*
@url:网络请求的完整 url
*/
TYWebRequestTiming timing = await Tingyun().createWebRequest(String url);// 创建一条网络性能数据
timing.start();// 请求开始
/*
@code:请求的状态码
*/
timing.stop(int code);// 请求结束
  • 代码示例
var url = "https://www.tingyun.com";
TYWebRequestTiming timing = await Tingyun().createWebRequest(url);
timing.startWebRequestTiming();
var response = await http.get(url)
        .then((response) {
    timing.stop(response.statusCode);// 请求结束
    return response;
 });

2、自定义启动结束点

TingYun_SDK 默认计算 SDK 初始化开始至第一个页面加载结束的时间为「冷启动耗时」,研发人员可以根据自身应用需求更改计算「冷启动耗时」的结束点。

  • 项目要求

    • Android 项目
      采集冷启动(含首次启动)数据需实现自定义的 Application 类。
    • iOS 项目
      采集启动数据需要在 main 函数中嵌码。
  • 开启自定义启动开关 需在 native 部分初始化 TingYun_SDK 时调用相关接口。

    • Android 接口
    /*
    [@isCustom](/user/isCustom):是否启用自定义启动,默认 false,如需开启,置为 true
    */
    NBSAppAgent.isCustomAppStart(boolean isCustom);
    
    • iOS 接口
    /**
     是否启用自定义启动,在启动SDK之前调用,默认 NO,如需开启,置为 YES
     */
    + (void)customLanuchEnd:(BOOL)enable;
    
    • 代码示例
      • Android 示例
      public class MyApplication extends Application {
          @Override
          public void onCreate() {  
              NBSAppAgent.setLicenseKey("AppKey")
              .isCustomAppStart(true)//在初始化SDK时调用,开启自定义启动时间功能
              .start(this.getApplicationContext());
          }
      }
      
      • iOS 示例
      int main(int argc, char* argv[]) {
        @autoreleasepool {
                [NBSAppAgent customLanuchEnd:YES];
                [NBSAppAgent setRedirectURL:@"Dc_Redirect"];
                [NBSAppAgent startWithAppID:@"AppKey"];
          return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
      }
      
  • 设置自定义启动的结束点 需要开启「自定义启动开关」,当自定义启动开关设置为 true 时,自定义启动结束点的接口设置才会生效。

    • 相关接口
    Tingyun().setCustomOnResumeEndIns();
    
    • 代码示例
    Widget build(BuildContext context) {
        Tingyun().setCustomOnResumeEndIns();
        return Scaffold(
          body: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            .....
          ));
    }
    

3、自定义用户操作

支持通过埋点方式采集操作数据,可支持 root 和 sub 两层 trace(注意:这里两层是指 sub trace 允许有多个并非两个)。

  • 接口限制

    • 操作数据截至到 root 节点结束。
    • 多组埋点 root 节点不能交叉调用。
  • 相关接口

/*
@name:操作名称
*/
TingyunRootAction rootAction = Tingyun().enterAction(String name);//创建一个操作
/*
@name:子 Action 名称
*/
TingyunAction subAction = rootAction.enterAction(String name);//创建一个子 Action
subAction.leaveAction();//子 Action 完成
/*
@props:附加信息
@tag:tag 标识
*/
rootAction.leaveAction({Map<String, dynamic> props, String tag = ""});//操作完成
  • 代码示例
TingyunRootAction rootAction = Tingyun().enterAction('my button enter');

TingyunAction subAction1 = rootAction.enterAction('sub1 button enter');

subAction1.leaveAction();

TingyunAction subAction2 = rootAction.enterAction('sub2 button enter');

subAction2.leaveAction();

rootAction.leaveAction(props:{"key1":"value1","key2":"value2"},tag: "tag");

4、自定义错误

使用「自定义错误」接口可以采集研发人员「try / catch 异常」和「业务错误」并在听云平台「异常分析」→「错误」中进行展示,可以帮助研发人员收集异常和错误。

  • 相关接口
/*
 @message:不可以传空,最大长度 1024 字节,超出截取前 1024 字节
 @stackTrace:上传 exception 取到抛出时的堆栈
 @props:value 值支持 Number, String, Array, Map 类型,最大限制128k,若超出最大限制上传为空
 */
Tingyun().reportError(String message, String stackTrace, {Map<String, dynamic> props});
  • 代码示例
try {
    throw new StateError('This is an async Dart exception.');
} catch (exception, stack) {
    Tingyun().reportError(exception.toString(), stack.toString(),props: {"ke y1":"value1","key2":"value2"});
}  

5、设置用户标识

通过添加「用户标识」可在听云报表平台通过该标识检索到具体用户的性能问题。

  • 相关接口
/*
@userIdentifier:最多包含64个字符,超出截取前64字符,支持中文、英文、数字、下划线,但不能包含空格或其他的转义字符
*/
Tingyun().setUserIdentifier(String userIdentifier);
  • 代码示例
Tingyun().setUserIdentifier("zhangsan@tingyun.com");

6、记录用户路径(面包屑)

研发人员可以在应用程序的任意位置调用「面包屑」接口进行埋点。当应用程序发生崩溃时,SDK 会按代码的触发顺序收集埋点信息并在崩溃轨迹中高亮显示,以协助研发人员在应用崩溃时了解代码调用逻辑。

  • 相关接口
/*
  @breadcrumb:自定义信息,最多包含100个字符,超出截取前100字符,支持中文、英文、数字、下划线
*/
Tingyun().leaveBreadcrumb(String breadcrumb);
  • 代码示例
Tingyun().leaveBreadcrumb("添加购物车");

7、自定义附加信息

在应用发生崩溃的时候,研发人员往往需要更多的信息以收集现场环境,可以通过调用「自定义崩溃附加信息」接口上传额外信息,协助分析崩溃问题。

  • 相关接口
/*
只保留最新的10条数据,随崩溃上传
@key:key 值
@value:value 值,最大长度限制100,超出则截取前100
*/
Tingyun().setUserCrashMessage(String key, String value);
  • 代码示例
Tingyun().setUserCrashMessage("当前页面", "Main");

更多关于Flutter性能监控插件tingyun_flutter_plugin的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter性能监控插件tingyun_flutter_plugin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


tingyun_flutter_plugin 是一个用于 Flutter 应用的性能监控插件,它可以帮助开发者监控应用的性能指标,如启动时间、页面加载时间、网络请求时间等。以下是如何使用 tingyun_flutter_plugin 的基本步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  tingyun_flutter_plugin: ^版本号

请将 ^版本号 替换为最新的插件版本号。

2. 初始化插件

在你的 Flutter 应用启动时,初始化 tingyun_flutter_plugin。通常可以在 main.dart 文件中进行初始化:

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

void main() {
  // 初始化 Tingyun 插件
  TingyunFlutterPlugin.init(
    appKey: '你的AppKey', // 替换为你的 Tingyun AppKey
    channel: 'your_channel', // 渠道号,可选
    debugMode: true, // 是否开启调试模式,可选
  );

  runApp(MyApp());
}

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

3. 监控页面加载时间

你可以使用 TingyunFlutterPlugin 来监控页面的加载时间。在页面加载时调用 startTrackPage,在页面卸载时调用 stopTrackPage

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

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
    // 开始监控页面加载时间
    TingyunFlutterPlugin.startTrackPage('MyHomePage');
  }

  @override
  void dispose() {
    // 停止监控页面加载时间
    TingyunFlutterPlugin.stopTrackPage('MyHomePage');
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
      ),
      body: Center(
        child: Text('Hello, Tingyun!'),
      ),
    );
  }
}

4. 监控网络请求

tingyun_flutter_plugin 也支持监控网络请求。你可以在发起网络请求时调用 startTrackHttp,在请求完成时调用 stopTrackHttp

import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:tingyun_flutter_plugin/tingyun_flutter_plugin.dart';

Future<void> fetchData() async {
  var url = Uri.parse('https://example.com/api/data');
  var requestId = TingyunFlutterPlugin.startTrackHttp(url.toString());

  try {
    var response = await http.get(url);
    TingyunFlutterPlugin.stopTrackHttp(requestId, response.statusCode, response.contentLength ?? 0);
  } on SocketException catch (e) {
    TingyunFlutterPlugin.stopTrackHttp(requestId, 500, 0);
  }
}

5. 自定义事件

你还可以使用 TingyunFlutterPlugin 来记录自定义事件:

TingyunFlutterPlugin.trackEvent('custom_event', {'key1': 'value1', 'key2': 'value2'});

6. 调试模式

在开发阶段,你可以开启调试模式来查看更多的日志信息:

TingyunFlutterPlugin.setDebugMode(true);

7. 发布应用

在发布应用时,确保关闭调试模式:

TingyunFlutterPlugin.setDebugMode(false);
回到顶部