You need to enable JavaScript to run this app.
导航

Flutter接入异常

最近更新时间2024.01.08 16:31:21

首次发布时间2023.06.25 14:39:14

接入 SDK 报错

请您根据控制台日志确定报错类型。

问题1:重复调用 WidgetsFlutterBinding.ensureInitialized(),异常信息中包含 '_debugInitializedType == null': is not true.

解决方案

通常出现这种问题,是因为您在 main 函数中或者其他地方手动调用了WidgetsFlutterBinding.ensureInitialized()或者其继承类的该方法,而 ve_apm 在 runTraceApp() 方法中也会调用。您需要根据调用方式进行如下配置来解决这个问题:

  • 调用的是非继承类的方法,即直接调用WidgetsFlutterBinding.ensureInitialized()

    • 如果在 runTraceApp() 之后调用了 WidgetsFlutterBinding.ensureInitialized(),直接删除该调用即可,不会对原有业务逻辑产生影响。

    • 如果在 runTraceApp() 之前调用了 WidgetsFlutterBinding.ensureInitialized(),删除该调用并且将原本的其他业务代码放置到runTraceApp()中,调整前后的代码对比如下:
      您的原始代码:

      void main() {
        WidgetsFlutterBinding.ensureInitialized();
        //业务代码
        SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
        
        runTraceApp((NavigatorObserver observer) {
          HttpOverrides.global = ApmHttpOverrides();
          enableVeApmLog(true);  // 控制台日志开关,默认为 true,建议接入测试过程中打开,便于排查问题
          return MyApp(observer);
        });
      }
      

      调整之后的代码:

      void main() {
        runTraceApp((NavigatorObserver observer) {
          //业务代码
          SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
          
          HttpOverrides.global = ApmHttpOverrides();
          enableVeApmLog(true);  // 控制台日志开关,默认为 true,建议接入测试过程中打开,便于排查问题
          return MyApp(observer);
        });
      }
      
  • 调用的是继承类的方法,如 CustomFlutterBinding.ensureInitialized()
    让继承类继承自ApmWidgetsFlutterBinding,然后将CustomFlutterBinding.ensureInitialized 作为参数传递给 runTraceApp(),并删除原来的调用,调整前后的代码对比如下:
    您的原始代码:

    void main() {
      CustomFlutterBinding.ensureInitialized();
      
      runTraceApp((NavigatorObserver observer) {
        HttpOverrides.global = ApmHttpOverrides();
        enableVeApmLog(true);  // 控制台日志开关,默认为 true,建议接入测试过程中打开,便于排查问题
        return MyApp(observer);
      });
    }
    

    调整之后的代码:

    void main() {
      runTraceApp((NavigatorObserver observer) {
        HttpOverrides.global = ApmHttpOverrides();
        enableVeApmLog(true);  // 控制台日志开关,默认为 true,建议接入测试过程中打开,便于排查问题
        return MyApp(observer);
      }, bindingInitHandler: CustomFlutterBinding.ensureInitialized);
    }
    
    mixin MixinFlutterBinding on ApmWidgetsFlutterBinding {
      @override
      void initInstances() {
        super.initInstances();
        print('MixinFlutterBinding initInstances');
      }
    
      @override
      void handleAppLifecycleStateChanged(AppLifecycleState state) {
        super.handleAppLifecycleStateChanged(state);
        print('MixinFlutterBinding handleAppLifecycleStateChanged');
      }
    }
    
    class CustomFlutterBinding extends ApmWidgetsFlutterBinding
        with MixinFlutterBinding {
      static WidgetsBinding? ensureInitialized() {
        CustomFlutterBinding();
        return WidgetsBinding.instance;
      }
    }
    

问题2:Binding 未被初始化,异常信息中包含 Binding has not yet been initialized.

图片
解决方案
如果未接入 ve_apm 之前无该异常,则可能是为了解决问题 1 引发的。您需要将 runTraceApp() 之前的代码移动到runTraceApp()。调整前后的代码对比如下:
您的原始代码:

void main() {
  //业务代码
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  
  runTraceApp((NavigatorObserver observer) {
    HttpOverrides.global = ApmHttpOverrides();
    enableVeApmLog(true);  // 控制台日志开关,默认为 true,建议接入测试过程中打开,便于排查问题
    return MyApp(observer);
  });
}

调整之后的代码:

void main() {
  runTraceApp((NavigatorObserver observer) {
    //业务代码
    SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
    
    HttpOverrides.global = ApmHttpOverrides();
    enableVeApmLog(true);  // 控制台日志开关,默认为 true,建议接入测试过程中打开,便于排查问题
    return MyApp(observer);
  });
}

Dart 异常 无数据

Dart 异常需要在 Flutter 监控 - Dart 异常 中查看,查看时请根据您测试的平台选择系统查看。
图片

  1. 确认Dart SDK以及Native SDK的初始化代码是否有误。

    注意

    如果您的 Android 初始化代码中,MonitorCrash.autoStart 设置为 false,则需要手动调用 monitorCrash.start(),否则 SDK 无法启动。

  2. 确认平台 SDK 上报配置。
    图片
    Dart 异常采样率默认值不是 100%,您可以到平台上修改配置为 100% 确保采样必定命中,或者添加设备白名单,白名单中的设备所有配置采样率均视为 100%。具体请参见SDK上报配置

    说明

    修改之后需要等待 5 分钟左右,然后重新启动应用才能拉取到最新配置。

  3. 编写测试代码触发 Dart 异常,然后检查控制台日志。
    • 控制台打印如下日志,说明未正确初始化 native SDK,请检查 native SDK 的代码及相关配置。

      method: reportToDartError, step: ApmInsight._cacheInsert
      
    • 控制台打印如下日志,说明命中了采样,并且成功记录了日志,请重启应用触发日志上报,然后等待 5 分钟左右即可在平台上看到 Dart 异常。

      method: reportToDartError, step: invoke reprotDartError
      
    • 没有出现上述两种日志,则可能是未命中采样,请确认已修改采样率或者添加白名单。如果已经修改过采样率,请根据第4步确认配置下发和数据上报情况。

  4. 使用 Charles 或者其他工具抓包查看请求,域名为apmplus.volces.com,如果没有这个域名的请求,则可能是 native SDK 未启动,请检查 native SDK 的初始化代码。
    1. 确认配置下发:查看 settings/get 接口,可能有多个请求,请查看下发数据中 appID(下图中为187277) 和您的应用匹配的请求。
      图片
      • 当圈选的字段 flutter_crash_ratioswitcher 都为 1 时说明采样命中,请重试第3步,如果依然无数据,请参考第5步进行反馈。
      • flutter_crash_ratio0 时,说明采样未命中,请参考第2步进行修改。
      • switcher0 时,说明总开关未打开,请参考第2步进行修改。
    2. 确认数据上报:如果请求中包含 monitor/collect/c/crash 接口,则说明异常已经上报,请等待 5 分钟左右在平台上查看数据。
      图片
  5. 如果上述排查路径均无法解决您的问题,请您提交以下相关信息给我们来协助您排查。
    • 初始化代码截图
    • SDK 上报配置截图
    • 控制台日志
    • Charles 抓包文件

Flutter 页面列表、页面体验 无数据

Flutter 页面数据需要在 Flutter 监控 - Flutter 页面列表 中查看,查看时请根据您测试的平台选择系统查看。
图片

  1. 确认Dart SDK以及Native SDK的初始化代码是否有误。

    注意

    请确认 Dart 初始化时是否正确设置了 observer,即把 runTraceApp()中builder参数的 observer 对象设置给根视图的 navigatorObservers

    void main() {
      runTraceApp((NavigatorObserver observer) {
        enableVeApmLog(true);  // 控制台日志开关,默认为 true,建议接入测试过程中打开,便于排查问题
        return MyApp(observer);
      });
    }
    
    class MyApp extends StatefulWidget {
      const MyApp([this._navigatorObserver]);
      final NavigatorObserver? _navigatorObserver;
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: HomePage(),
          navigatorObservers: <NavigatorObserver>[
            widget._navigatorObserver ?? ApmNavigatorObserver.instance 
          ],
          routes: generateRoutes(),
        );
      }
    }
    
  2. 确认平台 SDK上报配置。
    图片
    Flutter页面采样率默认值不是 100%,您可以到平台上修改配置为 100% 确保采样必定命中,或者添加设备白名单,白名单中的设备所有配置采样率均视为 100%。具体请参见SDK上报配置

    说明

    修改之后需要等待 5 分钟左右,然后重新启动应用才能拉取到最新配置。

  3. 检查控制台日志。

    1. 控制台打印如下日志,说明命中了采样,并且成功记录了日志,请重启应用触发日志上报,然后等待 5 分钟左右即可在平台上看到 Flutter 页面数据。

      method: ApmInsight.reportToInsight, step: invock reportToInsight, param
      

      注意

      确认 param 的 service 的取值,如果是 flutter_page_load,说明上报的是页面加载数据,在页面列表中查看数据;如果是 flutter_fps,说明上报的是帧率数据,在流畅性中查看数据。

    2. 控制台打印如下日志,说明未正确初始化 native SDK,请检查 native SDK 的代码及相关配置。

      method: ApmInsight.reportToInsight, step: ApmInsight._cacheInsert
      
    3. 没有出现上述两种日志,则可能是未命中采样,请确认已修改采样率或者添加白名单。如果已经修改过采样率,请根据第4步的指引确认配置下发。

  4. 使用 Charles 或者其他工具抓包查看请求,域名为 apmplus.volces.com,如果没有这个域名的请求,则可能是 native SDK 未启动,请检查 native SDK 的初始化代码。
    确认配置下发:查看 settings/get 接口,可能有多个请求,请查看下发数据中 appID(下图中为187277) 和您的应用匹配的请求。
    图片

    • 当圈选的字段都为 1 时说明采样命中,请重试第3步,如果依然无数据,请参考第5步进行反馈。
    • flutter_fps_ratioflutter_page_load_ratio0 时,说明采样未命中,请参考第2步进行修改。
    • switcher0 时,说明总开关未打开,请参考第2步进行修改。
  5. 如果上述排查路径均无法解决您的问题,请您提交以下相关信息给我们来协助您排查。

    • 初始化代码截图
    • SDK 上报配置截图
    • 控制台日志
    • Charles 抓包文件

