You need to enable JavaScript to run this app.
最新活动
产品
解决方案
定价
合作与生态
支持与服务
开发者
了解我们
导航

iOS 组件监控SDK接入

更新时间:2022.10.13 19:46:40

应用性能监控全链路版的iOS SDK基本为无侵入式,只需要根据接入章节的步骤完成SDK的初始化,引入需要的功能子库即可。

使用限制

  • 目前iOS SDK仅限中国大陆应用使用(不包括港澳台地区)。
  • 如果您的产品形态为 SDK,请参考此文档接入;如果您的产品形态为 APP,请参考iOS SDK接入
  • 组件监控能力并不完全对标APP监控能力,目前仅支持如下功能:崩溃监控、自定义错误、事件埋点。

注意

SDK会在初始化的时候就采集用户信息,请确保采集用户信息之前已经获得用户授权。
请确保您的用户在同意隐私协议后,再初始化APMSDK。

步骤一:获取SDK包

在 Podfile 中添加如下代码,然后执行 pod install 或者 pod update 安装SDK。

source 'https://github.com/volcengine/volcengine-specs.git'

  pod 'RangersAPM', '3.0.0', :subspecs => [
      'Crash',
      'WatchDog',
      'UserException',
      'EventMonitor',
      'SessionTracker',
      'CN'  #必须引入
  ]

引入字库,请参见4.subspecs说明

步骤二:初始化

在 SDK 的初始化代码中添加如下代码。

#import <RangersAPMForSDK.h>

- (void)init {

    RangersAPMForSDKConfig *sdkConfig = [RangersAPMForSDKConfig configWithSDKID:@"{{sdk_id}}" appToken:@"{{app_token}}"];
  	sdkConfig.channel = @"Cocoapods";   //SDK发布渠道,非必填
  	sdkConfig.hostAppID = @"host_app_id"; //宿主APP标识,非必填
  	sdkConfig.sdkVersion = @"1.0.0";   //SDK版本,必填
   
  	RangersAPMForSDK *sdkMonitor = [[RangersAPMForSDK alloc] initWithConfig:sdkConfig];
  
    return YES;
}

[RangersAPMForSDKConfig configWithSDKID:@"{{app_id}}" appToken:@"{{app_token}}"] 中的 {{app_id}} 替换为创建的应用对应的id,{{app_token}}替换为创建的应用对应的AppToken。
例如:[RangersAPMForSDKConfig configWithSDKID:@"2338" appToken:@"4f16"]

说明

代码初始化时机应尽量靠前,否则可能出现启动阶段(上述代码调用之前)发生的崩溃无法捕获,或者启动分析数据产生误差。

步骤三:验证数据上报

您可以根据需要,按照以下各模块说明,检查对应模块是否接入成功。

debug日志

开启Debug日志输出功能后,SDK在关键事件发生(初始化成功,上报成功等)时会向Xcode控制台输出日志,帮助您对SDK的接入和上报进行验证,参考如下代码开启:

#import <RangersAPM+DebugLog.h>

[RangersAPM allowDebugLogUsingLogger:^(NSString * _Nonnull log) {
    NSLog(@"APMInsight : %@", log);
}];
  • 支持通过修改block自定义日志输出格式。
    上述代码示例是SDK内部默认的输出格式,如果传入nil,SDK会使用默认的格式输出日志。

    [RangersAPM allowDebugLogUsingLogger:nil];
  • 请将上述代码在RangersAPM start方法之前初始化,否则对于一些同步事件可能无法输出日志。

    #if DEBUG
    [RangersAPM allowDebugLogUsingLogger:^(NSString * _Nonnull log) {
        NSLog(@"APMInsight : %@", log);
    }];
    #endif
    
    [RangersAPM startWithConfig:config];  //请先于此代码开启debug日志

测试用例

通过测试用例可以验证SDK功能是否已正确开启,您可以自己在代码中添加测试用例。如果您不了解如何添加测试用例,可以参考下面各模块给出的样例代码,或者到GitHub下载我们的Example工程作为参考。

通用

debug日志

日志内容说明
Setup APMInsight - version :APMInsight初始化开始,准备启动各功能模块,同时输出当前版本

