发布初衷
前几天遇上这么个需求,一个安卓项目做完后,自己手测不能测全面所有功能,在实际运用中触发了几次app崩溃,但是无法通过联机监控的方式找错,所以试着配置sentry来捕获错误信息。开发环境下配置的很顺畅,直接走dsn链接就能直接上传成功错误信息。但是在打包产品apk时,sentry的文档配置信息过于模糊,导致处理打包问题卡了一个下午,这边写个文档希望能帮到遇见同样问题的人。
初始配置
- app/build.gradle
apply plugin: 'kotlin-android'
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
sentry {
// Disables or enables the automatic configuration of proguard
// for Sentry. This injects a default config for proguard so
// you don't need to do it manually.
autoProguardConfig false
// Enables or disables the automatic upload of mapping files
// during a build. If you disable this you'll need to manually
// upload the mapping files with sentry-cli when you do a release.
autoUpload true
}
dependencies {
implementation 'io.sentry:sentry-android:1.7.27'
implementation 'org.slf4j:slf4j-nop:1.7.25'
implementation 'org.jetbrains:annotations:16.0.2'
}
- build.gradle
buildscript {
dependencies {
classpath 'io.sentry:sentry-android-gradle-plugin:1.7.33'
}
}
- AndroidManifest.xml
dsn地址在sentry项目配置里能直接找到,sentry的项目新建
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="xxx.xxx.xxx">
<uses-sdk tools:overrideLibrary="io.sentry.android" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application>
<meta-data android:name="io.sentry.dsn" android:value="https://63a66127c5a64e69a9c96a6e1ef9fc11@sentry.xxxx.com/61" />
</application>
</manifest>
全局错误捕获
异常捕获处理器, 用于接管原来的错误捕获, 捕获后直接通过sentry上传错误信息
import android.content.Context;
import java.lang.Thread.UncaughtExceptionHandler;
import io.sentry.Sentry;
/**
* <p>类描述:异常捕获处理器
* @author ma
*/
public class CrashHandler implements UncaughtExceptionHandler {
private UncaughtExceptionHanlderListener mHanlderListener;
private Context mContext;
private static CrashHandler sInstance;
private StringBuffer sb;
public static CrashHandler getInstance(Context context){
if (sInstance == null) {
sInstance = new CrashHandler(context);
}
return sInstance;
}
private CrashHandler(Context context){
mContext = context;
Thread.setDefaultUncaughtExceptionHandler(this);
}
/* (non-Javadoc)
* @see java.lang.Thread.UncaughtExceptionHandler#uncaughtException(java.lang.Thread, java.lang.Throwable)
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
hanldeException(ex);
if (mHanlderListener != null) {
mHanlderListener.handlerUncaughtException(sb);
}
}
/**
* 设置外部要处理异常发生时操作监听器
* @param hanlderListener : {@link UncaughtExceptionHanlderListener}
*/
public void setHanlderListener(UncaughtExceptionHanlderListener hanlderListener) {
this.mHanlderListener = hanlderListener;
}
//崩溃日志的保存操作
private void hanldeException(Throwable ex){
if (ex == null) {
return ;
}
Sentry.capture(ex);
}
/**
* 未捕获异常的处理监听器
*/
public static interface UncaughtExceptionHanlderListener{
/**
* 当获取未捕获异常时的处理
* 一般用于关闭界面和数据库、网络连接等等
*/
public void handlerUncaughtException(StringBuffer sb);
}
}
Application
public class MyApp extends Application {
// 初始化sentry配置,这里其实和上一步的io.sentry.dsn在AndroidManifest里的配置重复, 属于手动配置和自动配置两种
Sentry.init("dsn链接", new AndroidSentryClientFactory(getApplicationContext()));
CrashHandler.getInstance(getApplicationContext());
}
AndroidManifest.xml application声明替换
<application
android:name=".com.MyApp">
</application>
到这开发环境下 sentry基本走通了, 错误日志可以在MainActivity主动触发测试
public class MyActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String a = null;
a.split("/");
}
}
产品打包配置
这时直接打包会报错提示 An organization slug is required (provide with --org)
打包时需要通过app根目录下的sentry.properties配置去请求sentry服务器校验接口权限, 不走dsn链接,不确定是否能绕过这个校验,文档这块自己也没细究,只是照着正常途径往下做了。
defaults.project=sentry新建的具体项目名
defaults.org=组织名 // 比如https://sentry.xxxx.com/organizations/sentry1111/projects/,组织名为sentry1111
defaults.url=https://sentry.xxxx.com // 私有化部署sentry的,取自己域名;走官方sentry的该值不需要配置,直接删除
auth.token=authtoken // 这个值的获取比较麻烦, 私有化参照下面步骤获取,官方的应该走项目设置直接能生成
auth.token获取
执行该命令后,结果提示打开链接, 跳转accessToken管理,直接点新建按钮,权限默认,即可生成auth.token,
sentry-cli --url https://sentry.xxx.com login
结语
在产品打包环节,还遇到过sentry服务器的访问失败,查看sentry后台日志,最后发现是打包校验时,会尝试访问sentry data目录,由于没做好目录的软连接, 导致报错500。