SDK 功能介绍

重要

本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。

欢迎使用性能体验SDK集成指南。本文档将指导您如何在我们的移动应用中正确使用性能体验SDK,实现全域数据采集与性能监控。

准备阶段

重要

在使用与验证前请务必仔细确认您已经根据基础集成文档正确集成性能体验SDK。为了方便您进一步验证相关功能,请将SDK内的Log打开。详细参考基础集成文档中日志打印部分

1. 基础使用

1.1 崩溃异常采集

如您完成统计SDK和性能体验SDK的接入,即可使用Java异常、Native崩溃异常、ANR异常自动采集功能

如果您使用我们的SDK捕获native崩溃后,其他捕获工具将无法捕获到native 崩溃,可以使用如下方法在初始化SDK后进行设置,使其他SDK可以捕获到native 崩溃。

import com.uc.crashsdk.export.CrashApi
...
final Bundle customInfo = new Bundle();
customInfo.putBoolean("mCallNativeDefaultHandler",true);
CrashApi.getInstance().updateCustomInfo(customInfo);

1.2 崩溃回调(自定义字段)

重要

注册回调必需在sdk初始化以后,否则注册无效

当崩溃发生时,您可以在该回调方法中返回string类型的业务自定义数据,该数据会写入到崩溃文件中并上传到服务器展示。注意:崩溃回调中返回string类型数据的长度限制为256个字符。

接口示例:

import com.umeng.umcrash.UMCrash
...

UMCrash.registerUMCrashCallback(new UMCrashCallback(){
  
     @Override
     public String onCallback(){
         return"崩溃时register的自定义内容字符串";
    }
});

上传后即可在管理平台 性能监控-崩溃分析-错误详情-自定义字段 中查看到回调信息

image

1.2 自定义异常

如果开发者自己捕获了错误,需要手动上传到【QuickTracking】服务器进行分析可以调用下面两种方法:

方法一:

public static void UMCrash.generateCustomLog(Throwable e,String type)

参数

含义

e

错误异常

type

自定义错误的类型

示例:

try{ 
 // 抛出异常的代码 
}  catch(Exception e){ 
   UMCrash.generateCustomLog(e,"Custom Exception"); 
}

方法二:

public static void UMCrash.generateCustomLog(String e,String type)

参数

含义

e

错误异常

type

自定义错误的类型

示例:

String e ="自定义异常代码"; 
UMCrash.generateCustomLog(e,"Comtom Exception");

使用自定义错误,查看时请在错误列表页面选择【自定义异常】

1.3 卡顿异常采集

采集卡顿异常无法做额外配置,默认为开启,如果您需要关闭此采集功能,请参考开关与采样配置文档

安卓卡顿分析默认的值为超过2秒计为卡顿,如果您需要设置不同的阈值,可以通过下方的API进行设置,API和示例如下:

import com.umeng.umefs.UMEfs
...
/** 设置卡顿阈值的API是通过UMEfs.initConfig(Bundle bundle)方法设置,
 *  bundle对象中传入对应的key为UMEfs.KEY_PA_TIMEOUT_TIME,
 *  对应的值为您设置的卡顿的阈值 *
 **/
Bundle bundle = new Bundle();
bundle.putLong(UMEfs.KEY_PA_TIMEOUT_TIME, 2000L);//设置卡顿阈值为2000L
UMEfs.initConfig(bundle);
说明

注意: 需要在初始化之前设置,阈值限制为大于0且小于等于4,如传入的阈值为非法值(负数或大于4),SDK默认取值2秒设置阈值

1.4 内存异常采集

内存采集支持采集OOM异常和内存占用指标。

OOM异常是崩溃分析的子集,因此不单独提供开关配置,是否采集OOM与是否采集崩溃异常同步,如您需要关闭某类崩溃,可通过【管理后台】-【性能体验】- 【配置管理】-【开关与采样配置】调整。

内存占用,需要接入APM SDK 1.6.0.001.210_guomi及以上版本,并建议搭配最新版本统计分析SDK接入, 如您不希望采集内存占用相关指标,可通过调整配置进行关闭。如下图所示:

image

1.5 网络监控

说明