崩溃分析

完整的崩溃分析功能需要引入如下子库:Crash、WatchDog,支持单独引入各个子库。监控组件内部发生的崩溃,首先需要获取组件的地址区间,我们提供如下两种方案:

方案1:添加标记函数

  1. 在组件中添加如下两个源文件,并定义两个函数,把一个函数的地址作为组件的起始地址,另一个函数的地址作为组件的结束地址。

    注意

    不要直接用下面的文件名和函数名,需要添加前缀,避免冲突。

    //SDKBegin.c
    
    #include "SDKBegin.h"
    extern void * SDKBeginAddress(void) {
        return &SDKBeginAddress;
    }
    
    
    //SDKEnd.c
    
    #include "SDKEnd.h"
    extern void * SDKEndAddress(void) {
        return &SDKEndAddress;
    }
  2. 在Xcode Build Phases - Compile Sources 里面调整编译顺序。
    如下所示,SDKBegin.c为第一个编译,SDKEnd.c为最后一个编译。

  • 也可以把标志 SDK 符号起始的文件,添加 AAA 前缀,把标志 SDK 符号结束的文件,添加 ZZZ 前缀。
  • 对于有多个 subspecs 的 SDK,可以添加两个 subspecs,一个为 AAA****,一个为 ZZZ***,让其他的 subspec 都依赖这两个 subspec,这样不管用户引入的是哪些 subspecs,都可以正确获取 SDK 地址区间。
  1. 在RangersAPM SDK初始化时配置config的addressConfig参数,addressConfig支持传入多个地址区间,监控多段地址。
    #import <RangersAPMForSDK.h>
    
    extern void * SDKBeginAddress;
    extern void * SDKEndAddress;
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
      NSArray * addressRanges = @[[RangersAddressRange addressRangeWithStartAddress:(int64_t)&SDKBeginAddress endAddress:(int64_t)&SDKEndAddress]];
      RangersAPMAddressConfig * addressConfig = [RangersAPMAddressConfig configWithAddressRanges:addressRanges];
    
      RangersAPMForSDKConfig *sdkConfig = [RangersAPMForSDKConfig configWithSDKID:@"{{app_id}}" appToken:@"{{app_token}}"];
      sdkConfig.addressConfig = addressConfig;
      sdkConfig.channel = @"Cocoapods";
      sdkConfig.hostAppID = @"host_app_id"; //宿主APP标识
      sdkConfig.sdkVersion = @"1.0.0";
       
      RangersAPMForSDK *sdkMonitor = [[RangersAPMForSDK alloc] initWithConfig:sdkConfig];
      
        return YES;
    }
    这种方案接入方式简单,不需要宿主APP做额外配置,但是对组件有一定的侵入性,且二进制重排后地址区间的准确性无法保证。

方案2:添加编译脚本

注意

添加的脚本是在宿主的Project中添加,而不是在组件的Project中。

  1. 下载脚本。
    APMPlus_AddressRange.sh
    9.17KB
  2. 修改脚本内容 SDKAid & SDKName。
    SDKAid="123456"
    SDKName="RangersAPM"
    writeAddressRangeFile $SDKName $SDKAid
  • SDKAid
    • 不可为空
    • APMPlus 平台上面申请的APPId
  • SDKName
    • 不可为空
    • 如果SDK是通过Cocoapods引入的,则填写Pod名称即可;如果SDK是通过下载获取的,则填写SDK包最外层的文件夹名称即可。
  • 同时监控多个SDK
    • 如果这些SDK需要汇总到一个看板,即数据上报到APMPlus同一个APPId下面,则需要修改SDKName,并使用'|'把这些SDK name分隔开,即SDKName="SDK1|SDK2|SDK3",如下所示:
      SDKAid="123456"
      SDKName="RangersAPM|RangersAppLog"
      writeAddressRangeFile $SDKName $SDKAid

    • 如果这些SDK是相对独立的,即数据上报到各自的APPId下面,此时会有多个APPId,对每一个SDK进行上述调用,如下所示:
      SDKAid1="123456"
      SDKName1="RangersAPM"
      writeAddressRangeFile $SDKName1 $SDKAid1
      SDKAid2="4567890"
      SDKName2="RangersAppLog"
      writeAddressRangeFile $SDKName2 $SDKAid2

  1. 允许生成Link Map文件:在Xcode - Build Settings 中把 Write Link Map File 置为YES。

    由于脚本执行有一定耗时,为了避免影响开发体验,建议仅在Release环境下修改Write Link Map File为YES。

  2. 把修改后的脚本粘贴到Run Script里面,完成脚本接入工作。

    添加的Run Script需要位于Copy Pods Resources之前,Compile Sources之后。您可以通过拖动来移动Run Script的位置。

    这种方案不需要在RangersAPM SDK初始化时做其他的配置,准确度比方案1更高,但是需要宿主配合在Xcode中添加脚本。

