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

iOS SDK接入

更新时间:2023.06.09 15:38:40

应用性能监控全链路版的iOS SDK基本为无侵入式,App接入SDK后可以进行崩溃分析、错误分析、卡顿分析等各种监控指标的分析,帮助优化和定位问题。本文介绍产品形态为App的详细的接入步骤。

使用限制

目前iOS SDK仅限中国大陆应用使用(不包括港澳台地区)。

注意事项

调用SDK初始化接口不会采集用户信息,调用SDK启动接口会开始采集用户信息,请确保采集用户信息之前已经获得用户授权SDK隐私政策

Demo示例

APMInsight_iOS

  • Demo已经接入了SDK的所有能力。
  • 您可以通过Demo制造一些崩溃和性能数据。
  • 可以修改Demo中的appID和appToken,把性能数据上报到控制台以查看。

步骤一:获取SDK包

  1. 在Podfile中添加如下示例代码。

    source 'https://github.com/volcengine/volcengine-specs.git'
    
    pod 'RangersAPM', '3.3.2', :subspecs => [
        'Crash',
        'WatchDog',
        'OOM',
        'LAG',
        'UserException',
        'Monitors',
        'UITrackers',
        'Hybrid',
        'MemoryGraph',
        'NetworkPro',
        'EventMonitor',
        'SessionTracker',
        'APMLog',
        'CrashProtector',
        'CPUException',
        'MetricKit',
        'Disk',
        'GWPASan',
        'Coredump',
        'CN'  #必须引入
    ]

    添加 上述代码会引入应用性能监控全链路版SDK的所有功能,如果不想引入全部功能,可以参考 Subspec说明 按需引入子库 。

  2. 执行以下命令,安装SDK。

    pod install

步骤二:初始化

建议在AppDelegate.m的application didFinishLaunchingWithOptions:方法中(或者在用户同意隐私政策之后的合适时机)添加如下示例代码。

#import <RangersAPM.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    RangersAPMConfig *apmConfig = [RangersAPMConfig configWithAppID:@"{{app_id}}" appToken:@"{{app_token}}"];
    //{{app_id}}和{{app_token}}须替换为您创建的应用对应的AppID和AppToken,具体请参见如何查询AppID和AppToken?。
    apmConfig.channel = @"App Store";
    
    /**
     首次启动由于没有获取到配置,无法确定需要开启哪些功能模块。可以配置此属性,来决定首次启动默认需要开启的功能模块,仅对首次启动生效,一旦拉取到配置,下次启动就会先读取本地缓存的配置来决定。
1. 建议默认开启崩溃分析(RangersAPMCrashMonitorSwitch)、启动分析(RangersAPMLaunchMonitorSwitch)、网络分析(RangersAPMNetworkMonitorSwitch),避免一些和首次启动强相关的数据丢失.
2. 配置默认开启模块后,新设备首次启动会默认打开这些模块,可能会出现平台上关闭了这些模块,但是依然有数据上报的情况,可能会给您的事件量造成意外的消耗;请根据您的应用情况灵活配置。
3. 配置多个模块可以参考这种写法:RangersAPMCrashMonitorSwitch | RangersAPMNetworkMonitorSwitch | RangersAPMLaunchMonitorSwitch
     */
    apmConfig.defaultMonitors = RangersAPMCrashMonitorSwitch;

    return YES;
}

步骤三:启动SDK,开启数据采集

建议在AppDelegate.m的application didFinishLaunchingWithOptions:方法中(或者在用户同意隐私政策之后的合适时机)且SDK初始化之后添加如下示例代码。

#import <RangersAPM.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 使用初始化阶段获取的config启动SDK
    [RangersAPM startWithConfig:apmConfig];
    [RangersAPM setUserID:@"xxxx"];
    [RangersAPM setDeviceID:@"xxxx"]; //使用自定义deviceID,需要参考获取设备数与用户数章节,先修改apmConfig的相关参数
    return YES;
}

说明

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

步骤四:上传符号表

手动上传

  1. 验证符号表满足以下格式。
    图片

  2. 把符号表压缩为zip文件。
    Mac中zip需要去除默认生成的 DS_Store__MACOSX 文件。执行以下命令将 test.app.dSYM.ziptest.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模式和模拟器编译不会上传符号表。

  1. 选择Build Settings > Debug Infomation Format下,检查工程配置是生成符号表。
    图片

  2. 选择Build Phases > New Run Script Phase,添加Run Script。
    图片

  3. 将添加的Run Script置于最后,防止脚本执行时符号表还没有生成。
    图片

  4. 在脚本中添加以下命令,在Debug模式和模拟器编译时不会上传符号表。

    /bin/sh ${PODS_ROOT}/RangersAPM/RangersAPM/APMInsight_DSYMUploader.sh "APMInsightID"
    • APMInsightID须替换为您的应用ID。
    • 接入的SDK版本需要大于等于1.5.0。

特殊场景

当接入的SDK为较低版本且不想升级为更高版本,或者需要Debug模式和模拟器编译也能自动上传符号表,请执行以下操作:

  1. 下载脚本文件。
    APMPlus_DSYMUploaderV2.0.sh
    5.53KB
  2. 将下载的脚本文件内容复制到Run Script中,并修改APMPlus_APP_ID为您的应用ID。
  3. 根据需要,修改脚本中的UPLOAD_DEBUG_SYMBOLS和UPLOAD_SIMULATOR_SYMBOLS字段。
    图片

步骤五:验证数据上报

您可以根据业务需要,按照以下各模块说明检查对应模块是否接入成功。每个模块的说明主要包含以下两个部分:

  • 测试用例
    通过在项目中添加样例代码并在合适的时机触发,来验证SDK能否捕获对应事件的日志。您可以参见各模块给出的样例代码和说明,或者参见 Example工程

  • 日志说明
    开启Debug日志输出功能后,SDK在初始化成功、上报成功等关键时刻,会向Xcode控制台输出日志,帮助您对SDK的接入和上报进行验证。
    示例代码如下所示:

    #import <RangersAPM+DebugLog.h>
    
    #if DEBUG
                    //通过修改block,您可以定制自己的日志输出格式,下述代码示例是SDK内部默认的输出格式,如果您传入nil,则SDK会使用默认的格式输出日志。
        [RangersAPM allowDebugLogUsingLogger:^(NSString * _Nonnull log) {
            NSLog(@"APMInsight : %@", log);
        }];
    #endif
    
                    //请先于此代码开启debug日志,否则对于一些同步事件可能无法输出日志
        [RangersAPM startWithConfig:config];

    通用日志说明如下表所示:

    日志

    说明

    AppLog registered successfully! UserInfo:

    AppLog注册完成,同时输出注册的信息。
    如果没有使用RangersAppLog的设备注册,则不用关注。

    Setup APMInsight - version :

    APMInsight初始化开始,准备启动各功能模块,同时输出当前版本

崩溃分析

完整的崩溃分析功能需要引入子库,包括Crash、WatchDog、OOM,支持单独引入各个子库。
如果只需要OOM功能,请同时引入Crash、WatchDog,否则OOM的数据可能不准确。

测试用例

以下示例代码会触发NSException类型的Crash。更多类型的Crash,请参见Example工程

  1. 添加以下代码到您的APP代码中。

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSArray *array = [NSArray array];
            [array objectAtIndex:10];
        });
  2. 在Xcode中,修改Build Configuration为Release,然后通过Run把APP安装到模拟器或者真机。

  3. 在模拟器或者真机中打开APP,然后等待崩溃代码执行,APP闪退。

    注意

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

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

日志说明

日志

说明

Crash-Monitor start successfully!

崩溃监控模块启动成功

WatchDog-Monitor start successfully!

卡死监控模块启动成功

OOMCrash-Monitor start successfully!

OOM监控模块启动成功

Crash log is uploading...

开始上传崩溃日志

Crash log is uploaded successfully!

崩溃日志上报成功

Watchdog log is uploading...

开始上传卡死日志

OOM log is uploading...

开始上传OOM日志

错误分析

错误分析模块分为自定义错误和网络错误。

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

测试用例

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

#import <RangersAPM+UserException.h>

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

如果您在安装的SDK时无法找到以上头文件及接口,请检查SDK的版本,将其升级至1.1.0以上,或者参考以下代码记录自定义错误。

#import <RangersAPMUserExceptionManager.h>
            
    [RangersAPMUserExceptionManager trackAllThreadsLogExceptionType:@"testUserException" 
                       skippedDepth:0 
                       customParams:@{@"testCustomKey":@"testCustomValue"} 
                            filters:@{@"testFilterKey":@"testFilterValue"}
                           callback:^(NSError * _Nullable error) {
                                 NSLog(@"%@",error);}
    ];

说明

网络错误日志记录后不会立即上报,在以下时间会自动上报:

  • APP启动15s之后,触发一次上报。
  • 每经过120s,触发一次上报。
  • 当APP状态切换到background时,触发一次上报。