此操作仅代表手动集成网络监控的方法适用范围

  1. 目前网络监控仅支持监控OkHttp网络请求 ,并且需要手动设置eventListenerFactory和NetworkInterceptor

  2. 需要使用OkHttp的最低版本是3.11.0

1.5.1 集成方式

集成网络监控即需要您手动将网络监控 SDK 相关 API 预埋到您项目工程的OkHttp中。

设置eventListenerFactory和NetworkInterceptor。

在您构建OkHttpClient时,通过OkHttp的eventListenerFactory方法和addNetworkInterceptor方法分别设置事件监听器和拦截器,示例如下:

OkHttpClient okHttpClient = newOkHttpClient.Builder()
//设置事件监听器,OkHttpListener.get()为SDK API
.eventListenerFactory(OkHttpListener.get())
//设置拦截器,new OkHttpInterceptor()为SDK API
.addNetworkInterceptor(new OkHttpInterceptor())
.build();

1.6 启动监控

启动监控用于监控、还原C端用户启动您App时的真实感知情况。分类如下:

启动类型

启动场景

流程分解

监控指标

首次启动

App安装后的第一次启动

初始化时长、构建时长、页面加载时长

Application的attachbaseContext()开始到第一个Activity的onResume()结束

冷启动

App进程被"杀死"(包括手动方式、被动系统回收等),再次触发启动的过程

初始化时长、构建时长、页面加载时长

Application的attachbaseContext()开始到第一个Activity的onResume()结束

热启动

App进程存活,再次触发启动的过程(包括前后台切换、back退出再次进入等)

启动时长

如果退出时的Activity存在则从恢复该Activity的onRestart()开始到onResume()结束,如果退出时的Activity不存在则从Activity的onCreate()开始到onResume()结束。

1.6.1 集成方式

说明

集成方式主要包括手动集成和自动集成(即编译插件集成)两种

原理说明

启动监控的触发时机与说明如图image

手动集成:
说明

手动集成启动监控,需要您主动将启动监控模块相关 API 预埋到您项目工程中

使用方法

您可以在Application生命周期添加LaunchManager.onTraceApp(this, "参数2", 参数3);和在Activity生命周期中添加LaunchManager.onTracePage(this, "参数2", 参数3);来使其生效

其中:

参数

参数名

参数类型

参数说明

param1

context

Context

ApplicationContext,或者ActivityContext

param2

methodName

String

填写当前参数

param3

isBegin

boolean

是否开始计时

填写规则的说明如下:

添加地点

填写参数2

填写参数3

添加时机

Application

LaunchManager.APP_ATTACH_BASE_CONTEXT

true

Application 的 attachBaseContext()方法开始

LaunchManager.APP_ATTACH_BASE_CONTEXT

false

Application 的 attachBaseContext()方法结束

LaunchManager.APP_ON_CREATE

false

Application 的 onCreate()方法结束

Activity

LaunchManager.PAGE_ON_CREATE

true

Activity 的 onCreate()方法开始

LaunchManager.PAGE_ON_RE_START

true

Activity 的 onRestart()方法开始

LaunchManager.PAGE_ON_START

true

Activity 的 onStart()方法开始

LaunchManager.PAGE_ON_RESUME

false

Activity 的 onResume()结束

LaunchManager.PAGE_ON_STOP

true

Activity 的 onStop()方法开始

代码示例如下:

import com.efs.sdk.launch.LaunchManager
...

// Application部分 
public class TestApplication extends Application {
    @Override
    protected void attachBaseContext(Context base) {
        LaunchManager.onTraceApp(this, LaunchManager.APP_ATTACH_BASE_CONTEXT, true);
        super.attachBaseContext(base);
        ...
        LaunchManager.onTraceApp(this, LaunchManager.APP_ATTACH_BASE_CONTEXT, false);
    }
    
    @Override
    public void onCreate() {
        super.onCreate();
        ...
        LaunchManager.onTraceApp(this, LaunchManager.APP_ON_CREATE, false);
    }
}