Flutter 页面列表、页面体验 缺少部分页面数据

如果完全无数据,请参见Flutter 页面列表、页面体验 无数据排查,下述方案适用于缺失部分数据。

  • 如果您的应用当前包含多个 navigator ,则 SDK 目前无法监控所有的 navigator,只支持对其中一个设置 observer 进行监控。
  • SDK 会忽略掉页面名称未知的数据。
    • 如果您的页面在应用的路由表中注册过,则这些页面的性能数据自然可以被采集并上报。
    • 如果您使用了动态路由,请配置 settings 的 name 参数,来标识页面。
      图片

Flutter 网络监控 无数据

Flutter 网络数据需要在 Flutter 监控 - Flutter 网络监控 中查看,查看时请根据您测试的平台选择系统查看。
图片

  1. 确认Dart SDK以及Native SDK的初始化代码是否有误。

    注意

    请确认 Dart 初始化时设置了 HttpOverrides

    void main() {
      runTraceApp((NavigatorObserver observer) {
        HttpOverrides.global = ApmHttpOverrides();
        enableVeApmLog(true);  // 控制台日志开关,默认为 true,建议接入测试过程中打开,便于排查问题
        return MyApp(observer);
      });
    }
    
  2. 确认平台 SDK 上报配置。
    图片
    Flutter 网络采样率默认值不是 100%,您可以到平台上修改配置为 100% 确保采样必定命中,或者添加设备白名单,白名单中的设备所有配置采样率均视为 100%。具体请参见SDK上报配置

    说明

    修改之后需要等待 5 分钟左右,然后重新启动应用才能拉取到最新配置。

  3. 检查控制台日志。

    • 控制台打印如下日志,说明命中了采样,并且成功记录了日志,请重启应用触发日志上报,然后等待 5 分钟左右即可在平台上看到 Flutter 网络数据。

      method: ApmInsight.reportToInsight, step: invock reportToInsight, param
      

      注意

      需要确认下 param 的 service,如果是flutter_network,说明上报的是网络数据。

    • 控制台打印如下日志,说明未正确初始化 native SDK,请检查 native SDK 的代码及相关配置。

      method: ApmInsight.reportToInsight, step: ApmInsight._cacheInsert
      
    • 没有出现上述两种日志,则可能是未命中采样,请确认已修改采样率或者添加白名单。如果已经修改过采样率,请根据第4步的指引确认配置下发。

  4. 使用 Charles 或者其他工具抓包查看请求,域名为 apmplus.volces.com ,如果没有这个域名的请求,则可能是 native SDK 未启动,请检查 native SDK 的初始化代码。
    确认配置下发:查看 settings/get 接口,可能有多个请求,请查看下发数据中 appID(下图中为187277) 和您的应用匹配的请求。
    图片

    • 当圈选的字段都为 1 时说明采样命中,请重试第3步,如果依然无数据,请参考第5步进行反馈。
    • flutter_network_ratio0 时,说明采样未命中,请参考第2步进行修改。
    • switcher0 时,说明总开关未打开,请参考第2步进行修改。
  5. 如果上述排查路径均无法解决您的问题,请您提交以下相关信息给我们来协助您排查。

    • 初始化代码截图
    • SDK 上报配置截图
    • 控制台日志
    • Charles 抓包文件

Flutter Channel 监控 无数据