日志说明

日志

说明

UserException-Monitor start successfully!

自定义错误监控模块启动成功

Network-Monitor start successfully!

网络监控模块启动成功

卡顿分析

卡顿分析模块需要引入子库LAG。

测试用例

通过阻塞主线程来模拟一个卡顿事件。阻塞时间需要大于您在平台上配置的卡顿阈值,才能被SDK捕获上报,如果您未修改过此值,默认阈值为3s。

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    sleep(5);
});

说明

  • 同一次APP启动期间,发生的相同场景卡顿不会重复记录。
  • 如果您需要在卡顿场景发生时做一些自主处理,请参见通知

日志说明

日志

说明

Lag-Monitor start successfully!

卡顿监控模块启动成功

Lag log is uploading...

开始上传卡顿日志

事件分析

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

测试用例

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

#import "RangersAPM+EventMonitor.h"
  
  [RangersAPM trackEvent:@"event_name1"
          metrics:@{@"metric1":@(0)}
         dimension:@{@"dimension1":@"test"}
        extraValue:@{@"extra1":@"extravalue"}];

Metrics参数和dimension参数支持说明:

  • Metrics参数只支持Key为NSString类型,Value为NSNumber类型的NSDictionary对象。
  • dimension参数只支持Key和Value都为NSString类型的NSDictionary对象。
  • 两个参数均不支持嵌套结构。
    使用事件分析模块需要注意以下内容:
  • 只有在应用性能监控全链路版上创建过,且事件状态为开启或验证中,且客户端命中事件采样规则,才会记录并上报该事件。
  • 事件记录后不会立即上报,客户端上报规则如下:
    • APP启动之后,触发一次上报。
    • 每经过120s,触发一次上报。
    • 当APP状态切换到background时,触发一次上报。

日志说明

日志

说明

Record an event-log successfully, name:

成功记录一条事件日志,并输出事件名称。

用户体验

用户体验模块分为启动分析、页面响应分析、流畅性分析。启动分析模块和流畅性分析模块需要引入子库Monitors,页面响应分析模块需要引入子库UITrackers。

测试用例

用户体验模块日志会在APP状态、场景发生变化时进行记录,触发方式如下:

  • 启动分析
    • 在APP启动时会记录冷启动日志,该日志不可手动触发,且对于APP的每次启动只会记录一条冷启动日志。
    • 在APP从后台切换到前台会记录热启动日志,可以通过前后台切换来进行触发。
  • 页面响应日志
    当APP发生场景切换时会记录页面响应日志,日志包含如下阶段的耗时:loadView、viewDidLoad、viewWillAppear、viewDidAppear,可以通过切换viewController来触发。

说明

用户体验日志记录后不会立即上报,在以下时间会自动上报:

  • APP启动15s之后,触发一次上报。
  • 每经过120s,触发一次上报。
  • 当APP状态切换到background时,触发一次上报。

日志说明

日志内容

说明

Start-Monitor start successfully!

启动监控模块启动成功

FPS-Monitor start successfully!

流畅性监控模块启动成功

FrameDrop-Monitor start successfully!

掉帧分析模块启动成功

PageLoad-Monitor start successfully!

页面响应分析模块启动成功

页面监控

页面监控模块会捕获APP的WebView发生的加载、请求和错误事件,开启功能需要引入子库Hybrid。

测试用例

您可以在APP中弹出应用的WebView页面,也可以使用控制台页面来触发一些异常事件:
https://datarangers.com.cn/apminsight/demo/demo/rangers-site-hybrid-sdk-script

说明

页面监控日志记录后不会立即上报,在以下时间会自动上报:

  • APP启动15s之后,触发一次上报。
  • 每经过120s,触发一次上报。
  • 当APP状态切换到background时,触发一次上报。

日志说明

日志内容

说明

Hybrid-Monitor start successfully!

Hybrid监控模块启动成功

内存优化

内存优化模块会在APP使用内存过高(超过1GB)时,采集当前状态下的所有内存节点和引用关系,生成内存快照文件并上传。对应的,在平台上可以看到内存过高时APP的内存分配情况、通过现场信息排查内存泄漏或者大内存分配等问题。开启内存优化功能需要引入子库MemoryGraph。

