[
https://issues.apache.org/jira/browse/WEEX-587?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16589839#comment-16589839
]
ASF GitHub Bot commented on WEEX-587:
-------------------------------------
cxfeng1 closed pull request #1469: [WEEX-587][iOS] excpetion report fix
URL: https://github.com/apache/incubator-weex/pull/1469
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
index 7497dabe5a..bf747fed0d 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
@@ -1046,9 +1046,6 @@ + (void)mountContextEnvironment:(JSContext*)context
message = [NSString stringWithFormat:@"[WX_KEY_EXCEPTION_WXBRIDGE]
[%@:%@:%@] %@\n%@\n%@\n%@\n%@\n%@", exception[@"sourceURL"],
exception[@"line"], exception[@"column"], [exception toString],
[exception[@"stack"] toObject], instance.scriptURL.absoluteString,
instance.callCreateInstanceContext?:@"",
instance.createInstanceContextResult?:@"", instance.executeRaxApiResult?:@""];
userInfo =
@{@"jsMainBundleStringContentLength":instance.userInfo[@"jsMainBundleStringContentLength"]?:@"",
@"jsMainBundleStringContentMd5":instance.userInfo[@"jsMainBundleStringContentMd5"]?:@""};
- if ([self checkEmptyScreen:instance]) {
- errorCode = [NSString stringWithFormat:@"%d",
WX_KEY_EXCEPTION_EMPTY_SCREEN_JS];
- }
}
if (commitException) {
@@ -1121,24 +1118,4 @@ +
(void)handleConsoleOutputWithArgument:(NSArray*)arguments logLevel:(WXLogFlag)
}
}];
}
-
-+ (BOOL) checkEmptyScreen:(WXSDKInstance *) instance
-{
- if(!instance){
- return false;
- }
- if (!(instance.rootView) ) {
- return true;
- }
- CGRect rootFrame = instance.rootView.frame;
-
- if (rootFrame.size.height <=0 || rootFrame.size.width <=0) {
- return true;
- }
-
- if (!(instance.rootView.subviews) || instance.rootView.subviews.count <=0)
{
- return true;
- }
- return false;
-}
@end
diff --git a/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.h
b/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.h
index ba446b2521..e7606669be 100644
--- a/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.h
+++ b/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.h
@@ -79,7 +79,8 @@ typedef NS_ENUM(int, WXSDKErrCode)
WX_KEY_EXCEPTION_ABILITY_DOWN_TOH5 = -9602,
WX_KEY_EXCEPTION_ABILITY_DOWN_ = -9603,
- WX_KEY_EXCEPTION_EMPTY_SCREEN_JS = -9700
+ WX_KEY_EXCEPTION_EMPTY_SCREEN_JS = -9700,
+ WX_KEY_EXCEPTION_EMPTY_SCREEN_NATIVE = -9701
};
typedef NS_ENUM (NSInteger,WXSDKErrorType)
diff --git a/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.m
b/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.m
index c3b9a7791a..48c046f107 100644
--- a/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.m
+++ b/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.m
@@ -99,7 +99,8 @@ +(NSDictionary *) getMap
@(WX_KEY_EXCEPTION_ABILITY_DOWN_TOH5):@{ERROR_TYPE:@(WX_NATIVE_ERROR),ERROR_GROUP:@(WX_NATIVE)},
@(WX_ERR_JSFRAMEWORK_START):@{ERROR_TYPE:@(WX_NATIVE_ERROR),ERROR_GROUP:@(WX_NATIVE)},
@(WX_KEY_EXCEPTION_ABILITY_DOWN_):@{ERROR_TYPE:@(WX_NATIVE_ERROR),ERROR_GROUP:@(WX_NATIVE)},
-
@(WX_KEY_EXCEPTION_EMPTY_SCREEN_JS):@{ERROR_TYPE:@(WX_RENDER_ERROR),ERROR_GROUP:@(WX_JS)}
+
@(WX_KEY_EXCEPTION_EMPTY_SCREEN_JS):@{ERROR_TYPE:@(WX_RENDER_ERROR),ERROR_GROUP:@(WX_JS)},
+
@(WX_KEY_EXCEPTION_EMPTY_SCREEN_NATIVE):@{ERROR_TYPE:@(WX_RENDER_ERROR),ERROR_GROUP:@(WX_NATIVE)}
};
});
return codeMap;
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
index f1a4296e7a..c74f79df93 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
@@ -156,6 +156,11 @@ - (void)createInstance:(NSString *)instance
[self.instanceIdStack insertObject:instance atIndex:0];
}
}
+ //third team impl...
+ WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instance];
+ if (sdkInstance) {
+ sdkInstance.apmInstance.isStartRender = YES;
+ }
__weak typeof(self) weakSelf = self;
WXPerformBlockOnBridgeThread(^(){
[WXTracingManager startTracingWithInstanceId:instance ref:nil
className:nil name:WXTExecJS phase:WXTracingBegin
functionName:@"createInstance" options:@{@"threadName":WXTJSBridgeThread}];
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm
b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm
index a9146cba73..af710b73cb 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm
@@ -267,6 +267,7 @@ - (void)addComponent:(NSDictionary *)componentData
toSupercomponent:(NSString *)
WXLogWarning(@"addComponent,superRef from js never exit ! check JS
action, supRef:%@",superRef);
return;
}
+ supercomponent.weexInstance.apmInstance.hasAddView = YES;
[self _recursivelyAddComponent:componentData
toSupercomponent:supercomponent atIndex:index appendingInTree:appendingInTree];
}
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
index 56e6a6b934..95fa7f24ff 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
+++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
@@ -316,6 +316,11 @@ typedef NS_ENUM(NSInteger, WXErrorCode) {//error.code
*/
- (NSURL *)completeURL:(NSString *)url;
+/**
+ * jsbundle str ,may be nil (weak)
+ */
+- (NSString*) bundleTemplate;
+
/**
* application performance statistics
*/
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
index 0b9782530f..69ee169722 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
+++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
@@ -218,6 +218,7 @@ - (void)renderWithURL:(NSURL *)url options:(NSDictionary
*)options data:(id)data
return;
}
[self.apmInstance startRecord:self.instanceId];
+ self.apmInstance.isStartRender = YES;
self.needValidate = [[WXHandlerFactory
handlerForProtocol:@protocol(WXValidateProtocol)] needValidate:url];
WXResourceRequest *request = [WXResourceRequest requestWithURL:url
resourceType:WXResourceTypeMainBundle referrer:@""
cachePolicy:NSURLRequestUseProtocolCachePolicy];
@@ -239,6 +240,11 @@ - (void)renderView:(NSString *)source
options:(NSDictionary *)options data:(id)d
[WXTracingManager setBundleJSType:source instanceId:self.instanceId];
}
+- (NSString*) bundleTemplate
+{
+ return self.mainBundleString;
+}
+
- (void)_renderWithMainBundleString:(NSString *)mainBundleString
{
if (!self.instanceId) {
@@ -248,6 +254,7 @@ - (void)_renderWithMainBundleString:(NSString
*)mainBundleString
//some case , with out render (url)
[self.apmInstance startRecord:self.instanceId];
+ self.apmInstance.isStartRender = YES;
self.performance.renderTimeOrigin = CACurrentMediaTime()*1000;
[self.apmInstance onStage:KEY_PAGE_STAGES_RENDER_ORGIGIN];
diff --git a/ios/sdk/WeexSDK/Sources/Monitor/WXExceptionUtils.m
b/ios/sdk/WeexSDK/Sources/Monitor/WXExceptionUtils.m
index 9599505ff4..286b6550b3 100644
--- a/ios/sdk/WeexSDK/Sources/Monitor/WXExceptionUtils.m
+++ b/ios/sdk/WeexSDK/Sources/Monitor/WXExceptionUtils.m
@@ -35,22 +35,38 @@ + (void)commitCriticalExceptionRT:(NSString *)instanceId
errCode:(NSString *)err
NSString *bundleUrlCommit = @"BundleUrlDefault";
NSString *instanceIdCommit = @"InstanceIdDefalut";
+ WXSDKInstance * instance ;
if(![WXUtility isBlankString:instanceId]){
instanceIdCommit = instanceId;
- WXSDKInstance * instance = [WXSDKManager instanceForID:instanceId];
+ instance = [WXSDKManager instanceForID:instanceId];
if(instance){
bundleUrlCommit = instance.pageName?:([instance.scriptURL
absoluteString]?:bundleUrlCommit);
+ NSMutableDictionary* extInfo = [[NSMutableDictionary alloc]
initWithDictionary:extParams];
if (instance.containerInfo && instance.containerInfo.count >0) {
- NSMutableDictionary* extInfo = [[NSMutableDictionary alloc]
initWithDictionary:extParams];
[extInfo addEntriesFromDictionary:instance.containerInfo];
- extParams = extInfo;
}
+ [extInfo setObject:[self _convertInstanceStageToStr:instance]
forKey:@"wxStageList"];
+ [extInfo setObject:instance.pageName?:@"unKnowPageNameCaseUnSet"
forKey:@"wxPageName"];
+ [extInfo setObject:instance.bundleTemplate?:@"has recycle"
forKey:@"wxTemplateOfBundle"];
+ extParams = extInfo;
}else if([instanceIdCommit hasPrefix:@"WX_KEY_EXCEPTION"]){
bundleUrlCommit = instanceId;
}
}
-
+
WXJSExceptionInfo * jsExceptionInfo = [[WXJSExceptionInfo alloc]
initWithInstanceId:instanceIdCommit bundleUrl:bundleUrlCommit errorCode:errCode
functionName:function exception:exception userInfo: [extParams mutableCopy]];
+
+ //record top5 erromsg ,if errorType is not WX_RENDER_ERROR
+ NSNumberFormatter *formater = [[NSNumberFormatter alloc] init];
+ formater.numberStyle = NSNumberFormatterDecimalStyle;
+ NSNumber *codeNumber = [formater numberFromString:errCode];
+ if (codeNumber) {
+ WXSDKErrorType type = [WXSDKErrCodeUtil
getErrorTypeByCode:codeNumber.intValue];
+ if (type != WX_RENDER_ERROR && nil != instance) {
+ [instance.apmInstance recordErrorMsg:jsExceptionInfo];
+ }
+ }
+
[WXExceptionUtils commitCriticalExceptionRT:jsExceptionInfo];
}
@@ -64,4 +80,23 @@ + (void)commitCriticalExceptionRT:(WXJSExceptionInfo
*)jsExceptionInfo{
}
}
++ (NSString*) _convertInstanceStageToStr:(WXSDKInstance *)instance
+{
+ if (nil == instance || !instance.apmInstance.isOpenApm) {
+ return @"";
+ }
+ NSDictionary<NSString*,NSNumber*>* stageDic =
instance.apmInstance.stageDic;
+ if (!stageDic || stageDic.count <=0 ) {
+ return @"emptyStageRecord";
+ }
+ NSString* stageStr = @"";
+ for (NSString* key in stageDic) {
+ NSNumber* time = [stageDic objectForKey:key];
+ stageStr = [stageStr stringByAppendingFormat:@"%@ ->
%@:%@",stageStr,key,time];
+ }
+ return stageStr;
+}
+
+
+
@end
diff --git a/ios/sdk/WeexSDK/Sources/Performance/WXApmForInstance.h
b/ios/sdk/WeexSDK/Sources/Performance/WXApmForInstance.h
index 15748444a6..585add2dfb 100644
--- a/ios/sdk/WeexSDK/Sources/Performance/WXApmForInstance.h
+++ b/ios/sdk/WeexSDK/Sources/Performance/WXApmForInstance.h
@@ -1,4 +1,5 @@
#import <Foundation/Foundation.h>
+#import "WXJSExceptionInfo.h"
#pragma mark - const static string
@@ -76,8 +77,12 @@ extern NSString* const VALUE_ERROR_CODE_DEFAULT;
@interface WXApmForInstance : NSObject
-@property (nonatomic, assign) bool isFSEnd;
-@property (nonatomic, assign) bool isStartRecord;
+@property (nonatomic, assign) BOOL isFSEnd;
+@property (nonatomic,assign) BOOL isOpenApm;
+@property (nonatomic, assign) BOOL isStartRecord;
+@property (nonatomic, assign) BOOL hasAddView;
+@property (nonatomic, assign) BOOL isDegrade;
+@property (nonatomic, assign) BOOL isStartRender;
#pragma mark - basic method
@@ -106,4 +111,7 @@ extern NSString* const VALUE_ERROR_CODE_DEFAULT;
- (void) actionImgLoad;
- (void) actionImgLoadResult:(bool)succeed withErrorCode:(NSString*)errorCode;
+#pragma mark record top5 errorMsg
+- (void) recordErrorMsg:(WXJSExceptionInfo *)exception;
+- (NSDictionary<NSString*,NSNumber*>*) stageDic;
@end
diff --git a/ios/sdk/WeexSDK/Sources/Performance/WXInstanceApm.m
b/ios/sdk/WeexSDK/Sources/Performance/WXInstanceApm.m
index 3264a727ff..845464d91b 100644
--- a/ios/sdk/WeexSDK/Sources/Performance/WXInstanceApm.m
+++ b/ios/sdk/WeexSDK/Sources/Performance/WXInstanceApm.m
@@ -4,6 +4,11 @@
#import "WXSDKManager.h"
#import "WXAppConfiguration.h"
#import "WXUtility.h"
+#import "WXComponentManager.h"
+#import "WXConfigCenterProtocol.h"
+#import "WXSDKEngine.h"
+#import "WXSDKError.h"
+#import "WXExceptionUtils.h"
#pragma mark - const static string
@@ -82,6 +87,9 @@ @interface WXApmForInstance ()
@property (nonatomic,strong) id<WXApmProtocol> apmProtocolInstance;
@property (nonatomic,strong) NSString* instanceId;
@property (nonatomic,strong) NSMutableDictionary<NSString*,NSNumber*>*
recordStatsMap;
+@property (nonatomic,assign) BOOL isRecord;
+@property (nonatomic,strong) NSMutableDictionary<NSString*,NSNumber*>*
recordStageMap;
+@property (nonatomic,strong) NSMutableArray<WXJSExceptionInfo*>* errorList;
@end
@implementation WXApmForInstance
@@ -91,9 +99,14 @@ - (instancetype) init
{
self = [super init];
if (self) {
- id<WXApmGeneratorProtocol> generater = [WXHandlerFactory
handlerForProtocol:@protocol(WXApmGeneratorProtocol)];
- _apmProtocolInstance = [generater
gengratorApmInstance:WEEX_PAGE_TOPIC];
_recordStatsMap = [[NSMutableDictionary alloc] init];
+ _recordStageMap = [[NSMutableDictionary alloc] init];
+ _errorList = [[NSMutableArray alloc] init];
+ _isOpenApm = [self _loadApmSwitch];
+ if (_isOpenApm) {
+ id<WXApmGeneratorProtocol> generater = [WXHandlerFactory
handlerForProtocol:@protocol(WXApmGeneratorProtocol)];
+ _apmProtocolInstance = [generater
gengratorApmInstance:WEEX_PAGE_TOPIC];
+ }
}
return self;
}
@@ -111,7 +124,12 @@ - (void) onStage:(NSString *)name
if (nil == _apmProtocolInstance) {
return;
}
- [self.apmProtocolInstance onStage:name withValue:[WXUtility
getUnixFixTimeMillis]];
+ long time = [WXUtility getUnixFixTimeMillis];
+ [self.apmProtocolInstance onStage:name withValue:time];
+ __weak typeof(self) weakSelf = self;
+ WXPerformBlockOnComponentThread(^{
+ [weakSelf.recordStageMap setObject:@(time) forKey:name];
+ });
}
- (void) setProperty:(NSString *)name withValue:(id)value
@@ -134,10 +152,10 @@ - (void) setStatistic:(NSString *)name
withValue:(double)value
- (void) startRecord:(NSString*) instanceId
{
- if (nil == _apmProtocolInstance || self.isStartRecord) {
+ if (nil == _apmProtocolInstance || self.isRecord) {
return;
}
- self.isStartRecord = YES;
+ self.isRecord = YES;
_instanceId = instanceId;
[self.apmProtocolInstance onStart:instanceId topic:WEEX_PAGE_TOPIC];
@@ -178,6 +196,7 @@ - (void) endRecord;
[self onStage:KEY_PAGE_STAGES_DESTROY];
[self.apmProtocolInstance onEnd];
+ [self _checkScreenEmptyAndReport];
}
- (void) arriveFSRenderTime
@@ -202,11 +221,14 @@ - (void) updateDiffStats:(NSString *)name
withDiffValue:(double)diff
if (nil == _apmProtocolInstance) {
return;
}
- NSNumber* preNumber = [self.recordStatsMap objectForKey:name];
- double preVal = nil == preNumber?0:preNumber.doubleValue;
- double currentVal = preVal + diff;
- [self.recordStatsMap setObject:@(currentVal) forKey:name];
- [self setStatistic:name withValue:currentVal];
+ __weak typeof(self) weakSelf = self;
+ WXPerformBlockOnComponentThread(^{
+ NSNumber* preNumber = [self.recordStatsMap objectForKey:name];
+ double preVal = nil == preNumber?0:preNumber.doubleValue;
+ double currentVal = preVal + diff;
+ [weakSelf.recordStatsMap setObject:@(currentVal) forKey:name];
+ [weakSelf setStatistic:name withValue:currentVal];
+ });
}
- (void) updateMaxStats:(NSString *)name curMaxValue:(double)currentValue
@@ -214,14 +236,17 @@ - (void) updateMaxStats:(NSString *)name
curMaxValue:(double)currentValue
if (nil == _apmProtocolInstance) {
return;
}
- NSNumber* maxNumber = [self.recordStatsMap objectForKey:name];
- double maxVal = nil == maxNumber?0:maxNumber.doubleValue;
-
- if (maxVal < currentValue) {
- maxVal = currentValue;
- [self.recordStatsMap setObject:@(maxVal) forKey:name];
- [self setStatistic:name withValue:maxVal];
- }
+ __weak typeof(self) weakSelf = self;
+ WXPerformBlockOnComponentThread(^{
+ NSNumber* maxNumber = [weakSelf.recordStatsMap objectForKey:name];
+ double maxVal = nil == maxNumber?0:maxNumber.doubleValue;
+
+ if (maxVal < currentValue) {
+ maxVal = currentValue;
+ [weakSelf.recordStatsMap setObject:@(maxVal) forKey:name];
+ [weakSelf setStatistic:name withValue:maxVal];
+ }
+ });
}
- (void) updateExtInfo:(NSDictionary*) extInfo
@@ -294,5 +319,87 @@ - (void) actionImgLoadResult:(bool)succeed
withErrorCode:(NSString*)errorCode
}
}
+- (void) recordErrorMsg:(WXJSExceptionInfo *)exception
+{
+ if (nil == exception || !self.isOpenApm) {
+ return;
+ }
+ __weak typeof(self) weakSelf = self;
+ WXPerformBlockOnComponentThread(^{
+ if (weakSelf.errorList.count > 5) {
+ [weakSelf.errorList removeObjectAtIndex:0];
+ [weakSelf.errorList addObject:exception];
+ }
+ });
+}
+
+- (NSArray<WXJSExceptionInfo*>*) topExceptionList
+{
+ return self.errorList;
+}
+
+- (void) _checkScreenEmptyAndReport
+{
+ if(self.hasAddView || !self.isStartRender || self.isDegrade){
+ return;
+ }
+ WXSDKErrCode code = WX_KEY_EXCEPTION_EMPTY_SCREEN_NATIVE;
+
+
+ NSNumberFormatter *formater = [[NSNumberFormatter alloc] init];
+ formater.numberStyle = NSNumberFormatterDecimalStyle;
+
+ for (WXJSExceptionInfo* exception in self.errorList) {
+ NSNumber *codeNumber = [formater numberFromString:exception.errorCode];
+ if (nil == codeNumber) {
+ continue;
+ }
+ WXSDKErrorGroup group = [WXSDKErrCodeUtil
getErrorGroupByCode:codeNumber.intValue];
+ if(group == WX_JS){
+ code = WX_KEY_EXCEPTION_EMPTY_SCREEN_JS;
+ break;
+ }
+ }
+ NSString *codeStr = [NSString stringWithFormat:@"%d",code];
+ [WXExceptionUtils commitCriticalExceptionRT:self.instanceId
errCode:codeStr function:@"_checkScreenEmptyAndReport"
+ exception:[self
_convertTopExceptionListToStr] extParams:nil];
+
+}
+
+- (NSString *)_convertTopExceptionListToStr
+{
+ if (!self.isOpenApm) {
+ return @"";
+ }
+ if (!self.errorList || self.errorList.count <= 0) {
+ return @"emptyTopErrorlist";
+ }
+ NSString* errorStr = @"========== topErrorList start ============";
+ for (WXJSExceptionInfo* exception in self.errorList) {
+ errorStr = [errorStr stringByAppendingFormat:
+ @"%@ -> code:%@,func:%@,exception:%@ \n",
+
errorStr,exception.errorCode,exception.functionName,exception.exception
+ ];
+ }
+ errorStr = [errorStr stringByAppendingFormat:@"%@ ========== topErrorList
start end ============\n",errorStr];
+ return errorStr;
+}
+
+- (NSDictionary<NSString*,NSNumber*>*) stageDic
+{
+ return self.recordStageMap;
+}
+
+- (BOOL) _loadApmSwitch
+{
+ BOOL openApm = YES;
+ id<WXConfigCenterProtocol> configCenter = [WXSDKEngine
handlerForProtocol:@protocol(WXConfigCenterProtocol)];
+
+ if ([configCenter
respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) {
+ openApm = [[configCenter configForKey:@"iOS_weex_ext_config.open_apm"
defaultValue:@(YES) isDefault:NULL] boolValue];
+ }
+ return openApm;
+}
+
@end
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
> [iOS] 异常上报fix
> -------------
>
> Key: WEEX-587
> URL: https://issues.apache.org/jira/browse/WEEX-587
> Project: Weex
> Issue Type: Bug
> Reporter: peihan
> Assignee: Adam Feng
> Priority: Major
>
> * 白屏监测算法修改
> * 上报instance 当前执行的状态、步骤
> * 上报pagename、ur
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)