Parcourir la source

feat: 添加异常日志上报功能

TIANYONG il y a 2 semaines
Parent
commit
cf6a427e9f

+ 59 - 0
src/hooks/errorLog/index.ts

@@ -0,0 +1,59 @@
+import { uploadErrorLog } from "./uploadLog";
+import state from "/src/state";
+import { getQuery } from "/src/utils/queryString";
+
+type uploadType = {
+  clientType?: string;
+  phone?: string | undefined | null;
+  userAgent?: string;
+  appType?: string;
+  content?: string;
+  exceptionType?: string;
+  exceptionTime?: string;
+  deviceType?: string | null;
+  deviceVersion?: string | null
+}
+
+const query: any = getQuery();
+console.log(query["part-index"],1111)
+/**
+ * 页面有报错时上传错误日志
+ * @params
+ */
+export default function useErrorLog() {
+  const _uploadErrorLog = async (event: any) => {
+    // 错误信息
+    const contentError = `Error message: ${event.target.tagName || ''};${
+      event.target.src || event.target.href || ''
+    };lineno: ${event.lineno || ''};message: ${
+      event.message || ''
+    };filename: ${event.filename || ''};fileUrl: ${
+      window.location.href
+    };reason: ${event.reason?.message || ''};
+    stack: ${event.reason?.stack || ''};
+    bizId: ${state.examSongId || query.id || ''};
+    partIndex: ${query["part-index"] || 0}`;
+    uploadErrorLog(contentError)
+  };
+  /**
+   * 开始监听错误日志并上传
+   */
+  const startListenErrorLog = () => {
+    console.log('mount useErrorLog');
+    window.addEventListener('error', _uploadErrorLog);
+    window.addEventListener('unhandledrejection', _uploadErrorLog);
+  };
+
+  /**
+   * 停止监听
+   */
+  const stopListenErrorLog = () => {
+    window.removeEventListener('error', _uploadErrorLog);
+    window.removeEventListener('unhandledrejection', _uploadErrorLog);
+  };
+
+  return {
+    startListenErrorLog,
+    stopListenErrorLog
+  };
+}

+ 41 - 0
src/hooks/errorLog/uploadLog.ts

@@ -0,0 +1,41 @@
+import state from "/src/state";
+import dayjs from 'dayjs';
+import { sysExceptionLogSave } from '/src/utils/baseApi'
+import { browser } from "/src/utils";
+import { storeData } from "/src/store";
+
+// 上传错误日志
+export const uploadErrorLog = async (contentError: string) => {
+	//
+    let defaultParams = {
+		appKey: 'KLX', // 应用标识(GYT,GYM,KT,KLX,CBS),可用值:GYM,GYT,KLX,KLX_JG,KT,CBS
+		appType: browser().android ? 'ANDROID' : browser().ios && storeData.isApp ? 'IOS' : 'WEB', // 应用类型(IOS,ANDROID,HARMONY),可用值:IOS,ANDROID,HARMONY,WEB
+		clientType: '', // 客户端类型(TEACHER,STUDENT,SCHOOL,BACKEND),可用值:BACKEND,SCHOOL,TEACHER,STUDENT,TENANT	
+		content: '', // 内容
+		deviceType: null, // 设备类型
+		deviceVersion: null, // 设备版本
+		exceptionTime: null, // 异常时间
+		exceptionType: 'ERROR', // 异常类型(ERROR,RECORD),可用值:ERROR,RECORD	
+		phone: null, // 手机号
+		userAgent: window.navigator.userAgent, // 客户端信息
+	  }
+	console.log('errorLog','错误',event)
+	try {
+	console.log(window.location.hash, 'errorLog')
+
+	const params = [
+		{
+		...defaultParams,
+		clientType: state.systemType === 'teacher' ? 'TEACHER' : state.systemType === 'student' ? 'STUDENT' : 'BACKEND',
+		content: contentError,
+		exceptionTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+		phone: storeData.user?.phone,
+		userAgent: window.navigator.userAgent,
+		}
+	];
+	// console.log(params, '错误日志参数', 'errorLog')
+	await sysExceptionLogSave(params);
+	} catch {
+	//
+	}
+}

+ 11 - 1
src/page-instrument/main.ts

@@ -13,6 +13,7 @@ import "./theme.css";
 import "./custom-plugins/guide-driver/index.less"
 import { getQuery } from "/src/utils/queryString";
 import { getRequestHostname } from "/src/utils"
+import useErrorLog from "/src/hooks/errorLog"
 
 (function () {
 	const query = getQuery();
@@ -34,4 +35,13 @@ import { getRequestHostname } from "/src/utils"
 	});
 })();
 