说明

  • 内存采集有一定的性能损耗,由于采集内存需要保证堆安全,当触发内存采集时会挂起线程,此间用户操作会被阻塞,造成一种“卡顿”现象。不过,内存采集仅当内存占用超出异常阈值时才会触发,对正常使用的用户没有影响。
  • 内存分析功能只能在64位真机设备触发,只支持iPhone 6s及更高机型,要求操作系统iOS10+。
    以iPhone 8Plus机型为例,当APP内存占用超过1G时 :
    • 采集用时1.5s~2s
    • 采集时额外内存消耗10M~20M
    • 生成的文件压缩后5M~20M

测试用例

添加以下代码,调用OOMTrigger函数触发内存泄漏。

#import <mach/mach.h>
    //设置的内存采集启动阈值,当APP内存超过此值时将启动内存优化模块,采集APP内存状态
    static float dangerousMemoryThreshold = 1024.0;
            
    //计算APP当前的内存占用,当内存占用超过内存采集启动阈值时,返回true,否则返回false
    bool overMemoryThreshold(void)
    {
        kern_return_t kr;
                
        task_vm_info_data_t task_vm;
        mach_msg_type_number_t task_vm_count = TASK_VM_INFO_COUNT;
        kr = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t) &task_vm, &task_vm_count);
                   
        if (kr == KERN_SUCCESS) {
            printf("Current App Memory is :%f\n\n", task_vm.phys_footprint / (1024.0 * 1024.0));
            if (task_vm.phys_footprint / (1024.0 * 1024.0) > dangerousMemoryThreshold) {
                return true;
            } else {
                return false;
            }
        }
            
        return false;
    }
            
    //触发内存泄漏,当APP当前内存占用小于内存采集启动阈值时,会不断触发内存泄漏
    - (void)OOMTrigger{
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            while (1) {
                if (!overMemoryThreshold()) {
                    CGSize size = CGSizeMake(1024 * 8, 1024 * 8 * 9.0f/16.0);
                    const size_t bitsPerComponent = 8;
                    const size_t bytesPerRow = size.width * 4;
                    CGContextRef ctx = CGBitmapContextCreate(calloc(sizeof(unsigned char), bytesPerRow * size.height), size.width, size.height, bitsPerComponent, bytesPerRow, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast);
                    CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
                    CGContextFillRect(ctx, CGRectMake(0, 0, size.width, size.height));
                    sleep(1);
                } else {
                    break;
                }
            }
        });
    }

dangerousMemoryThreshold变量的值须修改为您在平台上配置的内存采集启动阈值。如果您未配置或修改过此值,则无需修改。
使用内存优化需要注意以下内容:

  • 开启内存优化采集策略:当APP的内存超过内存采集启动阈值时,启动内存优化模块,采集APP内存状态。
    内存采集启动阈值默认值为1024MB。某些场景,APP内存占用没有达到默认值,就被系统中断,您可以在平台的 SDK上报配置 > 内存优化 中调整取值。
  • 采集后上报策略:APP内存状态采集之后,会在下一次APP启动时进行上报。上报内存文件前,会先向Server请求是否允许上传。
    如果Server不允许上传的话,则会在下一次APP启动时重新请求。未通过请求的内存文件会缓存在APP的沙盒中,当Server允许上传时一起上传。
    如何判断Server是否允许上传:
    • 查看DebugLog。
    • 通过Charles抓包,查看接口的返回值:https://apmplus.volces.com/monitor/collect/c/ios_memory_upload_check
      如果该接口的返回结果为true,则说明本次内存文件上传被允许。
      图片
  • 其他配置:C++本地符号化是否开启
    MemoryGraph默认关闭C++本地符号化。如果需要开启,可以在平台的 SDK上报配置 > 内存优化 中手动配置。
  • 其他配置:本模块允许占用的最大内存
    MemoryGraph对自身占用的内存大小进行了限制,当自身占用的内存大小会超过阈值时,或者APP当前可用内存小于此阈值时,会触发降级。当触发降级时,SDK只采集节点信息,不采集引用信息。在 单设备查询 表现为只有聚类列表,没有引用树、支配树等信息。
    本模块允许占用的最大内存默认值为200MB,可以在平台的 SDK上报配置 > 内存优化 中手动配置此阈值。
  • 其他配置:日志文件占用的最大磁盘空间
    SDK对生成的内存快照文件占用的磁盘空间进行了限制,当内存节点数量过多,可能会超出磁盘空间限制,会触发降级。
    日志文件占用的最大磁盘空间默认值为250MB,可以在平台的 SDK上报配置 > 内存优化 中手动配置此阈值,来放宽限制。注意不要把阈值设置的过大,否则下次启动上传时内存文件加载可能会再次触发OOM。
    那么,阈值调整为多大比较合适呢?
    • MemoryGraph判断SDK模块自身占用内存大小是否会超出阈值的算法为:当自身占用的内存大小上限为100MB时,则内存节点数超出260W~ 270W(存在浮动)会触发降级,等比例增加。
    • 阈值不宜过大,否则当APP可用内存小于阈值时,会触发降级。建议配置的阈值为100MB~ 200MB,如果节点数非常多,可以通过调小内存采集启动阈值来减少节点数,进而避免降级。

