Skip to content
This repository has been archived by the owner on Jun 3, 2021. It is now read-only.

[WEEX-606][Android]fix monitor data #1497

Merged
merged 1 commit into from Sep 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 7 additions & 4 deletions android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
Expand Up @@ -1267,6 +1267,7 @@ public void onChangeElement(WXComponent component, boolean isOutOfScreen) {
}

public void onRenderError(final String errCode, final String msg) {
getExceptionRecorder().recordReportErrorMsg("["+errCode+",onRenderError,"+msg+"]");
if (mRenderListener != null && mContext != null) {
runOnUiThread(new Runnable() {

Expand All @@ -1281,6 +1282,7 @@ public void run() {
}

public void onJSException(final String errCode, final String function, final String exception) {
getExceptionRecorder().recordReportErrorMsg("["+errCode+","+function+","+exception+"]");
if (mRenderListener != null && mContext != null) {
runOnUiThread(new Runnable() {

Expand Down Expand Up @@ -1846,7 +1848,6 @@ public void onHttpResponseProgress(int loadedLength) {

@Override
public void onHttpFinish(WXResponse response) {
mApmForInstance.onStage(WXInstanceApm.KEY_PAGE_STAGES_DOWN_BUNDLE_END);

if (this.instance != null
&& this.instance.getWXStatisticsListener() != null) {
Expand Down Expand Up @@ -1927,6 +1928,7 @@ public void onHttpFinish(WXResponse response) {
WXLogUtils.renderPerformanceLog("networkTime", mWXPerformance.networkTime);
String wxErrorCode = WXInstanceApm.VALUE_ERROR_CODE_DEFAULT;
if (response!=null && response.originalData!=null && TextUtils.equals("200", response.statusCode)) {
mApmForInstance.onStage(WXInstanceApm.KEY_PAGE_STAGES_DOWN_BUNDLE_END);
String template = new String(response.originalData);
render(pageName, template, options, jsonInitData, flag);

Expand All @@ -1951,6 +1953,7 @@ public void onHttpFinish(WXResponse response) {
);
}
else {
getExceptionRecorder().isDownLoadBundleFailed = true;
wxErrorCode = WXErrorCode.WX_DEGRAD_ERR_NETWORK_BUNDLE_DOWNLOAD_FAILED.getErrorCode();
onRenderError(wxErrorCode,
response.errorMsg);
Expand All @@ -1974,10 +1977,10 @@ private boolean isNet(String requestType){
public String getTemplateInfo() {
String template = getTemplate();
if(template == null){
return " template md5 null " + JSONObject.toJSONString(responseHeaders);
return " template md5 null ,httpHeader:" + JSONObject.toJSONString(responseHeaders);
}
if(TextUtils.isEmpty(template)){
return " template md5 length 0 " + JSONObject.toJSONString(responseHeaders);
return " template md5 length 0 ,httpHeader" + JSONObject.toJSONString(responseHeaders);
}
try {
byte[] bts = template.getBytes("UTF-8");
Expand All @@ -1992,7 +1995,7 @@ public String getTemplateInfo() {
return " template md5 " + sourceMD5 + " length " + bts.length
+ " base64 md5 " + sourceBase64MD5
+ " response header " + JSONObject.toJSONString(responseHeaders);
} catch (UnsupportedEncodingException e) {
} catch (Exception e) {
return "template md5 getBytes error";
}

Expand Down
Expand Up @@ -196,8 +196,8 @@ public enum WXErrorCode {
/**
* WX Key Exception Commit Bundle Js Download
*/
WX_KEY_EXCEPTION_JS_DOWNLOAD("-9200", "[WX_KEY_EXCEPTION_JS_DOWNLOAD]|",ErrorType.NATIVE_ERROR,ErrorGroup.NET),
WX_KEY_EXCEPTION_JS_DOWNLOAD_FAILED("-9201", "[WX_KEY_EXCEPTION_JS_DOWNLOAD_FAILED] | details",ErrorType.NATIVE_ERROR,ErrorGroup.NET),
WX_KEY_EXCEPTION_JS_DOWNLOAD("-9200", "[WX_KEY_EXCEPTION_JS_DOWNLOAD]|",ErrorType.DOWN_LOAD_ERROR,ErrorGroup.NATIVE),
WX_KEY_EXCEPTION_JS_DOWNLOAD_FAILED("-9201", "[WX_KEY_EXCEPTION_JS_DOWNLOAD_FAILED] | details",ErrorType.DOWN_LOAD_ERROR,ErrorGroup.NATIVE),

/**
* WX Key Exception Commit RT DomAction Excute
Expand Down Expand Up @@ -245,7 +245,7 @@ public enum WXErrorCode {
/**
* degrade code.
*/
WX_DEGRAD_ERR("-1000", "degradeToH5|Weex DegradPassivity \n",ErrorType.DEGRAD_ERROR,ErrorGroup.JS),
WX_DEGRAD_ERR("-1000", "degradeToH5|Weex DegradPassivity ->",ErrorType.DEGRAD_ERROR,ErrorGroup.JS),

/**
* degrade for instance create failed, once this case occured,detail js stack and other specific
Expand All @@ -257,20 +257,20 @@ public enum WXErrorCode {
* degrade for network failed download js bundle.once this case occured,network requist response header
* and statuscode need track into errmsg.
*/
WX_DEGRAD_ERR_NETWORK_BUNDLE_DOWNLOAD_FAILED("-1002", "|wx_network_error|js bundle download failed",ErrorType.DEGRAD_ERROR,ErrorGroup.NET),
WX_DEGRAD_ERR_NETWORK_BUNDLE_DOWNLOAD_FAILED("-1002", "|wx_network_error|js bundle download failed",ErrorType.DOWN_LOAD_ERROR,ErrorGroup.NATIVE),

/**
* degrade for network failed for bundlejs is unbroken , once this case occured,network requist response header
* and statuscode need track into errmsg.
*/
WX_DEGRAD_ERR_NETWORK_CHECK_CONTENT_LENGTH_FAILED("-1003", "degradeToH5|wx_network_error|js bundle content-length check failed",ErrorType.DEGRAD_ERROR,ErrorGroup.NET),
WX_DEGRAD_ERR_NETWORK_CHECK_CONTENT_LENGTH_FAILED("-1003", "degradeToH5|wx_network_error|js bundle content-length check failed",ErrorType.DEGRAD_ERROR,ErrorGroup.NATIVE),

/**
* degrade for Response header Content-Type is null or not "application/javascript".
* once this case occured,network requist response header and statuscode need track into errmsg.
*/
WX_DEGRAD_ERR_BUNDLE_CONTENTTYPE_ERROR("-1004", "degradeToH5|wx_user_intercept_error |Content-Type is not application/javascript, " +
"Weex render template must be javascript, please check your request!",ErrorType.DEGRAD_ERROR,ErrorGroup.NET),
"Weex render template must be javascript, please check your request!",ErrorType.DEGRAD_ERROR,ErrorGroup.NATIVE),

/**
* degrade for other reason. such as white screen which block error for some unknown reason.
Expand Down Expand Up @@ -337,12 +337,12 @@ public enum ErrorType{
JS_ERROR,
NATIVE_ERROR,
RENDER_ERROR,
DEGRAD_ERROR
DEGRAD_ERROR,
DOWN_LOAD_ERROR
}

public enum ErrorGroup{
JS,
NATIVE,
NET
NATIVE
}
}
Expand Up @@ -133,15 +133,10 @@ public String getJsFrameworkVersion() {

@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("WeexSDKVersion:").append(mWeexVersion)
.append(" JSFrameworkVersion:").append(mJsFrameworkVersion)
.append(" instanceId:").append(mInstanceId)
.append(" bundleUrl:").append(mBundleUrl)
.append(" errCode:").append(mErrCode.getErrorCode())
.append(" function:").append(mFunction)
.append(" exception:").append(mException)
.append(" extParams:").append(mExtParams);
return buffer.toString();
return new StringBuilder()
.append(" errCode:").append(null == mErrCode?"unSetErrorCode":mErrCode.getErrorCode())
.append(",function:").append(null == mFunction?"unSetFuncName":mFunction)
.append(",exception:").append(null == mException?"unSetException":mException)
.toString();
}
}
Expand Up @@ -107,6 +107,7 @@ public class WXInstanceApm {
private Map<String, Double> recordStatsMap;
private boolean isFSEnd;
private boolean mHasInit = false;
private boolean mEnd = false;
private boolean hasRecordFistInteractionView =false;
public final Map<String,Object> extInfo;

Expand Down Expand Up @@ -148,7 +149,7 @@ public void onStageWithTime(String name,long time){
if (null != instance){
instance.getExceptionRecorder().recordStage(name, time);
}
if (null == apmInstance) {
if (null == apmInstance || mEnd) {
return;
}
apmInstance.onStage(name, time);
Expand All @@ -159,7 +160,7 @@ public void onStageWithTime(String name,long time){
* record property
*/
public void addProperty(String key, Object value) {
if (null == apmInstance) {
if (null == apmInstance || mEnd) {
return;
}
apmInstance.addProperty(key, value);
Expand All @@ -169,7 +170,7 @@ public void addProperty(String key, Object value) {
* record statistic
*/
public void addStats(String key, double value) {
if (null == apmInstance) {
if (null == apmInstance || mEnd) {
return;
}
apmInstance.addStats(key, value);
Expand Down Expand Up @@ -234,11 +235,12 @@ public void onDisAppear(){
* end record
*/
public void onEnd() {
if (null == apmInstance) {
if (null == apmInstance || mEnd) {
return;
}
onStage(KEY_PAGE_STAGES_DESTROY);
apmInstance.onEnd();
mEnd = true;
}

public void arriveFSRenderTime() {
Expand Down
Expand Up @@ -29,6 +29,7 @@
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

import android.text.TextUtils;
import com.taobao.weex.common.WXErrorCode;
import com.taobao.weex.common.WXErrorCode.ErrorGroup;
import com.taobao.weex.common.WXErrorCode.ErrorType;
Expand All @@ -42,12 +43,14 @@ public class WXInstanceExceptionRecord {
public static final String KEY_EXP_STAGE_LIST = "wxStageList";

private final Map<String,Long> mStageMap;
public final List<WXJSExceptionInfo> errorList;
public final List<String> errorList;
public final String instanceId;
public final AtomicBoolean hasAddView;
public final AtomicBoolean hasDegrade;
private boolean mHasReportScreenEmpty = false;
private boolean mBeginRender = false;
public boolean isDownLoadBundleFailed = false;
public static boolean isReportWriteScreen = true;

public WXInstanceExceptionRecord(String instanceId) {
this.instanceId = instanceId;
Expand All @@ -70,20 +73,30 @@ public void recordErrorMsg(WXJSExceptionInfo exceptionInfo) {
mHasReportScreenEmpty = true;
return;
}
recordReportErrorMsg(exceptionInfo.toString());
}

public void recordReportErrorMsg(String appendStr){
if (!isReportWriteScreen){
return;
}
//screen has view, or degrade , will not be empty
if (hasAddView.get() || hasDegrade.get()) {
if (TextUtils.isEmpty(appendStr) || hasAddView.get() || hasDegrade.get()) {
return;
}
if (errorList.size() > sErrorMsgSizeLimit) {
errorList.remove(0);
}
errorList.add(exceptionInfo);
errorList.add(new StringBuilder()
.append("time ").append(System.currentTimeMillis())
.append(",msg ").append(appendStr).toString()
);
}

public void recordStage(String stage, long time) {
if (WXInstanceApm.KEY_PAGE_STAGES_RENDER_ORGIGIN.equals(stage)
|| WXInstanceApm.KEY_PAGE_STAGES_DOWN_BUNDLE_START.equals(stage)
|| WXInstanceApm.KEY_PAGE_STAGES_LOAD_BUNDLE_START.equals(stage)
|| WXInstanceApm.KEY_PAGE_STAGES_LOAD_BUNDLE_END.equals(stage)
) {
setBeginRender(true);
}
Expand All @@ -96,7 +109,7 @@ public void setBeginRender(boolean isBegin){

public String convertStageToStr() {
if (mStageMap.isEmpty()) {
return "emptyStage";
return "noStageRecord";
}
List<Map.Entry<String,Long>> list = new ArrayList<>(mStageMap.entrySet());
Collections.sort(list, new Comparator<Entry<String, Long>>() {
Expand All @@ -115,85 +128,74 @@ public int compare(Entry<String, Long> o1, Entry<String, Long> o2) {

private String convertExceptionListToString() {
if (errorList.isEmpty()) {
return "empty";
return "";
}
StringBuilder builder = new StringBuilder();
builder.append("======== error stack start (top5) =====\n");
for (WXJSExceptionInfo info : errorList) {
builder.append("time :").append(info.time).append("\n")
.append("extErrorCode :").append(info.getErrCode().getErrorCode()).append('\n')
.append("extErrorType :").append(info.getErrCode().getErrorType()).append('\n')
.append("extErrorGroup :").append(info.getErrCode().getErrorGroup()).append('\n')
.append("extErrorMsg :").append(info.getErrCode().getErrorMsg()).append('\n')
.append("extErrorExceptionDetail :").append(info.getException()).append('\n')
.append("extErrorStageList :").append(
info.getExtParams().containsKey(KEY_EXP_STAGE_LIST) ? info.getExtParams().get(KEY_EXP_STAGE_LIST)
: "empty"
).append("\n")
.append("============= next ==============\n");
int i = 0;
for (String info : errorList) {
builder.append("error_").append(i).append(": ").append(info).append("--->");
}
builder.append("======== error stack end =====\n");
return builder.toString();
}

public void checkEmptyScreenAndReport() {
if (!mBeginRender || mHasReportScreenEmpty || hasAddView.get() || hasDegrade.get()) {
if (!isReportWriteScreen || isDownLoadBundleFailed){
return;
}
//2s limit of instance stayTime (case in\quit very fast case)
final long DIFF_LIMIT_FROM_RENDER_URL = 2000;
final long DIFF_LIMIT_FROM_RENDER_TEMPLATE = 1000;

long curTime = WXUtils.getFixUnixTime();
Long startRequestTime = mStageMap.get(WXInstanceApm.KEY_PAGE_STAGES_DOWN_BUNDLE_START);
long useTime;
String useTimeForm;
boolean shouldReportByUseTime;
if (null != startRequestTime) {
useTime = curTime - startRequestTime;
shouldReportByUseTime = useTime >= DIFF_LIMIT_FROM_RENDER_URL;
useTimeForm = WXInstanceApm.KEY_PAGE_STAGES_DOWN_BUNDLE_START;
}else {
Long startRenderTemplateTime = mStageMap.get(WXInstanceApm.KEY_PAGE_STAGES_RENDER_ORGIGIN);
useTime = null != startRenderTemplateTime?curTime - startRenderTemplateTime:curTime;
shouldReportByUseTime = useTime >= DIFF_LIMIT_FROM_RENDER_TEMPLATE;
useTimeForm = WXInstanceApm.KEY_PAGE_STAGES_RENDER_ORGIGIN;
if (!mBeginRender || mHasReportScreenEmpty || hasAddView.get() || hasDegrade.get()) {
return;
}

if (!shouldReportByUseTime){
Long startExecJsTime = mStageMap.get(WXInstanceApm.KEY_PAGE_STAGES_LOAD_BUNDLE_END);
if (null == startExecJsTime){
//too fast to quit
return;
}
long currentTime = WXUtils.getFixUnixTime();
long jsExecTime = currentTime - startExecJsTime;
//3s limit of instance stayTime (case in\quit very fast case)
if (jsExecTime <= 3000){
return;
}

boolean hasJsException = false;
for (WXJSExceptionInfo info : errorList) {
if (info.getErrCode().getErrorGroup() == ErrorGroup.JS) {
hasJsException = true;
break;
}
String errorMsg;
if(errorList.isEmpty()){
errorMsg = mStageMap.containsKey(WXInstanceApm.KEY_PAGE_STAGES_CREATE_FINISH)
?"writeScreen :never add view until page destroy(js has execute > 3s)"
:"writeScreen :never add view even js executeTime > 3s";
}else {
errorMsg = "writeScreen :history exception :"+ convertExceptionListToString();
}


Map<String,String> flagMap = new HashMap<>(4);
flagMap.put("wxBeginRender",String.valueOf(mBeginRender));
flagMap.put("wxHasAddView",String.valueOf(hasAddView.get()));
flagMap.put("wxHasDegrade",String.valueOf(hasDegrade.get()));
flagMap.put("wxHasReportScreenEmpty",String.valueOf(mHasReportScreenEmpty));
flagMap.put("wxUseTime", String.valueOf(useTime));
flagMap.put("wxUseTimeForm", useTimeForm);
flagMap.put("wxJSExecTime", String.valueOf(jsExecTime));

WXExceptionUtils.commitCriticalExceptionRT(
instanceId,
hasJsException ? WXErrorCode.WX_RENDER_ERR_JS_RUNTIME : WXErrorCode.WX_RENDER_ERR_NATIVE_RUNTIME,
WXErrorCode.WX_RENDER_ERR_JS_RUNTIME,
"checkEmptyScreenAndReport",
convertExceptionListToString(),
errorMsg,
flagMap
);
}

public Long getStageTime(String key){
return mStageMap.get(key);
}



@Override
public String toString() {
return new StringBuilder()
.append(super.toString())
.append("wxStageList :\n").append(convertStageToStr())
.append("wxErrorList :\n").append(convertExceptionListToString())
.append("wxStageList :").append(convertStageToStr())
.append("wxErrorList :").append(convertExceptionListToString())
.toString();
}
}