// Activity部分 
public class TestActivity extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        LaunchManager.onTracePage(this, LaunchManager.PAGE_ON_CREATE, true);
    }

    @Override
    protected void onRestart() {
        LaunchManager.onTracePage(this, LaunchManager.PAGE_ON_RE_START, true);
        super.onRestart();
    }

    @Override
    protected void onStart() {
        LaunchManager.onTracePage(this, LaunchManager.PAGE_ON_START, true);
        super.onStart();
        ...
    }

    @Override
    protected void onResume() {
        super.onResume();
        ...
        LaunchManager.onTracePage(this, LaunchManager.PAGE_ON_RESUME, false);
    }

    @Override
    protected void onStop() {
        LaunchManager.onTracePage(this, LaunchManager.PAGE_ON_STOP, true);
        super.onStop();
    }
}
自动集成
说明

您也可以添加APM Gradle插件来自动完成应用启动监控过程的埋点

  1. 依赖插件

打开您工程根目录的build.gradle,在dependencies中添加如下:

classpath "com.lydaas.qtsdk:apm-plugin:2.0.0"

注意:确保您已在工程根目录的build.gradle中添加Maven地址。

示例如下:

buildscript {
  repositories {
    //配置 阿里云镜像 maven地址
    maven { setUrl("https://maven.aliyun.com/repository/central") }
    google()
    jcenter()
  }

  dependencies {
      //引入apm性能分析插件 
      classpath 'com.lydaas.qtsdk:apm-plugin:2.0.0' 
  }
}

...

allprojects {
  repositories {
    //配置 阿里云镜像 maven地址
    maven { setUrl("https://maven.aliyun.com/repository/central") }
    google()
    jcenter()
  }
}

配置插件

打开您App的build.gradle添加使用插件,在文件头添加代码如下:

apply plugin: 'com.efs.sdk.plugin'

同时添加插件的相关配置,代码如下:

efs {
    //是否对启动过程进程插桩的开关,如果使用自动集成监控则必须开启,false则不开启启动插件
    enable = true
    //白名单,支持包力度,必须填写,如填写自己应用的包名
    whiteList = [
            "com.efs.sdk.demo.test", // 如需要针对test目录下所有的Activity进行自动
            "com.efs.sdk.demo.work.WorkActivity"  // 针对work目录下的WorkActivity进行监听
    ]
    //黑名单,支持包力度,必须填写,如填写自己应用的包名
    blackList = [
            "com.efs.sdk.demo.work" // work下的所有Activity都不需要监听
    ]
}
重要

注意: 白名单的判断优先级是高于黑名单的,如果有个白名单Activity在黑名单包目录下,则会正常监听

完整示例:

image

如何确认插件是否正确集成:

编译时查看编译中的Log搜索关键字EfsPluginTracer,出现下列关键字,即代表集成自动采集插件

[INFO][EfsPluginTransform]begin efs transform.
[INFO][EfsPluginTracer]dir need trace file is

如下图所示:

image

1.6.2 自定义启动阶段数据

说明

如果您想在启动监控过程中加入自定义的监控阶段,比如初始化业务数据(initData)、初始化页面组件(initView)等,您可以使用自定义启动阶段API加入您自定义的启动阶段数据。

重要

1、自定义启动阶段只支持冷启动阶段,热启动不支持

2、如果自定义启动阶段超过SDK所定义的启动结束时间点(即Activity生命周期中的 onResume方法被),则会被SDK丢弃

您可以通过在启动前后添加LaunchManager.onTraceBeginLaunchManager.onTraceEnd来实现自定义启动阶段上报

警告

注意:LaunchManager.onTraceBeginLaunchManager.onTraceEnd 方法必须配套使用,否则会被SDK上报丢弃

方法

在您自定义阶段开始处添加LaunchManager.onTraceBegin如:

注:自定义阶段key长度不可以超过10个字符

/**
* 参数1:上下文
* 参数2:自定义阶段key,需要和onTraceEnd配对使用
* 参数3:时间戳
*/
LaunchManager.onTraceBegin(context, "自定义阶段key_1", System.currentTimeMillis());

在您自定义阶段结束处添加LaunchManager.onTraceEnd如下API:

注:自定义阶段key长度不可以超过10个字符

/**
* 参数1:上下文
* 参数2:自定义阶段key,需要和onTraceBgin配对使用
* 参数3:时间戳
*/
LaunchManager.onTraceEnd(context, "自定义阶段key_1", System.currentTimeMillis());