方案3:配置库名(仅适用于动态库)

在初始化应用性能监控全链路版 SDK 时,配置 RangersAPMForSDKConfig 的 libNames 属性,传入您的 SDK 包名。

测试用例

下面的代码会触发NSException类型的Crash,更多类型的case,可以下载Example工程。

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
       NSArray *array = [NSArray array];
       [array objectAtIndex:10];
   });
  1. 将上述代码嵌入您的APP代码中。
  2. 在Xcode中,修改Build Configuration为Release,然后通过Run把APP安装到模拟器或者真机
  3. 在模拟器或者真机中打开APP,然后等待崩溃代码执行,APP闪退。

    注意

    不要直接通过Xcode Run启动APP,这样触发的崩溃无法捕获。

  4. 重新启动APP,SDK会立即上报上一次启动期间发生的崩溃。
    您可以通过Xcode Run启动APP,而且您可以在控制台看到上报成功的日志。

debug日志

日志内容说明
Crash-Monitor start successfully!崩溃监控模块启动成功
WatchDog-Monitor start successfully!卡死监控模块启动成功
Crash log is uploading...开始上传崩溃日志
Crash log is uploaded successfully!崩溃日志上报成功
Watchdog log is uploading...开始上传卡死日志

自定义错误错误

自定义错误模块需要引入子库UserException,自定义错误为自埋点功能,需要手动调用接口来记录APP发生的错误,并上报到火山引擎应用性能监控全链路版平台,统一查看。

测试用例

下面的代码会记录一条自定义错误日志,SDK每记录5条日志会触发一次上报。网络错误日志可以通过发送一次会发生错误的网络请求来自动记录,可以参考Example工程。

#import <RangersAPMForSDK+UserException.h>

//获取之前初始化的实例,需要先参考 初始化 章节初始化一个实例
RangersAPMForSDK *sdkMonitor = [RangersAPMForSDK monitorWithSDKID:@"{{sdk_id}}"];

[sdkMonitor trackAllThreadsLogExceptionType:@"testUserException" 
                               skippedDepth:0  
                             customParams:@{@"testCustomKey":@"testCustomValue"}
                                  filters:@{@"testFilterKey":@"testFilterValue"}
                                 callback:^(NSError * _Nullable error){
                                    NSLog(@"%@",error); 
                                 }
];

debug日志

日志内容说明
UserException-Monitor start successfully!自定义错误监控模块启动成功

事件分析

事件分析模块是一个自埋点功能,需要您手动调用接口来进行事件的记录,使用该功能需要引入EventMonitor模块。

测试用例

可以通过如下代码记录一个事件,相关参数可以查看头文件介绍。

#import "RangersAPMForSDK+EventMonitor.h"
  
//获取之前初始化的实例,需要先参考 初始化 章节初始化一个实例
RangersAPMForSDK *sdkMonitor = [RangersAPMForSDK monitorWithSDKID:@"{{app_id}}"];