日志说明

日志

说明

OOMCrash-Monitor start successfully!

OOM崩溃监控模块启动成功

MemoryGraph start successfully!

MemoryGraph模块启动成功

MemoryGraph start failed. Reason: ...

MemoryGraph模块启动失败,原因:...

Memory-Monitor start successfully!

内存指标监控模块启动成功

MemoryGraph generate start.

APP内存达到阈值,启动内存采集

MemoryGraph generate failed, reason :

内存采集失败,并输出错误原因

MemoryGraph generate successfully!

内存采集成功

Upload MemoryGraph -- server check failed.

Server当前不允许上传MemoryGraph file

MemoryGraph file is uploading...

正在上传MemoryGraph file

Upload MemoryGraph file successfully!

上传MemoryGraph file成功

Upload MemoryGraph file failed.

上传MemoryGraph失败

网络分析

网络分析模块需要引入子库Network。

测试用例

您可以通过发送一些网络请求来触发SDK网络数据记录。

说明

  • 网络分析日志记录后不会立即上报,在以下时间会自动上报:
    • APP启动15s之后,触发一次上报。
    • 每经过120s,触发一次上报。
    • 当APP状态切换到background时,触发一次上报。
  • 如果您不想或者只想监控某些URL的网络请求,可以在网络请求配置中进行配置。

日志说明

日志内容

说明

Network-Monitor start successfully!

网络监控模块启动成功

日志回捞

日志回捞模块需要引入子库APMLog。通过使用SDK提供的接口进行打点,可以记录一些APP运行期间产生的日志。此模块是一种基于mmap的高效率的日志打点框架,日志压缩率高达25倍,结合云控可以做到线上用户日志的实时定向回捞,帮您高效率,精准的定位、解决问题。
日志不会全部上报,获取这些日志的方式如下:

  • 崩溃发生后自动上报崩溃发生前一段时间产生的日志。
    上报的日志在崩溃详情页的自定义日志里查看。
  • 通过下发云控命令获取指定设备/用户、指定时间内产生的日志。
    更多信息请参见 日志回捞

测试用例

对于C/C++、Objective-C、Swift,APMPlus提供了三类日志打点的接口,每一类有四个接口,分别为Debug、Info、Warn、Error,代表日志严重程度的四个等级,可以在平台查看日志时进行筛选。

//无论使用哪类接口,首先都需要先调用如下接口开启Alog功能
//注意:仅在APP启动时调用一次即可
#import "RangersAPM+ALog.h"

[RangersAPM setALogEnabled];  //启用Alog
[RangersAPM enableConsoleLog];  //同时在控制台输出日志

//Objective-C 可以使用如下接口进行日志打点
#import "RangersAPM+ALog.h"

//第一个参数标识当前日志的业务、场景等信息;
//第二个参数为日志具体信息,可以使用format类型,如果使用format,需要继续传入对应的参数
 RANGERSAPM_ALOG_DEBUG(@"Business", @"version : %@", [self version]);  //Debug类日志
 RANGERSAPM_ALOG_INFO(@"Business", @"version : %@", [self version]);   // Info类日志
 RANGERSAPM_ALOG_WARN(@"Business", @"version : %@", [self version]);   //Warn类日志
 RANGERSAPM_ALOG_ERROR(@"Business", @"version : %@", [self version]);   //Error类日志
  
  
  
//C/C++ 可以使用如下接口进行日志打点
#import "RangersAPM_ALog.h"
 
//第一个参数标识当前日志的业务、场景等信息;
//第二个参数为日志具体信息,可以使用format类型,如果使用format,需要继续传入对应的参数
 RANGERSAPM_ALOG_DEBUG_C("Business", "version : %s", version());
 RANGERSAPM_ALOG_INFO_C("Business", "version : %s", version());
 RANGERSAPM_ALOG_WARN_C("Business", "version : %s", version());
 RANGERSAPM_ALOG_ERROR_C("Business", "version : %s", version());
 
 
 