代码示例:

//监控initData()方法在启动阶段的耗时
 LaunchManager.onTraceBegin(MainActivity.this, "initData", System.currentTimeMillis());
 initData();
 LaunchManager.onTraceEnd(MainActivity.this, "initData", System.currentTimeMillis());

结果验证

集成完成启动App,过滤efs.px.api,可以看到如下启动数据发送成功相关信息,即表示启动数据成功上报。

image

1.7 APP应用内H5页面的APM功能

集成QuickTracking JS SDK的网页在嵌入到App后,JS SDK采集到的数据可以通过App端上传到服务器,该功能默认关闭。如果开启,需要在每一个webview loadUrl前调用如下方法:

import com.efs.sdk.h5pagesdk.H5Manager
...
//以下方法仅支持APM SDK Android 1.6.0.001及以上版本
H5Manager.enableJavaScriptBridge(webView);
webView.loadUrl("https://www.demo.com");
重要

在API 16及以下版本中,注入JavaScript有安全漏洞,请谨慎使用。

嵌入到App中的H5页面集成APM SDK后需要设置App应用包名白名单,桥接场景下H5不需要设置收数域名。

详情参考性能体验Web SDK接入

1.8 原生页面

1.8.1自动集成

说明

原生页面的自动集成与启动监控的自动集成一致,参考启动监控-依赖插件章节进行插件依赖的添加即可自动集成

1.8.2 自定义页面阶段数据

如果您想在页面监控过程中加入自定义的监控阶段,比如初始化业务数据(initData)、初始化页面组件(initView)等,您可以使用自定义页面阶段API加入您自定义的页面阶段数据。

在您自定义阶段开始处添加如下API: 注:

1、自定义阶段key长度不可以超过10个字符;

2、key的名称不能以"UM_"开头;

3、单个页面使用上限为6个,超出则过滤。

import com.umeng.pagesdk.PageManger


在您自定义阶段开始处添加如下API
/**
* 参数1: 当前activity对象
* 参数2: 自定义阶段key,需要和onTracePageEnd配对使用
*/
PageManger.onTracePageBegin(MainActivity.this, "initView");


在您自定义阶段结束处添加如下API:
/**
* 参数1: 当前activity对象
* 参数2: 自定义阶段key,需要和onTracePageBegin配对使用
*/
PageManger.onTracePageEnd(MainActivity.this, "initView");

代码示例:

import com.umeng.pagesdk.PageManger

public class TestActivity extends Activity {
    ...
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //监控initView()方法在页面阶段的耗时
        PageManger.onTracePageBegin(MainActivity.this, "initView");
        initView(); // 业务方初始化逻辑
        PageManger.onTracePageEnd(MainActivity.this, "initView");
    }

    ...
}

2. 高级功能

2.1 采集开关

说明

注:您在产品管理平台中「开关与采样配置」中设置的开关和采样率优先级高于在SDK中设置的开关,SDK会间隔8小时同步是否有开关和采样配置更新的请求

本采集开关适用于开发者在不想使用某个APM SDK监控模块时灵活自定义采集范围。如目前提供功能都需要采集,则不需要使用该开关,如需要调整某个模块,可按照下面bundle控制说明,选择key进行设置。

重要

此API需要在调用初始化方法前使用

import com.umeng.umcrash.UMCrash
import com.umeng.umefs.UMEfs
...

/**
* 通过Bundle中指定的key和key的value值(boolean类型)来控制该key对应APM模块的关闭
*/
UMCrash.initConfig(Bundle args)	
 //用于控制UMCrash.KEY_ENABLE_CRASH_JAVA
 //UMCrash.KEY_ENABLE_CRASH_NATIVE
 //UMCrash.KEY_ENABLE_ANR
UMEfs.initConfig(Bundle args)
 //用于控制UMEfs.KEY_ENABLE_PA
 //UMEfs.KEY_ENABLE_LAUNCH
 //UMEfs.KEY_ENABLE_MEM
 //UMEfs.KEY_ENABLE_NET
 //UMEfs.KEY_ENABLE_H5PAGE
 //UMEfs.KEY_ENABLE_PAGE

Bundle控制说明:

key

说明

开关级别

UMCrash.KEY_ENABLE_CRASH_JAVA

用于关闭java crash捕获,默认为true可设置为false进行关闭

二级

UMCrash.KEY_ENABLE_CRASH_NATIVE

用于关闭native crash捕获,默认为true可设置为false进行关闭

二级

UMCrash.KEY_ENABLE_ANR

用于关闭ANR捕获,默认为true可设置为false进行关闭

一级

UMEfs.KEY_ENABLE_PA

用于关闭卡顿捕获,默认为true可设置为false进行关闭

一级

UMEfs.KEY_ENABLE_LAUNCH

用于关闭启动捕获,默认为true可设置为false进行关闭

一级

UMEfs.KEY_ENABLE_MEM

用于关闭内存占用捕获,默认为true可设置为false进行关闭

一级

UMEfs.KEY_ENABLE_NET

用于关闭网络分析捕获,默认为true可设置为false进行关闭

一级

UMEfs.KEY_ENABLE_H5PAGE

用于关闭App与H5打通开关,默认为true可设置为false进行关闭

一级

UMEfs.KEY_ENABLE_PAGE

用于关闭Page开关,默认为true可设置为false进行关闭

一级

UMEfs.KEY_ENABLE_CODE_LOG

用于关闭日志回捞开关,默认为true可设置为false进行关闭

一级

UMEfs.KEY_ENABLE_INIT_SEND_PV

用于开启冷起PV上报开关,默认为false可设置为true进行开启)

一级

代码示例如下:

 QtConfigure.setLogEnabled(true);
 Bundle bundle = new Bundle();
 bundle.putBoolean(UMCrash.KEY_ENABLE_CRASH_JAVA, true);
 bundle.putBoolean(UMCrash.KEY_ENABLE_CRASH_NATIVE, true);
 bundle.putBoolean(UMCrash.KEY_ENABLE_ANR, false);
 bundle.putBoolean(UMEfs.KEY_ENABLE_PA, false);
 bundle.putBoolean(UMEfs.KEY_ENABLE_LAUNCH, false);
 bundle.putBoolean(UMEfs.KEY_ENABLE_MEM, false);
 bundle.putBoolean(UMEfs.KEY_ENABLE_H5PAGE, false);
 bundle.putBoolean(UMEfs.KEY_ENABLE_CODE_LOG, false);
 bundle.putBoolean(UMEfs.KEY_ENABLE_INIT_SEND_PV, true); //v2.0.2 及以上版本支持
 UMCrash.initConfig(bundle);
 UMEfs.initConfig(bundle)
 QtConfigure.init(this,"您的appkey","应用商店名称",QtConfigure.DEVICE_TYPE_PHONE, "");
说明

1、由于启动监控早于SDK初始化,所以彻底去掉启动监控还需关闭插件插桩或去掉手动API埋点。

2、卡顿开关关闭情况下不会对卡顿模块进行初始化,并输出如下日志内容:enablePaLog is false 。

3、启动开关关闭情况下不会对卡顿模块进行初始化,并输出如下日志内容:enableLaunchLog is false 。

4、内存开关关闭情况下不会对内存模块进行初始化,并输出如下日志内容:enableMemLog is false 。

5、日志回捞关闭情况下不会对日志回捞模块进行初始化,并输出如下日志内容:enable codeLog is false 。

2.2 符号表

2.2.1 什么是符号表

符号表是内存地址与函数名、文件名、行号的映射表。符号表元素如下所示:

<起始地址> <结束地址> <函数> [<文件名:行号>]

为了能快速并准确地定位用户APP发生Crash的代码位置,我们使用符号表对APP发生Crash的程序堆栈进行解析还原 因此在使用APM SDK还原时需要先上传符号表!

2.2.2 为什么要上传符号表

为了能快速并准确地定位用户APP发生Crash的代码位置,使用符号表对APP发生Crash的程序堆栈进行解析还原

举一个例子,解析前:

image

解析后:

image

管理平台-性能体验-配置管理处提供了手动上传符号表功能如下图:

image

2.2.3 Android 打包符号表方式

Java 符号表

需要将多个mapping文件请自行处理追加到一个文件中,最终命名为mapping.txt,并打包成zip文件,如果需要同时包含so符号,可以把so文件打包在一起。(具体结构可参考下面符号文件建议示例

Android so库

保证符号表的so文件与发布的so文件同名,so压缩前最大支持400M;如果一个版本里包含同文件名,不同架构的so,可以压缩到不同的目录中,反符号化时需要通过buildid去关联;建议编译时使用-g参数,带上debug信息,崩溃堆栈可以解析到代码行级,实际发布时,再使用strip命令去掉调试信息;如果不带debug信息,则只能定位到函数名级下列情况下,需要so文件带有buildid

  • 不同CPU架构的so文件名一样,放在不同的路径下

  • 同一个应用版本里,可能有多个版本的so库,使用了动态加载的技术如何生成带buildid的so,请检查编译参数,确保没有带”—build-id=none”,如果还是没有buildid,可以添加编译参数”ld_flags += -Wl,--build-id=sha1”可通过file命令检查so文件是否带buildid,调试信息

符号文件建议示例:

image

如果您是使用CMake编译的项目,那么so文件在工程中的位置为:

<项目文件夹>/<Module>/build/intermediates/cmake/debug/obj/local<架构>/对应的so文件

image

mapping文件的位置:

<项目文件夹><Module>/build/outputs/mapping/<build-type>/image

版本选择

当前支持现有版本列表和手动输入两种方式:

  1. 如果是已经有错误上报到APM后台的版本,可以直接在上传符号表时的版本下拉框中选择

  2. 如果是即将发布的新版本,支持手动输入版本号,请输入与新版本完全一致的内容,并点击‘添加版本号‘即可手动添加

image

2.2.4 手动上传方式

  1. 按照文档说明将符号表文件压缩到一起:查看【符号文件建议示例

  2. 登录平台,进入【性能体验】-【配置管理】

  3. 点击符号表管理 ,点击上传符号表文件,将第一步压缩好的符号表文件上传即可

  4. 已经上传的符号表可以在符号表管理页面进行查看

    image

    当前支持上传方式:后台手动上传(最大支持400M)

2.3 设置HTTP接口API

您可以通过调用UMEfs.setRequestProtocol来设置http接口

 //isHttpsProtocol默认为true,为false则SDK本地默认发送HTTP请求
 UMEfs.setRequestProtocol(boolean isHttpsProtocol);

接口说明:

  1. 该接口仅影响UAPM 性能部分发送请求,UMCrash模块不受该API控制;

  2. 该接口需要在初始化SDK之前设置;

  3. 用户可通过该接口修改SDK本地是以HTTP头发送还是HTTPS头发送,默认SDK是以HTTPS头发送,并且可以通过云控配置动态下发修改,并且云控下发会覆盖该接口的设置;

  4. 通过setCustomDomainEfs接口传入的域名中的HTTP或HTTPS头接口内会自动切掉,以SDK默认值(HTTPS头)或setRequestProtocol接口或云控决定SDK使用HTTP或HTTPS。

2.4 日志回捞

2.4.1 设置回捞标识

您可以通过如下接口设置回捞标识:

Bundle bundle = new Bundle();
//设置回捞标识为android0911
bundle.putString(UMEfs.KEY_LOG_USER_ID, "android0911");
UMEfs.initConfig(bundle);

注意:

  1. 该设置必须在初始化SDK之前完成,运行时不可再次设置

  2. 回捞标识不能为空,且长度不能超过128

  3. 如果不设置回捞标识,默认以UMID作为标识回捞

2.4..2 日志记录

您可以通过如下接口完成相关日志的记录:

import com.umeng.logsdk.ULog;
...
ULog.v("日志TAG", "日志内容");
ULog.d("日志TAG", "日志内容");
ULog.i("日志TAG", "日志内容");
ULog.w("日志TAG", "日志内容");
ULog.e("日志TAG", "日志内容");

注意:

  1. 共提供五种日志等级,包括:v/d/i/w/e

  2. 参数1为日志的TAG,不能为空或长度超过64,参数2为日志的内容,不能为空或长度超过1024

  3. 务必使用「import com.umeng.logsdk.ULog;」类下的ULog.v等方法,且必须要在初始化SDK之后调用。如果使用「com.umeng.commonsdk.statistics.common.ULog;」将不生效

2.4.3 日志策略

  1. 日志持久化存储上限为5MB,当达到上限时则仅保留最近7天的日志,如果最近7天日志达到上限则不再继续存储日志

  2. 触发日志持久化存储:

    2.1. 前后台切换;

    2.2. 缓存数据达到上限则进行持久化日志存储

  3. 当回捞任务下发到本地,并成功加载后,则进行回捞任务和本地日志的匹配,匹配到的日志开始上传,当前进程正在产生的日志需要下次启动后匹配任务继续上传

2.4.4 日志排查

  1. 日志回捞模块开启,输出如下日志:

    enable codeLog is true

  2. 正确读取并加载日志任务,输出如下日志:

    09-13 14:56:28.988 15994-15994/com.efs.demo I/ULogConfigManager: [log register] begin. 09-13 14:56:29.704 15994-15994/com.efs.demo I/ULogConfigManager: [log register] call back config. 09-13 14:56:29.709 15994-15994/com.efs.demo I/ULogConfigManager: [log register] save did is 9560fe0f75e7c92fff351d537633a91cia 09-13 14:56:29.709 15994-15994/com.efs.demo I/ULogConfigManager: [log register] save uid is android0911 09-13 14:56:29.710 15994-15994/com.efs.demo I/ULogConfigManager: [log register] save task id is 1660130437264, task is {"task_etime":1663257599000,"target_type":0,"task_id":"1660130437264","task_btime":1662307200000,"task_type":0} 09-13 14:56:29.710 15994-15994/com.efs.demo I/ULogConfigManager: [log register] add mem task id is 1660130437264 09-13 14:56:29.710 15994-15994/com.efs.demo I/ULogConfigManager: [log register] save task id is 1660130437265, task is {"task_etime":1663257599000,"target_type":1,"task_id":"1660130437265","task_btime":1662307200000,"task_type":0} 09-13 14:56:29.710 15994-15994/com.efs.demo I/ULogConfigManager: [log register] add mem task id is 1660130437265 09-13 14:56:29.710 15994-15994/com.efs.demo I/ULogConfigManager: [log register] save task id set is 1660130437264_1660130437265

  3. 持久化存储日志(如前后台切换),输出如下日志:

    09-13 15:06:23.445 15994-16722/com.efs.demo I/efs.base: {"fr":"android","sdk":23,"others_OS":"Android","stime":1663052188738,"dsp_h":1920,"rom":"6.0.1","sdk_ver":"1.3.11.umeng","w_tm":1663052783,"um_access":"wifi","lang":"zh","um_umid_header":"aid03bc207717fd2238c5d8bf93ed4fffb","pkg":"com.efs.demo","type":"codelogperf","dsp_w":1080,"um_network_type":0,"wid":"54d8e67e-0a4e-4e11-9517-08ac993aa670","log_uid":"android0911","pid":15994,"ps":"com.efs.demo","build_model":"MI 4LTE","appid":"ez2cookeijezdgu3nxmci6zt","um_app_carrier":"","ctime":1663052783,"net":"wifi","um_crash_sdk_version":"efs.1.6.0.001.200","um_os":"android","vcode":"1","tzone":"Asia\/Shanghai","um_app_channel":"Umeng","brand":"xiaomi","log_did":"9560fe0f75e7c92fff351d537633a91cia","codelog":{"taskid":"","status":0,"time_start":1663052782368,"time_end":1663052783439,"uid":"android0911","did":"9560fe0f75e7c92fff351d537633a91cia","body":[{"tag":"walle","msg":"button 1 --->>> ","level":0,"time":1663052782367,"process":"com.efs.demo","thread":"main"},{"tag":"walle","msg":"button 1 --->>> ","level":2,"time":1663052782370,"process":"com.efs.demo","thread":"main"}]},"uid":"54d8e67e-0a4e-4e11-9517-08ac993aa670","ver":"1.0","model":"mi-4lte"} 09-13 15:06:23.459 15994-16077/com.efs.demo I/RecordLogCacheProcessor: save file, type is codelogperf 09-13 15:06:23.463 15994-16077/com.efs.demo I/RecordLogCacheProcessor: upload file, name is codelogperf_none_1_1_15994_2442_1663052783458_android0911_9560fe0f75e7c92fff351d537633a91cia_1663052782368_1663052783439

说明

查看data/data/<你的app>/app_UApm/<你的appkey>/upload_codelog中有日志文件,则表示日志保存成功

  1. 日志匹配并上传成功,输出如下日志:

    09-13 15:06:39.255 15994-16077/com.efs.demo I/efs.cache: [-->>] add file is codelogperf_gzip_2_1_15994_3356_1663052783463_android0911_9560fe0f75e7c92fff351d537633a91cia_1663052782368_1663052783439 09-13 15:06:39.262 15994-16141/com.efs.demo I/efs.LogSendAction.Codelog: send data url is http://aplus2-portal-lite.emas-poc.com 09-13 15:06:39.272 15994-16141/com.efs.demo I/efs.px.api: Upload file, url is http://aplus2-portal-lite.emas-poc.com/apm_logs 09-13 15:06:39.478 15994-16141/com.efs.demo I/efs.px.api: upload result : true, resp is HttpResponse {succ=true, code=200, data='{"msg":"成功","code":0,"cip":"XXX.XX.XX.XXX","stm":1663052801}', extra={req_url=http://aplus2-portal-lite.emas-poc.com/apm_logs, flow_limit=true, biz_code=0, size=592, type=codelogperf}} 09-13 15:06:39.480 15994-16077/com.efs.demo I/efs.send_log: send secess.

3. 本地Log说明

本地Log仅用于排查本地是否正确集成性能体验SDK,以及各项功能的正确触发,不代表管理平台处表现

开启本地日志

可通过QtConfigure.setLogEnabled(boolean)接口控制Log的输出。

重要

App正式上线前请关闭SDK运行调试日志。避免无关Log输出。

日志开关

可以通过调用如下方法控制SDK运行调试日志是否输出,默认情况下SDK运行调试日志为关闭。需要用户手动打开

/**
* 设置组件化的Log开关
* @param boolean 默认为false,如需查看Log设置为true
*/
QtConfigure.setLogEnabled(true);
说明

如果查看初始化过程中的Log,一定要在调用初始化方法前将Log开关打开。

日志等级

  • 日志分为四种等级,方便用户查看:

  • Error(打印SDK集成或运行时错误信息)。

  • Warn(打印SDK警告信息)。

  • Info(打印SDK提示信息)。

  • Debug(打印SDK调试信息)。

常见场景与日志说明:

  1. 初始化

    初始化成功后,会产生初始化成功log 您可以通过过滤QtLog来查看

    image

  2. 崩溃分析

    模拟崩溃后查看是否采集到崩溃日志,您可以通过过滤DEBUG关键字来查看日志

    image

  3. 内存异常采集上报

    模拟内存溢出后查看是否采集到崩溃日志,您可以通过过滤DEBUG关键字来查看日志

    image

  4. 启动上报

    模拟崩溃后查看是否采集到崩溃日志,您可以通过过滤LaunchTrace关键字来查看日志

    image

    说明

    其中coldTime is ***为冷启动标志hotTime is ***为热启动标志, 完整采集日志如上图所示

  5. 网络分析上报

    在排查网络分析上报日志时您可以先检查一下网络分析是否正确打开,您可以通过过滤inner config关键字来查看

    inner config : net open.inner config : net rate is 100 时网络分析功能打开

    image

    过滤NetTrace关键字可以用于检查网络分析是否正确采样状态

    正确采样时:

    image

    未采样时:image

  6. 卡顿采集上报

    模拟卡顿时过滤patrace关键字查看日志,卡顿采集成功如下图所示:image

  7. 内存分析上报

    开启内存分析后过滤wf_heap_used_rate关键字查看日志,默认间隔1s输出一条日志,日志如下图所示:

    image

  8. 原生页面流畅度和帧率上报

    帧率上报需集成自动化采集插件请根据配置插件教程正确集成,管理平台开启慢加载阈值设置加载时长请根据自己需求添加image

    冷启动2次过滤PageManger-PageFPSImpl关键字查看日志,日志如下图所示:

    image