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

Commit

Permalink
[WEEX-606][Android]fix monitor data (#1497)
Browse files Browse the repository at this point in the history
* [Android] writescreen check stage limimt
* [Android] add writescreen swtich
* [Android] monitor download failed
* [Android] when download success,report download stage
  • Loading branch information
lucky-chen authored and YorkShen committed Sep 6, 2018
1 parent 419b100 commit 876c152
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 82 deletions.
11 changes: 7 additions & 4 deletions android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
}
}
Original file line number Diff line number Diff line change
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();
}
}
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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();
}
}

0 comments on commit 876c152

Please sign in to comment.