-createApp(App).use(router).mount("#app");
+// createApp(App).use(router).mount("#app");
+const app = createApp(App)
+
+app.use(router)
+
+// 监听错误信息
+const errorLog = useErrorLog();
+errorLog.startListenErrorLog();
+
+app.mount("#app")  

+ 6 - 1
src/page-instrument/view-detail/index.tsx

@@ -42,6 +42,7 @@ import { musicData } from "/src/view/music-score"
 import Vip from "/src/page-instrument/component/vip"
 import Permission from "/src/page-instrument/component/vip/permission"
 import { getSvgPngToSize } from "/src/helpers/svgToPng"
+import { uploadErrorLog } from '/src/hooks/errorLog/uploadLog'
 // import bgJson from "./images/index.json";
 
 // const DelayCheck = defineAsyncComponent(() =>
@@ -181,8 +182,10 @@ export default defineComponent({
       state.guideInfo = guideInfoStore
       try { 
         await getMusicDetail(id);
-      } catch (err) {
+      } catch (err: any) {
         console.error(err);
+        const contentError = `reason: ${err?.message || ''};stack: ${err?.stack || ''};bizId: ${state.examSongId || query.id || ''};partIndex: ${query["part-index"] || 0};`;
+        uploadErrorLog(contentError)
         state.isLoading = false;
         isEmptyMusicShow.value = true
         // 需要向外面(iframe)派发计时器数据的时候触发
@@ -348,6 +351,8 @@ export default defineComponent({
         handleRendered(osmd)
       }catch(err:any){
         console.log(err, "err")
+        const contentError = `reason: ${err?.message || ''};stack: ${err?.stack || ''};bizId: ${state.examSongId || query.id || ''};partIndex: ${query["part-index"] || 0};`;
+        uploadErrorLog(contentError)
         // 需要向外面(iframe)派发计时器数据的时候触发
         if(query.isbeatTimes){
           console.log("webApi_beatTimes",err)

+ 0 - 1
src/state.ts

@@ -24,7 +24,6 @@ import { api_lessonTrainingTrainingStudentDetail } from "/src/page-instrument/ap
 import { undoData, moveData } from "/src/view/plugins/move-music-score"
 import { HANDLE_WORK_ADD } from "/src/page-instrument/custom-plugins/work-index";
 import { speedBeatTo, unitImgs } from "/src/helpers/beatConfig"
-import { fixInstrumentNameCode } from "/src/constant/instruments";
 import { musicalInstrumentCodeInfo, instruments, fixInstrumentNameCode } from "/src/constant/instruments";
 
 const query: any = getQuery();

+ 1 - 1
src/store.ts

@@ -28,7 +28,7 @@ type IUser = {
 };
 type IStatus = "init" | "login" | "logout" | "error";
 type IPlatformType = "STUDENT" | "TEACHER" | "WEB" | "";
-type IPlatformApi = "/api-student" | "/api-teacher" | "/api-web" | "/api-backend" | "/edu-app" | "/cbs-app";
+type IPlatformApi = "/api-student" | "/api-teacher" | "/api-web" | "/api-backend" | "/edu-app" | "/cbs-app" | "/api-admin";
 type IProxy = "" | "/gym" | "/colexiu" | "/orchestra" | "/instrument";
 
 export interface IStoreData {

+ 9 - 0
src/utils/baseApi.ts

@@ -38,4 +38,13 @@ export const creatMusicSheetImg = (data: any) => {
 export const getInstrumentCode = () => {
   const url = `/music/sheet/instrumentCode`;
   return request.get(url);
+};
+
+/** 上传错误信息 */
+export const sysExceptionLogSave = (data: any): Promise<any> => {
+  return request.post('/sysExceptionLog/save', {
+    requestType: 'json',
+    isExceptionLog: true, // js异常收集,需要使用api-auth
+    data
+  });
 };

+ 1 - 1
src/utils/request.ts

@@ -19,7 +19,7 @@ request.interceptors.request.use(
 	(url, options) => {
 		// console.log(9999,storeData.proxy,storeData.platformApi,options)
 		// 内容平台的前缀为cbs-app
-		const platformApi = options.isContentCenter ? '/cbs-app' : storeData.platformApi
+		const platformApi = options.isContentCenter ? '/cbs-app' : options.isExceptionLog ? '/api-auth' : storeData.platformApi
 		const _prefix = storeData.proxy + platformApi;
 		/** 
 		 * 只有后台才去设置

+ 1 - 1
vite.config.ts

@@ -52,7 +52,7 @@ export default defineConfig({
     // https: true,
     proxy: {
       "^/instrument/.*": {
-        target: "https://dev.colexiu.com",
+        target: "https://test.colexiu.com",
         changeOrigin: true,
         rewrite: (path) => path.replace(/^\/instrument/, ""),
       },