[sdkMonitor trackEvent:@"event_name1"
               metrics:@{@"metric1":@(0)}
             dimension:@{@"dimension1":@"test"}
            extraValue:@{@"extra1":@"extravalue"}];
  1. 只有在应用性能监控全链路版上创建过,且事件状态为开启或验证中,且客户端命中事件采样规则,才会记录并上报该事件。
  2. Metrics 参数只支持Key为NSString类型,Value为NSNumber类型的NSDictionary对象;dimension只支持Key和Value都为NSString类型的NSDictionary对象;同时两个参数均不支持嵌套结构。
  3. 事件记录后不会立即上报,客户端上报规则如下:APP启动之后触发一次上报,每经过120s触发一次上报,当APP状态切换到background时触发一次上报。

debug日志

日志内容说明
Record an event-log successfully, name:成功记录一条事件日志,并输出事件名称

Subspecs说明

子库名称功能简介对应平台模块开始支持版本
Crash崩溃监控:捕获CPP Exception、Mach Exception、NSException Exception 和 Signal Exception崩溃分析2.8.1
WatchDog卡死监控:监控主线程长时间卡住被系统 watchdog 给强杀的情况崩溃分析2.8.1
UserException自定义错误,需要业务方手动打点错误分析-自定义错误2.8.1
EventMonitor事件分析,记录自定义事件,需要手动埋点事件分析2.8.1
SessionTrackerPV/UV统计,接入后会自动上报数据各模块异常率、异常用户比例等2.8.1
BootingProtectLite连续崩溃保护\2.10.0

符号表上传

注意

组件监控的崩溃日志需要上传了符号表才能解析。如果您的 SDK 是静态库,符号表是接入宿主APP后,宿主APP打包产生的符号表。

手动上传

  1. 请确保您的符号表满足如下格式。

  2. 把符号表压缩为zip文件。
    Mac 下 zip 需要去除默认生成 DS_Store __MACOSX 文件。可以用如下命令(将test.app.dSYM.zip 和 test.app.dSYM 替换为您的符号表名称)。

    zip -r test.app.dSYM.zip test.app.dSYM -x "*.DS_Store" -x "__MACOSX"
  3. 上传符号表。

  • 在 "符号表管理" 模块上传符号表。
  • 使用curl命令上传。
    curl	https://console.volcengine.com/apmplus_api/eue/guest/app/mapping/upload	-F	"file=@dSYMZipName"	-F	"type=Dwarf"	-F	"os=iOS"	-F	"aid=APMInsightID"	-H	"Content-Type:	multipart/form-data"	-w	%{http_code}
  • 需要注意将命令参数值用 ' " ' 包起来,否则参数中的空格可能导致命令解析错误。
  • 将上述命令中的 dSYMZipName 替换为您的符号表文件路径, APMInsightID 替换为您的AppID。
  • 执行完成后,命令行输出如下即说明上传成功。

自动上传

在Xcode中对应Target下配置Build Phases、添加Run Script,可以实现APP打包时自动上传符号表。

说明

默认Debug模式和模拟器编译不会上传符号表,如果需要在这两种情况下上传符号表,请参考下述 3.ii 部分内容

  1. 检查工程配置是否生成符号表,位置Build Settings - Debug Infomation Format。

  2. 添加Run Script。

    说明

    请将添加的这个Run Script置于最后,避免脚本执行时符号表还没有生成,如下图所示(可以通过拖动调整顺序)

  3. 修改脚本内容。

    • 如果您接入的SDK版本大于1.5.0(包含),仅需要在脚本中添加/bin/sh ${PODS_ROOT}/RangersAPM/RangersAPM/APMInsight_DSYMUploader.sh "APMInsightID" ,并将命令中的 APMInsightID 替换为您的应用ID即可,这种方式在Debug模式和模拟器编译时不会上传符号表。

    • 如果您接入的SDK为较低版本且不想升级为更高版本,或者需要Debug模式和模拟器编译也能自动上传符号表。

      1. 下载脚本文件。

        APMInsight_DSYMUploaderV1.1.sh
        5.57KB

      2. 将下载的脚本文件内容复制到Run Script中,并修改APMInsight_APP_ID为您的应用ID。

      3. 根据需要,修改脚本中的 UPLOAD_DEBUG_SYMBOLS 和 UPLOAD_SIMULATOR_SYMBOLS字段。

SDK扩展功能说明

自定义数据与自定义维度