//Swift 可以使用如下接口进行日志打点
#import "RangersAPM+ALog.h"

//第一个参数为日志具体信息
//tag 标识当前日志的业务、场景等信息;
//fileName 为当前所在文件名,可以参考示例传入 #file
//funcName 为当前所在方法名,可以参考示例传入 #function
//line 为当前所在文件的行号,可以参考示例传入 #line
RangersAPM.debugALog("alogtest", tag: "Business", fileName: #file, funcName: #function, line: #line)
RangersAPM.infoALog("alogtest", tag: "Business", fileName: #file, funcName: #function, line: #line)
RangersAPM.warnALog("alogtest", tag: "Business", fileName: #file, funcName: #function, line: #line)
RangersAPM.errorALog("alogtest", tag: "Business", fileName: #file, funcName: #function, line: #line)

日志说明

日志内容

说明

ALog is uploaded successfully!

(回捞)自定义日志上报成功

Upload ALog failed, reason :

(回捞)自定义日志上报失败,并输出原因

ALog is uploaded manually!

手动上报自定义日志成功

Manually upload ALog failed

手动上报自定义日志失败

CloudCommand start successfully!

回捞功能启动成功

CloudCommand is being executed ...

回捞指令正在执行

ALog start successfully!

自定义日志功能启动成功

CPU监控

CPU监控模块包含两个子模块:

  • CPU指标
    CPU指标会监控APP运行过程中的CPU使用情况,需要引入Monitors子库,同时SDK版本需要高于2.7.3。
  • CPU异常
    CPU异常会监控APP运行过程中CPU使用率过高的场景,并记录当时的调用堆栈,需要引入子库CPUException。

测试用例

CPU指标会在APP运行时自动上报。以下示例代码模拟CPU使用率过高场景,触发CPU异常的上报。

for (int i = 0; i < 10; i++) {
        NSString *queueName = [NSString stringWithFormat:@"com.apmplus.testcpu%d",i];
        dispatch_queue_t queue = dispatch_queue_create([queueName UTF8String], DISPATCH_QUEUE_SERIAL);
                dispatch_async(queue, ^{
                        int count = 0;
                        while (1) {
                                count++;
                        }
                });
}

日志说明

日志

说明

CPUException log is uploading...

CPU异常日志正在上报

CPUException-Monitor start successfully!

CPU异常监控功能启动成功

Record CPUException log successfully!

成功记录CPU异常日志

CPUMetric-Monitor start successfully!

CPU指标监控功能启动成功

MetricKit

MetricKit模块会监控MetricKit.framework生成的系统日志,并上报给平台。如需接入,请引入MetricKit子库,同时APMPlus SDK版本需要高于2.12.1。

测试用例

系统会每天生成一份MetricKit日志,提供给业务方。如果想测试是否接入成功,请真机调试状态下,操作如图所示:
图片

日志说明

日志

说明

MetricKit start successfully!

MetricKit模块启动成功

Disk

Disk模块会监控沙盒的使用情况。同时,将生成指标和异常信息上报给平台。如需接入,请引入Disk子库,同时APMPlus SDK 版本需要高于3.0.0。

测试用例

为了防止检索沙盒文件,影响用户体验。磁盘监控启动时,Disk模块会在程序后台检索沙盒文件并上报。

Subspecs说明

子库名称

功能简介

对应平台模块

开始支持版本

Crash

崩溃监控:捕获CPP Exception、Mach Exception、NSException Exception 和 Signal Exception

崩溃分析

0.0.5

WatchDog

卡死监控:监控主线程长时间卡住被系统 watchdog 给强杀的情况

崩溃分析

0.0.5

OOM

Out of memory 监控

崩溃分析内存优化-OOM趋势

0.0.5

LAG

卡顿监控:监控主线程短时间内无法响应的情况

卡顿分析

0.0.5

UserException

自定义错误,需要业务方手动打点

错误分析-自定义错误

0.0.5

Monitors

启动分析:流畅性:

用户体验-启动分析用户体验-页面体验内存优化-OOM趋势-扩展指标

0.0.7

UITrackers

页面分析:

用户体验-页面体验-页面响应

0.0.7

Hybrid

WKWebView H5 页面监控

页面监控

0.0.8

MemoryGraph

内存分析,获取某一时刻APP的内存状态

内存优化

0.0.8

Network

网络分析:网络错误,Http、DNS分析

网络分析错误分析-网络错误

1.0.0

EventMonitor

事件分析,记录自定义事件,需要手动埋点

事件分析

2.0.0

Flutter

Flutter监控,需要参考Flutter接入文档接入

Flutter监控

2.2.1

SessionTracker

PV/UV统计,接入后会自动上报数据

各模块异常率、异常用户比例等

2.3.0

APMLog

APM日志库,可以手动打点记录APP运行日志

日志回捞崩溃分析-崩溃详情-自定义日志

2.4.0

CrashProtector

崩溃防护

异常防护-崩溃防护

2.5.2

CPUException

CPU异常监控

CPU监控-CPU异常

2.7.3

Zombie

线上Zombie分析

崩溃分析

2.8.0(不支持白名单)
2.10.0(支持白名单)

BootingProtect

连续崩溃保护

-

2.10.0

BootingProtectLite

连续崩溃保护Lite版(不依赖OOM)

-

2.10.0

MetricKit

MetricKit

MetricKit

2.12.1

Disk

磁盘监控

磁盘监控

3.0.0

GWPASan

GWPASan

崩溃分析

3.1.0

Coredump

Coredump

崩溃分析

3.2.0

SDK扩展功能

通知

某些事件发生时,SDK会发出通知,您可以监听这些通知,来做一些自定义的应对措施。以卡顿场景为例,您可以通过如下方式注册通知,如果引入了LAG子库,在卡顿场景发生时,SDK会发出通知,从而触发lagHandler。

#import <RangersAPMNotifications.h>
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(lagHandler) name:APMLagTimeOutNotification object:nil];

说明

  • 除了卡顿通知,SDK还支持内存触顶等其他通知,详情可以查看头文件RangersAPMNotifications.h
  • SDK版本需大于1.5.4。

启动分析自定义链路

自定义埋点

启动分析默认监控四个启动阶段:

  1. from_exec_to_load
  2. from_load_to_didFinishLaunching
  3. from_didFinishLaunching_to_first_render_time
  4. from_vc_loadView_to_didAppear

各阶段时间节点说明:

时间节点

说明

exec

APP进程启动的时间

load

RangersAPM的+load调用时间

didFinishLaunching

初始化RangersAPM的时间

first_render_time

第一次CoreAnimation提交的时间

vc_loadView

第一个ViewController,loadView的时间

didAppear

第一个ViewController,viewDidAppear的时间

如果需要额外记录启动过程的某些节点,请参考如下两种埋点方案:

  • 在节点开始和结束分别埋点

    #import <RangersAPM+PerformanceAPI.h>
    
      RangersAPMConfig *config = [RangersAPMConfig configWithAppID:@"{{app_id}}" appToken:@"{{app_token}}"];
      [RangersAPM startWithConfig:config];
    
      [RangersAPM beginLaunchSpan:@"business" callback:^(NSError * _Nullable error) {
          if (error.code == RangersAPMStartDetectorErrorTypeDuplicateSpanName) {
              //do something
          }
      }];
    
      //business
    
      [RangersAPM endLaunchSpan:@"business" callback:^(NSError * _Nullable error) {
          if (error.code == RangersAPMStartDetectorErrorTypeDuplicateSpanName) {
              //do something
          }
      }];
  • 记录节点开始时间和结束时间,在节点结束时埋点

    #import <RangersAPM+PerformanceAPI.h>
    
        RangersAPMConfig *config = [RangersAPMConfig configWithAppID:@"{{app_id}}" appToken:@"{{app_token}}"];
        [RangersAPM startWithConfig:config];
    
        NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970] * 1000;
        //business
        NSTimeInterval endTime = [[NSDate date] timeIntervalSince1970] * 1000;
    
        [RangersAPM addSpan:@"business" startTimeMs:startTime endTimeMs:endTime callback:^(NSError * _Nullable error) {
            if (error.code == RangersAPMStartDetectorErrorTypeDuplicateSpanName) {
                //do something
            }
        }];

    说明

    以上两个方法,只能在App启动阶段进行埋点,APP启动完成后调用是无效的。

自定义终点

如果您想要自定义启动链路的终点,需要配置RangersAPMConfig的customFinishStartTrace参数为YES,并在SDK初始化之后,即[RangersAPM startWithConfig:]之后,在一个合适的时机调用[RangersAPM finishLaunchTrace]方法结束启动链路。
示例代码:

#import <RangersAPM.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    RangersAPMConfig *apmConfig = [RangersAPMConfig configWithAppID:@"{{app_id}}" appToken:@"{{app_token}}"];
    apmConfig.customFinishStartTrace = YES;
    apmConfig.channel = @"App Store";
    
    [RangersAPM startWithConfig:apmConfig];
    
    [RangersAPM finishLaunchTrace];
      
    return YES;
}

自定义数据与自定义维度

使用如下接口,您可以添加一些自定义环境或业务信息,如用户email、定位信息、业务场景等,这些信息会随着SDK的日志一同上报,帮助您排查一些问题。

[RangersAPM setCustomContextValue:@"customKeyDemoTest" forKey:@"customValueDemoTest"];

添加后,您可以在控制台日志详情页看到这些自定义数据。
图片
使用如下接口,您可以添加一些自定义维度,作为自定义的的筛选项,用来筛选某些特定情况下的日志。

[RangersAPM setCustomFilterValue:@"filterValueDemooTest" forKey:@"filterKeyDemoTest"];

添加后,您可以在筛选列表中的自定义维度下查看这些自定义维度。
图片

注意

在没有日志详情,只有统计数据的模块,无法看到这些自定义数据和自定义维度,如流畅性、Http等。

页面追踪

只需引入UITrackers子库,无需额外嵌码,就可以在崩溃详情页的自定义数据模块下,看到崩溃发生前用户的页面访问路径。自定义错误、卡顿详情同样支持该功能。
图片

连续崩溃保护

连续崩溃保护可以在应用发生连续的崩溃时进行一些本地的处理,例如清理缓存、删除文件等。连续崩溃保护需要接入SDK的BootingProtect模块,具体请参见Subspecs说明

#import <RangersAPM+BootingProtect.h>

    [RangersAPM 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");
        }
        if (info.OOMTimes >= 1) {
            NSLog(@"⚠️Consecutive oom 1 time");
        }
    }];