Flutter Channel数据需要在 Flutter 监控 - Channel监控 中查看,查看时请根据您测试的平台选择系统查看。
图片

  1. 确认Dart SDK以及Native SDK的初始化代码是否有误。
  2. 确认平台 SDK上报配置。
    图片
    Flutter Channel 采样率默认值不是 100%,您可以到平台上修改配置为 100% 确保采样必定命中,或者添加设备白名单,白名单中的设备所有配置采样率均视为 100%。具体请参见SDK上报配置

    说明

    修改之后需要等待 5 分钟左右,然后重新启动应用才能拉取到最新配置。

  3. 检查控制台日志。
    • 控制台打印如下日志,说明命中了采样,并且成功记录了日志,请重启应用触发日志上报,然后等待 5 分钟左右即可在平台上看到 Flutter Channel数据。

      method: ApmInsight.reportToInsight, step: invock reportToInsight, param
      

      注意

      确认 param 的 service 的取值,如果是flutter_channel,说明上报的是 channel 数据。

    • 控制台打印如下日志,说明未正确初始化 native SDK,请检查 native SDK 的代码及相关配置。

      method: ApmInsight.reportToInsight, step: ApmInsight._cacheInsert
      
    • 没有出现上述两种日志,则可能是未命中采样,请确认已修改采样率或者添加白名单。如果已经修改过采样率,请根据第4步的指引确认配置下发。

  4. 使用 Charles 或者其他工具抓包查看请求,域名为 apmplus.volces.com,如果没有这个域名的请求,则可能是 native SDK 未启动,请检查 native SDK 的初始化代码。
    确认配置下发:查看 settings/get 接口,可能有多个请求,请查看下发数据中 appID(下图中为187277) 和您的应用匹配的请求。
    图片
    • 当圈选的字段 flutter_channel_ratioswitcher 都为 1 时说明采样命中,请重试第3步,如果依然无数据,请参考第5步进行反馈。
    • flutter_channel_ratio0 时,说明采样未命中,请参考第2步进行修改。
    • switcher0 时,说明总开关未打开,请参考第2步进行修改。
  5. 如果上述排查路径均无法解决您的问题,请您提交以下相关信息给我们来协助您排查。
    • 初始化代码截图
    • SDK 上报配置截图
    • 控制台日志
    • Charles 抓包文件

日志回捞/自定义日志 / ALog无数据

需要接入Dart 组件ve_alog自行埋点,且通过回捞查看日志。

  1. 确认Dart SDK以及Native SDK的初始化代码是否有误。

    注意

    务必按照 自定义日志 章节进行 Dart 和 Native 侧的配置,才可以成功记录并回捞日志.

  2. 创建回捞日志。详情请参见回捞
  3. 使用 Charles 或者其他工具抓包查看请求,域名为 apmplus.volces.com,如果没有这个域名的请求,则可能是 native SDK 未启动,请检查 native SDK 的初始化代码。
    1. 确认命令拉取:查看 monitor/collect/c/cloudcontrol/get 接口,可能有多个请求,请查看请求的query string 中 aid(下图中为187277) 和您的应用匹配的请求。
      图片
      • 确认命令拉取的字段 device_id/uid、aid 和您创建的回捞命令是否匹配,如果不匹配,请检查初始化设置的 device_id 和 user_id 是否正确,字段说明如下:
        • device_id:设备ID,即创建回捞命令使用的 DID
        • aid:应用ID
        • uid:用户ID,即创建回捞命令使用的 UID
    2. 确认数据上报:如果请求中包含 monitor/collect/c/cloudcontrol/file 接口,则说明回捞任务已经执行完成,日志已经上报,请在平台上查看回捞任务执行结果。
      图片
  4. 如果上述排查路径均无法解决您的问题,请您提交以下相关信息给我们来协助您排查。
    • 初始化代码截图
    • 回捞任务详情页截图
    • Charles 抓包文件

flutter_boost页面监控数据

手动调用 FlutterBoost.singleton.addBoostNavigatorObserver() 即可。
示例代码:

import 'package:flutter_boost/flutter_boost.dart';

void main() {
  runTraceApp((NavigatorObserver observer) {
    FlutterBoost.singleton.addBoostNavigatorObserver(observer);
    HttpOverrides.global = ApmHttpOverrides();
    enableVeApmLog(true);  // 控制台日志开关,默认为 true,建议接入测试过程中打开,便于排查问题
    return MyApp(observer);
  }, bindingInitHandler: CustomFlutterBinding.ensureInitialized);
}

Unable to find a specification for FlutterMacOS depended upon by shared_preferences_foundation

修改 source 书写方式。
示例代码:

target 'Runner' do 
  pod 'RangersAPM', '3.3.2', :source => 'https://github.com/volcengine/volcengine-specs.git', :subspecs => [ 
    'Flutter', 
    'CN' 
  ] 
  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 
end

Flutter 引擎退出时崩溃

如果崩溃堆栈和下图类似,则问题已经在 3.0.6 版本修复,升级 SDK 即可。
图片

和 Dynatrace 的入口抢占问题

Dynatrace().start() 和 runTraceApp() 会抢占应用初始化,可以改为调用 Dynatrace 的这个接口。
图片

火山的捕获是否会影响其他的异常捕获

原本通过注册 onError 能够捕获到的异常依然能够捕获到,但是有部分异常没法捕获到,例如异步方法触发的异常。