使用如下接口,您可以添加一些自定义的环境或业务信息,如用户email、定位信息、业务场景等,这些信息会随着SDK的日志一同上报,帮助您排查一些问题,您可以在应用性能监控全链路版上的日志详情页看到这些信息。

#import <RangersAPMForSDK.h>

//获取之前初始化的实例,需要先参考 初始化 章节初始化一个实例
RangersAPMForSDK *sdkMonitor = [RangersAPMForSDK monitorWithSDKID:@"{{app_id}}"];

//自定义key-value
[sdkMonitor setCustomContextValue:@"sdk1context1value" forKey:@"sdk1context1key"];

除了上报自定义数据外,您也可以在需要的时候添加一些自定义维度,作为自定义的的筛选项,用来筛选某些特定情况下的日志。

#import <RangersAPMForSDK.h>

//获取之前初始化的实例,需要先参考 初始化 章节初始化一个实例
RangersAPMForSDK *sdkMonitor = [RangersAPMForSDK monitorWithSDKID:@"{{app_id}}"];

//自定义筛选项
[sdkMonitor setCustomFilterValue:@"sdk1filter1value" forKey:@"sdk1filter1key"];

连续崩溃保护

连续崩溃保护需要接入SDK的BootingProtectLite模块,参考Subspecs说明。使用此功能,您可以在应用发生连续的崩溃时进行一些本地的处理,例如清理缓存、删除文件等。

#import <RangersAPMForSDK+BootingProtect.h>

		//获取之前初始化的实例,需要先参考 初始化 章节初始化一个实例
		RangersAPMForSDK *sdkMonitor = [RangersAPMForSDK monitorWithSDKID:@"{{app_id}}"];
    [sdkMonitor startProtectWithBootingThreshold:10 bootingCrashHandler:^(RangersAPMBootingInfo * _Nonnull info) {
        /**
         对连续异常的场景进行防护策略,这里的demo只输出了一些log,您可以在自己的应用中做一些本地缓存清理或其他策略。可以针对不同的异常发生次数制定不同的策略。
         */
        if (info.consecutiveExceptionTimes >= 1) {
            NSLog(@"⚠️Consecutive exception 1 time");
        } else if (info.consecutiveExceptionTimes >= 3) {
            NSAssert(NO, @"⚠️Consecutive exception 3 times !!!");
        }
        
        /**
         除了对连续异常进行防护,您也可以针对不同的异常类型执行不同的防护策略。
         */
        if (info.crashTimes >= 1) {
            NSLog(@"⚠️Consecutive crash 1 time");
        }
        if (info.watchdogTimes >= 1) {
            NSLog(@"⚠️Consecutive watchdog 1 time");
        }
    }];

关于获取设备数与用户数

1. 使用应用性能监控全链路版 SDK 自身服务

应用性能监控全链路版 SDK 内部默认使用自身服务生成的 deviceID 用以标识一台设备和用户,如果您不想使用应用性能监控全链路版 SDK 自身服务生成的 deviceID,我们也提供了其他方案供您参考,使用其他方案则 SDK 内部不会再次请求自身服务生成 deviceID。

2. 使用自己的DeviceID

如果您想要使用自己的deviceID,请参考如下方式:

  1. 配置应用性能监控全链路版 SDK初始化config的deviceIDSource。

  2. 在应用性能监控全链路版 SDK初始化方法之后,设置deviceID。

    #import <RangersAPMForSDK.h>
    
    - (void)init {
        
        RangersAPMForSDKConfig *sdkConfig = [RangersAPMForSDKConfig configWithSDKID:@"{{app_id}}" appToken:@"{{app_token}}"];
        sdkConfig.channel = @"Cocoapods";
        sdkConfig.hostAppID = @"host_app_id"; //宿主APP标识
        sdkConfig.sdkVersion = @"1.0.0";
        sdkConfig.deviceIDSource = RAPMDeviceIDSourceFromUser;
       
        RangersAPMForSDK *sdkMonitor = [[RangersAPMForSDK alloc] initWithConfig:sdkConfig];
        
        [sdkMonitor setDeviceID:@"MYDEVICEID"];
      
        return YES;
    }