全链路监控

功能说明请参考全链路监控,客户端需要进行如下配置,开启功能。

//需要引入如下头文件
#import <RangersAPMConfig+NetworkPro.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    RangersAPMConfig *apmConfig = [RangersAPMConfig configWithAppID:@"{{app_id}}" appToken:@"{{app_token}}"];
    apmConfig.channel = @"App Store";
    
    //配置 enableTracing 为 YES 以开启全链路监控功能
    apmConfig.enableTracing = YES;

    [RangersAPM startWithConfig:apmConfig];
    
    return YES;
}

获取设备数与用户数

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

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

已接入RangersAppLog,使用其生成的DeviceID

如果您目前已经接入了RangersAppLog,或者想要接入,请参考如下方式:

  1. 在Podfile中声明RangersAppLog依赖,RangersAppLog版本需要大于6.0.1。

    pod 'RangersAppLog', '>=6.0.1', :subspecs => [
      'Core',
      'Host/CN'
    ]
  2. 初始化RangersAppLog SDK。

    #import <BDAutoTrack.h>
    
    - (BOOL)application:(UIApplication *)application 
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
       BDAutoTrackConfig *config = [BDAutoTrackConfig configWithAppID:@"{{app_id}}" launchOptions:launchOptions];
       config.channel = @"App Store";
       [BDAutoTrack startTrackWithConfig:config];
    
       //初始化APMInsight
    
       return YES;
    }
  3. 配置应用性能监控全链路版SDK初始化config的deviceIDSource,应用性能监控全链路版会自动从RangersAppLog获取deviceID。

    #import <RangersAPM.h>
       
       - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
       
       //初始化RangersAppLog
       
       RangersAPMConfig *apmConfig = [RangersAPMConfig configWithAppID:@"{{app_id}}" appToken:@"{{app_token}}"];
       
       apmConfig.channel = @"App Store";
       
       apmConfig.deviceIDSource = RAPMDeviceIDSourceFromRAppLog;
       
       [RangersAPM startWithConfig:apmConfig];
       
       return YES;
       
       }

使用自己的DeviceID

如果您想要使用自己的deviceID,请严格按照如下方式:

  1. 配置应用性能监控全链路版SDK初始化config的deviceIDSource。
  2. 在应用性能监控全链路版SDK初始化方法调用之后,再设置deviceID。
    #import <RangersAPM.h>
    
        - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
            RangersAPMConfig *apmConfig = [RangersAPMConfig configWithAppID:@"{{app_id}}" appToken:@"{{app_token}}"];
            apmConfig.channel = @"App Store";
            apmConfig.deviceIDSource = RAPMDeviceIDSourceFromUser;
            [RangersAPM startWithConfig:apmConfig];
    
            [RangersAPM setDeviceID:@"MYDEVICEID"];
    
            return YES;
        }