更新时间:2023.05.30 17:14:51
本文介绍Android SDK的详细接入步骤。接入SDK后,验证数据上报成功,即可在应用性能监控全链路版平台上使用相关分析功能。
Android SDK目前仅限在中国大陆应用使用(不包括港澳台地区)。
调用SDK初始化接口不会采集用户信息,调用SDK启动接口会开始采集用户信息,请确保采集用户信息之前已经获得用户授权SDK隐私政策。
应用性能监控全链路版的Android SDK无需下载,请根据下方初始化配置说明接入。
在project级别的build.gradle添加maven地址。
buildscript { repositories { maven { url "https://artifact.bytedance.com/repository/Volcengine/" } maven { url "https://artifact.bytedance.com/repository/byteX/" } } } allprojects { repositories { maven { url "https://artifact.bytedance.com/repository/Volcengine/" } } }
接入应用性能监控全链路版。
在project级别的build.gradle文件的dependencies中添加以下代码。
classpath "com.volcengine:apm_insight_plugin:1.4.2"
在app module的build.gradle文件的dependencies中添加以下代码。
插桩是为了辅助收集启动耗时、页面加载、网络监控的数据,这部分只适用于接入App进行监控的用户,不适用于接入SDK进行监控的用户。
//在文件头添加 apply plugin: 'apm-plugin' // 在dependencies中添加 implementation 'com.volcengine:apm_insight:1.5.0.cn' implementation 'com.volcengine:apm_insight_crash:1.4.7'
AppID和AppToken获取方法,请参见如何查询AppID和AppToken?。
在Application中onCreate中,添加以下代码初始化崩溃相关功能。
MonitorCrash.Config config = MonitorCrash.Config.app({{AppId}}) .token({{AppToken}})// 设置鉴权token,可从平台应用信息处获取,token错误无法上报数据 // .versionCode(1)// 可选,默认取PackageInfo中的versionCode // .versionName("1.0")// 可选,默认取PackageInfo中的versionName // .channel("test")// 可选,设置App发布渠道,在平台可以筛选 // .url("www.xxx.com")// 默认不需要,私有化部署才配置上报地址 //可选,可以设置自定义did,不设置会使用内部默认的 // .dynamicParams(new MonitorCrash.Config.IDynamicParams() { // @Override // public String getDid() {//返回空会使用内部默认的did // return null; // } // // @Override // public String getUserId() { // return null; // } // }) //可选,添加业务自定义数据,在崩溃详情页->现场数据展示 // .customData(crashType -> { // HashMap<String, String> map = new HashMap<>(); // map.put("app_custom", "app_value"); // return map; // }) // .autoStart(false) // 是否在初始化时自动开启监控,默认为true // .debugMode(true) //线下使用的日志开关,线上不要调用或设置为false // 可选,添加pv事件的自定义tag,可以用来筛选崩溃率计算的分母数据 //.pageViewTags(<<Map<String, String>>>) .build(); MonitorCrash monitorCrash = MonitorCrash.init(ApplicationContext, config); // 启动监控,当初始化时autoStart传入false设置为初始化时不自动开启监控,需要在合适的位置调用start方法开启监控;如果初始化时未设置autoStart参数或者设置为true,将自动开启监控,不需要调用start方法。 if (monitorCrash != null) { monitorCrash.start(); }
初始化崩溃相关功能的代码有以下说明:
在Application中onCreate中,添加以下代码初始化性能相关功能。
注意
请在主线程中添加初始化性能相关功能的代码。
//必须放到Application的onCreate里面,会注册监听生命周期,不涉及数据采集和隐私合规问题 ApmInsight.getInstance().init(application); //在同意隐私合规后调用 ApmInsightInitConfig.Builder builder = ApmInsightInitConfig.builder(); //设置分配的appid builder.aid({{app_id}}); //设置分配的AppToken builder.token({{AppToken}}); //是否开启卡顿功能 builder.blockDetect(true); //是否开启严重卡顿功能 builder.seriousBlockDetect(true); //是否开启流畅性和丢帧 builder.fpsMonitor(true); //控制是否打开WebView监控 builder.enableWebViewMonitor(true); //控制是否打开内存监控 builder.memoryMonitor(true); //控制是否打开电量监控 builder.batteryMonitor(true); //控制是否打开CPU监控 builder.cpuMonitor(true); //控制是否打开磁盘监控 builder.diskMonitor(true); //控制是否打开流量监控 builder.trafficMonitor(true); //是否打印日志,注:线上release版本要配置为false builder.debugMode(true); //默认不需要,私有化部署才需要配置数据上报的域名 (内部有默认域名,测试支持设置http://www.xxx.com 默认是https协议 //builder.defaultReportDomain("www.xxx.com"); //设置渠道。1.3.16版本增加接口 builder.channel("google play"); //打开自定义日志回捞能力。1.4.1版本新增接口 builder.enableLogRecovery(true); //设置数据和Rangers Applog数据打通,设备标识did必填。1.3.16版本增加接口 builder.setDynamicParams(new IDynamicParams() { @Override public String getUserUniqueID() { //可选。依赖AppLog可以通过AppLog.getUserUniqueID()获取,否则可以返回null。 return null; } @Override public String getAbSdkVersion() { //可选。如果依赖AppLog可以通过AppLog.getAbSdkVersion()获取,否则可以返回null。getAbSdkVersion是回调类的参数可以初始化后再设置。 return null; } @Override public String getSsid() { //可选。依赖AppLog可以通过AppLog.getSsid()获取,否则可以返回null。getSsid是回调类的参数可以初始化后再设置。 return null; } @Override public String getDid() { //1.4.0版本及以上可选,其他版本必填。设备的唯一标识,如果依赖AppLog可以通过 AppLog.getDid() 获取,也可以自己生成。getDid是回调类的参数可以初始化后再设置。 return null; } @Override public String getUserId() { //可选。用户的唯一标识,支持用户自定义user_id把平台数据和自己用户关联起来。getUserId是回调类的参数可以初始化后再设置。 return "userid"; } }); ApmInsight.getInstance().start(builder.build()); //初始化自定日志,配置自定义日志最大占用磁盘,内部一般配置20,代表最大20M磁盘占用。1.4.1版本开始存在这个api VLog.init(this,20);
启动分析和页面体验相关功能依赖插件插桩,需配置ApmPlugin的whiteList为自己的包名,配置后该目录下的代码会被插桩。
在app module的build.gradle文件最外层,添加以下代码完成插桩。
ApmPlugin { // 是否进行插桩 enable true // 是否在Debug包插桩,默认不插桩 enableInDebug true // DEBUG("DEBUG"), INFO("INFO"), WARN("WARN"), ERROR("ERROR"); // DEBUG 级别Log会汇总所有被插桩处理的类供查看,路径 app/build/ByteX/ApmPlugin/ApmPlugin_log.txt logLevel "DEBUG" // 启动分析开关:监控App启动耗时,需要同时开启pageLoadSwitch startSwitch = true // 页面响应开关:监控Activity的生命周期耗时 pageLoadSwitch = true // 网络监控开关:监控okhttp3的网络请求 okHttp3Switch = true //插桩显示HttpUrlConnection的网络请求开关 httpUrlConnectionSwitch = true // 白名单下的包进行插桩,需要填写要插装类所在的包名,支持前缀配置 whiteList = [ "com" ] // 黑名单包下类不进行插桩,可以配置包名和类名,没有可以填空 blackList = [ "com.xxx" ] }
WebView初始化一般在某个Activity或者某个Fragment内,添加以下代码将待监控的Webview进行封装:
//设置webView的WebChromeClient如下或者继承WebViewMonitorWebChromeClient webView.setWebChromeClient( new WebViewMonitorWebChromeClient()); //设置webView的WebViewClient如下或者继承WebViewMonitorWebViewClient webView.setWebViewClient(new WebViewMonitorWebViewClient()); //WebView加载url时候需要调用如下函数 WebViewMonitorHelper.getInstance().onLoadUrl(webView, url); webView.loadUrl(url);
配置设备白名单
崩溃是100%上报的,不受采样率控制。除了崩溃其他监控数据需要在平台SDK上报配置页面配置采样上报,默认情况下采样命中后才会上报。由于平台默认配置的采样率较低,在SDK接入测试阶段请配置DID白名单,确保当前设备所有性能数据都采样命中,才可以上报到平台查看这些数据。
那么,如何获取需要添加到白名单的DID?
ApmInsightAgent.getDid()
配置各模块采样率
例如,验证卡顿数据前,请在SDK上报配置页面打开总开关,并将卡顿采样率配置为100%。验证完成后,再修改为适合的采样率。
完成前提条件后,添加以下代码发生崩溃。崩溃只有在下次启动才会上报。
throw new RuntimeException("Monitor Exception"); // 执行就崩,如果应用启动后8秒内崩溃, 则判定为启动崩溃进行上报
完成前提条件后,在主线程调用以下函数发生卡顿。初始化SDK时,在主线程阻塞,App会自动监控到卡顿,2分钟内会上报到服务器。
例如,主线程调用如下函数:
private void testSeriousBlock() { try { Thread.sleep(3500); } catch (Exception e){ } }
严重卡顿把sleep时间修改为6000毫秒。
完成前提条件后,初始化SDK时,打开启动分析和页面响应的开关,App启动一段时间SDK会自动上报启动分析、页面响应的数据。
完成前提条件后,初始化SDK时,打开配置功能的开关,用户进入页面后滑动一段时间SDK会自动上报流畅性数据和丢帧数据。
完成前提条件后,初始化SDK时,打开配置功能开关,设置debug测试模式。
builder.debugMode(true); builder.memoryMonitor(true);
上述代码可以模拟发生以下两种场景:
OOMMaker.createReachTop(80);
。完成前提条件后,初始化SDK时,配置插桩ApmPlugin的okHttp3Switch,打开网络监控开关。
当App使用okhttp3进行访问时会自动监控到并上报到服务器。插桩支持的okhttp版本最低是3.10.0
。当前okhttp3对外暴露了上报网络监控数据的接口。
其他网络库监控需要自己采集网络监控数据,然后再通过网络监控数据接口上报网络数据,才能在平台查看监控数据。具体上报接口和上报数据结构请联系平台对接的人员获取。
完成前提条件后,初始化SDK时,打开电量开关。
App启动后,端上采样命中会自动采集上报电量数据。
完成前提条件后,在事件管理页面新增事件并配置采样,事件采样命中才会上报。
添加以下代码,配置事件上报的规则:
HashMap<String, String> dimension = new HashMap<>(); //维度值 dimension.put("key1", "value1"); dimension.put("key2", "value2"); HashMap<String, Double> metric = new HashMap<>(); //指标值 metric.put("metric1", (double) 10); metric.put("metric2", 8.8); ApmInsightAgent.monitorEvent("event1", dimension, metric);
添加以下代码,通过事件上报接口配置事件采样:
/** * 事件上报 * * @param serviceName 事件名 * @param dimension 可枚举Key-Value,代表维度。key代表维度名称,value代表维度值,平台会自动计算key值下的value的百分占比和上报量 * @param metric 不可枚举的Key-Value,代表指标。key代表指标名称,value代表指标值,平台会自动计算value的平均值和上报量 */ public static void monitorEvent(final String serviceName, final Map<String, String> dimension, final Map<String, Double> metric) { } /** * 事件上报 * * @param serviceName 事件名 * @param dimension 可枚举Key-Value标识维度 * @param metric 不可枚举的Key-Value标识指标 * @param extraJson 辅助分析事件的数据,只可以在单点原始日志查看 * */ public static void monitorEvent(final String serviceName, final Map<String, String> dimension, final Map<String, Double> metric, final JSONObject extraJson) { }
通过以上接口配置事件采样后,可以在平台查看事件信息。
平台查看的事件示例如下所示:
//代表event1 采样没有命中 2021-04-11 21:19:01.019 13535-13587/com.example.apm.insight.demo D/ApmInsight: Receive:EventData event1 simple:false //代表event2 采样命中 2021-04-11 21:19:01.916 13535-13587/com.example.apm.insight.demo D/ApmInsight: Receive:EventData event102 simple:true
完成前提条件后,初始化SDK时,打开CPU监控,CPU指标会自动采集后上报。
CPU异常可以在端上模拟异常场景,然后等待端上检测异常上报后,在平台查看异常数据。
添加以下代码,模拟CPU异常:
for (int i = 0; i < 6; i++) { new Thread(new Runnable() { @Override public void run() { while (true) { Math.acos(Math.cos(java.lang.Double.valueOf(9999999))); } } },"cpu-"+i).start(); }
打开debug开关后,在Logcat日志中过滤ApmInsight,可以查看以下日志:
//CPU异常数据 2021-12-30 15:29:29.512 26285-26887/com.example.apm.insight.demo D/ApmInsight: Receive:ExceptionCpuData //CPU指标 2021-12-30 15:29:29.512 26285-26887/com.example.apm.insight.demo D/ApmInsight: Receive: ProcessCpuDat
测试阶段建议配置:平台磁盘相关采样率配置为100%,磁盘相关阈值都配置为1,最大上报文件使用默认值20,端上设置 builder.debugMode(true) 。
App一次启动只会上报一次磁盘数据。为了降低对性能的影响,SDK默认为App在后台时才会采集上报一次磁盘数据,按照测试阶段建议配置后,您可以设置debug模式在前台也可以采集上报磁盘数据。 冷启动后过滤ApmInsight会看到Receive:DiskData的日志,代表磁盘监控数据上报成功,可以在平台磁盘异常页面查看数据。
完成前提条件后,初始化SDK时,打开流量开关。App启动后,端上采样命中会自动采集上报流量数据。流量指标10分钟采集一次。流量异常需要端上10分钟流量消耗超过平台配置的阈值。
添加以下代码,模拟流量异常:
//十分钟流量 2023-01-12 21:10:49.615 5472-5576/com.example.apm.insight.demo D/ApmInsight: TrafficData10 //流量异常 2023-01-12 21:10:49.615 5472-5576/com.example.apm.insight.demo D/ApmInsight: TrafficDataException
自定义日志的的三个使用场景:崩溃日志上报、日志回捞以及主动上报。
初始化SDK时,打开自定义日志。
//打开自定义日志回捞能力 builder.enableLogRecovery(true); ApmInsight.getInstance().init(this, builder.build()); //初始化自定日志,配置自定义日志最大占用磁盘,内部一般配置20,代表最大20M磁盘占用。1.4.1版本开始存在这个能力 VLog.init(this,20);
主动上报Vlog日志文件。
//示例:上传当前时间前10分钟的vlog日志。 ApmInsightAgent.uploadVlog(System.currentTimeMillis() - 1000 * 60 * 10, System.currentTimeMillis()); /** * Vlog日志 主动上报 * * @param start 起始时间 毫秒 * @param end 结束时间 毫秒 */ public static void uploadVlog(long start, long end) { }
日志文件比较大,一次上报大约会消耗200事件量。
在平台的自定义文件页面,根据DID或User ID查询日志文件。
初始化SDK时,打开自定义日志。
//打开自定义日志回捞能力 builder.enableLogRecovery(true); ApmInsight.getInstance().init(this, builder.build()); //初始化自定日志,配置自定义日志最大占用磁盘,内部一般配置20,代表最大20M磁盘占用。1.4.1版本开始存在这个能力 VLog.init(this,20);
在平台SDK上报配置页面崩溃分析里配置是否上传自定义日志。
在平台崩溃详情页面的自定义日志下查看通过VLog类打印的日志。
用户出现问题需要日志排查时,通过平台回捞端上通过自定义日志VLog打印的日志来排查问题。具体步骤如下所示:
初始化SDK时,打开自定义日志。
//打开自定义日志回捞能力 builder.enableLogRecovery(true); ApmInsight.getInstance().init(this, builder.build()); //初始化自定日志,配置自定义日志最大占用磁盘,内部一般配置20,代表最大20M磁盘占用。1.4.1版本开始存在这个能力 VLog.init(this,20);
通过API打点自定义日志。
// com.apm.insight.VLog; VLog.v(String tag, String msg); VLog.d(String tag, String msg); VLog.i(String tag, String msg); VLog.w(String tag, String msg); VLog.e(String tag, String msg); // 也可以通过接口来设置生效的日志级别 VLog.changeLevel(com.apm.insight.LogLevel.WARN);
通过平台日志回捞页面新建任务,输入DID或UID回捞指定用户的自定义日志排查问题。
UID初始化时配置:
@Override public String getUserId() { //可选。用户的唯一标识,支持用户自定义user_id把平台数据和自己用户关联起来。getUserId是回调类的参数可以初始化后再设置。 return "userid"; }
DID初始化时配置:
@Override public String getDid() { //1.4.0版本及以上,可选,其他版本必填,设备的唯一标识。如果依赖AppLog可以通过 AppLog.getDid() 获取。也可以自己生成。 return null; }
如果DID返回的是null,可以通过UID的配置进行日志回捞。
回捞支持自定义回捞,用户在平台输入自定义回捞参数,这里可以根据参数返回想要回捞的结果
//可选,自定义回捞设置 ApmInsightAgent.setRecoveryTemplate(new ITemplateConsumer() { @Override public CustomResult handleTemplateMessage(JSONObject template) { //template 是平台配置的 【自定义回捞参数】 if (template != null) { String type = template.optString("type"); if (!TextUtils.isEmpty(type)) { if (type.equals("type_one")) { //返回type_one 回捞的结果 HashMap<String, String> result = new HashMap<>(); result.put("result", "获取文件成功"); //result平台会直接展示,file平台支持下载 CustomResult customResult = new CustomResult(result, application.getFilesDir()); //返回的回捞结果 return customResult; } else if (type.equals("type_two")) { //返回type_two 回捞的结果 return null; } } } return null; } });
应用性能监控全链路版支持手动上传符号表和自动上传符号表。
手动上传在平台上操作。
在应用工程的build.gradle中添加以下代码,配置自动上传符号表:
apply from: 'https://sf3-ttcdn-tos.pstatp.com/obj/apminsight-symbolicate/apminsight.gradle' apminsightConfig { api_token = "" // 从平台的 全部功能->符号表管理->系统选择 Android->下面可以看到api key和api token。或者联系开发同学获取到的对应appId的一个token,私有化部署不用设置 api_key = 0 // 从平台的 全部功能->符号表管理->系统选择 Android->下面可以看到api key和api token。或者联系开发同学获取到的对应appId的一个key,私有化部署不用设置 aid = 187277 // 应用性能监控全链路版上的appid // updateVersionCode = -1 // 默认不用写这一行, 除非您在初始化的时候手动指定了非标准版本号(或SDK版本号); 此处一定要与初始化的版本号一致 // mappingUrl = "https://www.xxx.com" // 默认不用写这一行,如果是私有化,这里配置私有化平台域名 }
SDK接入时,updateVersionCode字段的值必须与初始化ApmInsight传入的值一致。App接入时,不需要配置,请删除这行代码。
崩溃的时候会上报很多数据,如果用户想上报一些自定义的数据,在崩溃的时候一起上报,可以添加以下代码。
崩溃配置其他字段:包括渠道、版本号等所有自定义字段。
public Config config()
崩溃组件的自定义维度:
public MonitorCrash addTags(String key, String value)
性能组件的自定义维度:上报的tag在日志查询里或者原始日志文件里可以查询到。
//示例 ApmInsightAgent.addPerfTag("tag_test","tag_1"); /** * 性能数据增加tag * @param key * @param value */ public static void addPerfTag(@NonNull String key, @NonNull String value) { } /** * 性能数据移除tag * @param key * @param value */ public static void removePerfTag(@NonNull String key, @Nullable String value) { }
其中参数message、type可以为任意字符串(不可过长),可用于筛选。
public void reportCustomErr(String message, String type, Throwable throwable)
例如:
MonitorCrash crash = 初始化返回的MonitorCrash实例 crash.reportCustomErr("test err", "type1", new RuntimeException());
启动监控支持自定义打点,方法需要配对出现。
在Application的onCreate和首个Activity的onResume之间,添加以下代码配置自定义打点。
LaunchTrace.startSpan("initData"); LaunchTrace.endSpan("initData");
添加上述代码后,可以在平台启动分析的启动节点耗时中查看自定义打点的耗时: