React我爱编程

react-native线上错误分析定位实践

2018-05-22  本文已影响633人  jetzhliu

最近在处理App项目中的错误上报、错误分析工作,由于项目主要使用react-native开发,这里总结下如何上报RN的错误、奔溃,以及如何定位到源码位置。

有发布过生产环境的朋友应该清楚,无论是客户端还是web,上线前都是需要经过混淆这一步的,经过混淆,不仅可以减少用户下载的体积,还可以提高破解成本。但混淆过的代码可读性很差,调试困难,对应错误堆栈也很难定位到源码的报错位置。为了解决这个问题,这时候就要请出本文的主角之一“sourcemap”了。

sourcemap

sourcemap如字面含义所示:“源码映射”,它的功能是根据转换后的代码位置反推出源码的对应位置。上面说的混淆就是转换之一,其他例如typescript的转译、ES6的转译也属于其中。功能有点类似Android中的mapping.txt或者iOS下的dSYM文件。更详细的介绍可以网上搜索sourcemap,这里就不多做介绍了。

Sentry

有了sourcemap这个得力助手,那项目中具体该怎么使用呢?对于线上的应用,错误分析的流程应该是这样子的:捕获代码的错误、异常 --> 上报服务端 --> 根据上报信息中的App版本找到对应的sourcemap文件 --> 根据错误堆栈的行列号信息和sourcemap文件,定位到源码位置。整个流程比较复杂,全部自研稍有成本。经过调研,项目选择了Sentry这个平台用于客户端错误上报及分析。选择 Sentry 主要基于以下考虑:

有了Sentry这把瑞士军刀,下面整理下App接入sentry的流程:

创建项目站点

image.png

原生接入react-native-sentry

# 安装原生依赖,用于上报和手机客户端信息
npm install react-native-sentry --save
# 若使用sentry.io的账号,可以用下方命令一键引入原生依赖和初始化
# react-native link react-native-sentry
# 若使用自己架设的sentry后端服务,需要手动引入依赖和初始化

Android

// android/setting.gradle
include ':react-native-sentry'
project(':react-native-sentry').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sentry/android')
// android/app/build.gradle
// 若项目结构和RN初始化出来的一致,可以使用以下命令在每次构建时上次sourcemap,本项目不使用该方式
// apply from: "../../node_modules/react-native-sentry/sentry.gradle"
// 加入依赖
dependencies {
    compile project(':react-native-sentry')
}
// android/app/src/main/java/com/reactnativedemo/MainApplication.java
import io.sentry.RNSentryPackage;
public class MainApplication extends Application implements ReactApplication {
  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.asList(
        new MainReactPackage(),
        // 插入下方代码
        new RNSentryPackage(MainApplication.this)
      );
    }
  };
}

iOS

参考添加其他RN依赖的操作,把node_modules/react-native-sentry/ios/RNSentry.xcodeproj拖到xcode中,并添加libRNSentry.so。

react-native配置上报地址

  1. 获取上报地址
image.png
  1. 在入口文件index.js中配置上报地址
// index.js
import { Sentry } from "react-native-sentry";
Sentry.config("上图中的DSN地址").install();

上传sourcemap文件

通过上述配置,已经可以完成错误上报、统计工作。为了便于定位出错的源码位置,可以考虑上传sourcemap。下图展示了上传sourcemap前后的堆栈信息展示区别:

image.png

很明显,得到右边的信息对于解决crash是很关键的

  1. 获取上传文件必须的Auth Token,进入平台/api/路径下,复制已有的或新建一个token;
image.png
  1. 把配置写到文件.sentry.properties
# .sentry.properties
defaults.url=自己的后端服务地址
defaults.org=项目所在组织
defaults.project=项目名
auth.token=上一步复制的token
cli.executable=/usr/local/bin/sentry-cli
  1. 打包时生成sourcemap文件
react-native bundle \
    --platform android \
    --dev false \
    --entry-file index.js \
    --bundle-output path/to/index.android.bundle \
    --assets-dest path/to/asset \
    --sourcemap-output path/to/index.android.map
  1. 安装sentry-cli
npm -g install sentry-cli
  1. 上传sourcemap
export SENTRY_PROPERTIES=.sentry.properties

sentry-cli releases \
    files RELEASE_NAME \
    upload-sourcemaps \
    --dist DISTRIBUTION_NAME \
    --strip-prefix /path/to/project/root \
    --rewrite \
    path/to/index.android.bundle path/to/index.android.map

RELEASE_NAME: 包名-版本号,如com.example.myapp-1.0.0
DISTRIBUTION_NAME: 构建号,如52,在Android或iOS项目中设置

至此,RN版本的sentry集成已完成,web版的线上错误分析定位同样可以借助强大的sentry轻松完成,就不赘述了。以后可能会专门写篇web的sentry集成实践。

常见问题

sourcemap上传了,但没有解析出源码位置

原因1:没有集成原生代码,可以检查上报信息中的SDK信息,确保是通过sentry-react-native上传的:


image.png

原因2:版本号没对应上,可以检查上报信息中的APP信息,确保和上传sourcemap时填的一致:


image.png
上一篇下一篇

猜你喜欢

热点阅读