rn-blockmonitor
Version:
block monitor
212 lines (192 loc) • 5.73 kB
JavaScript
// @ts-nocheck
import MessageQueue from 'react-native/Libraries/BatchedBridge/MessageQueue';
import { AppState } from 'react-native';
import HMS from 'house-middleware-sdk';
import { BMLinkList } from './BMLinkList';
import DeviceInfo from 'react-native-device-info';
const JSEventLoopWatchdog = require('./BMJSEventLoopWatchdog'); // eslint-disable-line @typescript-eslint/no-var-requires
let isPause = false;
AppState.addEventListener('change', (nextAppState) => {
if (nextAppState == 'background' || nextAppState == 'inactive') {
console.log('========================view_pause========================');
isPause = true;
} else if (nextAppState == 'active') {
console.log('========================view_resume========================');
if (isPause) {
JSEventLoopWatchdog.reset();
isPause = false;
}
}
});
const blockStack = [];
function saveStall(busyTime, lastInterval, now) {
if (global.origin) {
if (!showBroserLog) return;
}
if (!global.callStack) {
return;
}
if (!uploadStackUrl || uploadStackUrl.length === 0) return;
let stack;
if (global.callStack && global.callStack.getUploadData) {
stack = global.callStack.getUploadData(busyTime, lastInterval, now, thresholdInterval);
}
if (stack) {
blockStack.push({
type: 'BLOCK',
blockTime: busyTime,
callStack: stack,
pageName: global.CURRENT_PAGE
});
}
}
function buildHeader(data) {
const header = {};
if (!data || !data.os) {
header.imei = DeviceInfo.getUniqueId();
header.device = `${DeviceInfo.getBrand()}-${DeviceInfo.getModel()}`;
header.version = DeviceInfo.getVersion();
data = {
os: Platform.OS,
osv: DeviceInfo.getSystemVersion()
};
} else {
header.imei = global.IS_ANDROID ? data.imei : data.openudid;
header.device = global.IS_ANDROID ? (`${data.brand}-${data.ua}`) : (data.ua.split('_')[0]);
header.version = data.version;
}
header.insectVersion = '2.1.0';
header.appName = global.CURRENT_PACKAGE;
header.os = `RN-${data.os}-${data.osv}`;
header['Content-Type'] = 'application/x-www-form-urlencoded';
return header;
}
function buildBody() {
const dataList = [];
blockStack.map((v) => {
const dataObject = {};
dataObject.page = global.CURRENT_PAGE;
dataObject.type = '4';
dataObject.stackInfo = v.callStack;
dataObject.blockTime = v.blockTime;
// dataObject.FPS = '';
// dataObject.CPU = '';
// dataObject.memory = '';
// dataObject.functionTime = '';
// dataObject.flow = '';
// dataObject.startupTime = '';
dataObject.ext1 = '';
dataObject.ext2 = { bundleId: global.BUNDLE_ID };
dataList.push(dataObject);
return false;
});
return `data=${JSON.stringify(dataList)}`;
}
function status(response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response);
}
return Promise.reject(new Error(response.statusText));
}
function toJson(response) {
return new Promise((resolve, reject) => {
response.json()
.then((jsonData) => {
resolve(jsonData);
})
.catch((e) => {
reject(e);
});
});
}
function error(e) {
return Promise.reject(e);
}
function uploadBlock() {
if (global.origin) {
return;
}
if (__DEV__) {
if (!offlineUploadStackSwitchOn) return;
} else if (!onlineUploadStackSwitchOn) return;
if (!uploadStackUrl || uploadStackUrl.length === 0) return;
setTimeout(() => {
if (blockStack.length > 0) {
Promise.race([
new Promise((resolve) => {
HMS.initNativeParams((initParams) => {
resolve(initParams);
}, true);
})
.then(initParams => fetch(uploadStackUrl, {
method: 'POST',
headers: buildHeader(initParams.httpHeader),
body: buildBody()
}))
.then(status)
.then(toJson)
.catch(error),
new Promise((resolve, reject) => setTimeout(() => {
reject(new Error('网络超时'));
}, 10000))
])
.then((res) => {
if (res.status === 0) {
blockStack.splice(0, blockStack.length);
}
})
.catch();
}
uploadBlock();
}, 5000);
}
const BMMonitor = {
register() {
global.CURRENT_PAGE = 'INIT';
console.log('Index', 'start');
JSEventLoopWatchdog.install({
thresholdMS: thresholdInterval
});
uploadBlock();
let spyBuffer = [];
MessageQueue.spy((data) => {
spyBuffer.push(data);
});
JSEventLoopWatchdog.addHandler({
onStall: ({ busyTime, lastInterval, now }) => {
if (isPause) return;
saveStall(busyTime, lastInterval, now);
},
onIterate: () => {
spyBuffer = [];
}
});
}
};
let thresholdInterval = global.origin ? 200 : 200;
let uploadStackUrl = null;
let onlineUploadStackSwitchOn = true;
let offlineUploadStackSwitchOn = false;
let stopWatchdog = false;
let showBroserLog = false;
export function StartMonitor(config) {
// HMS.showToast(`${JSON.stringify(config)}`,6);
if (!config) {
return;
}
stopWatchdog = config.stopWatchdog;
if (stopWatchdog) {
JSEventLoopWatchdog.stop();
return;
}
uploadStackUrl = config.uploadStackUrl;
onlineUploadStackSwitchOn = config.onlineUploadStackSwitchOn;
offlineUploadStackSwitchOn = config.offlineUploadStackSwitchOn;
showBroserLog = config.showBroserLog;
if (!global.callStack) {
global.callStack = new BMLinkList();
global.callStack.setMaxStackSize(config.recordLength);
global.callStack.setShowLocalConsoleLogByTimeInterval(config.showLocalConsoleLogByTimeInterval);
}
BMMonitor.register();
}