From 456919ed1f40faa36b6ce56399e8f99c720581db Mon Sep 17 00:00:00 2001 From: zhangzepeng Date: Wed, 10 Jul 2024 18:00:13 +0800 Subject: [PATCH] =?UTF-8?q?=E2=80=98ide-src-trace=E5=85=B6=E4=BD=99?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=90=88=E5=85=A5=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangzepeng --- ide/src/trace/SpApplication.ts | 531 ++++++++++++------ ide/src/trace/SpApplicationPublicFunc.ts | 16 +- ide/src/trace/database/ConfigWorker.ts | 2 +- ide/src/trace/database/Convert.ts | 7 +- ide/src/trace/database/Procedure.ts | 2 +- ide/src/trace/database/SqlLite.ts | 130 +++-- ide/src/trace/database/SqlLiteWorker.ts | 21 +- ide/src/trace/database/StateBusyTimeWorker.ts | 9 +- ide/src/trace/database/TempSql.ts | 21 +- ide/src/trace/database/TraceWorker.ts | 92 ++- .../database/data-trafic/ArkTsReceiver.ts | 4 +- .../database/data-trafic/ClockDataSender.ts | 11 +- .../database/data-trafic/CpuDataReceiver.ts | 4 +- .../database/data-trafic/CpuDataSender.ts | 16 +- .../data-trafic/EnergySysEventReceiver.ts | 7 +- .../database/data-trafic/IrqDataReceiver.ts | 19 +- .../database/data-trafic/IrqDataSender.ts | 9 +- .../data-trafic/NativeMemoryDataReceiver.ts | 358 ++++++------ .../data-trafic/NativeMemoryDataSender.ts | 2 +- .../database/data-trafic/SliceReceiver.ts | 101 +++- .../trace/database/data-trafic/SliceSender.ts | 16 +- .../data-trafic/cpu/CpuFreqDataSender.ts | 9 +- .../cpu/CpuFreqLimitDataReceiver.ts | 3 +- .../data-trafic/cpu/CpuFreqLimitDataSender.ts | 9 +- .../data-trafic/cpu/CpuStateSender.ts | 9 +- .../database/data-trafic/dmaFenceReceiver.ts | 106 ++++ .../database/data-trafic/dmaFenceSender.ts | 66 +++ .../hiperf/HiperfCallChartReceiver.ts | 78 ++- .../data-trafic/process/FuncDataReceiver.ts | 9 +- .../data-trafic/process/FuncDataSender.ts | 14 +- .../data-trafic/process/ProcessDataSender.ts | 12 +- .../ProcessDeliverInputEventDataReceiver.ts | 5 +- .../process/ProcessMemDataReceiver.ts | 4 +- .../process/ProcessMemDataSender.ts | 2 +- .../ProcessTouchEventDispatchDataReceiver.ts | 107 ++++ .../ProcessTouchEventDispatchDataSender.ts | 74 +++ .../data-trafic/process/ThreadDataReceiver.ts | 2 +- .../data-trafic/process/ThreadDataSender.ts | 12 +- .../data-trafic/utils/AllMemoryCache.ts | 4 +- .../database/data-trafic/utils/DataFilter.ts | 19 +- .../data-trafic/utils/ExecProtoForWorker.ts | 4 + .../database/data-trafic/utils/QueryEnum.ts | 2 + .../ProcedureLogicWorkerCommon.ts | 152 ++++- .../ProcedureLogicWorkerFileSystem.ts | 11 +- .../ProcedureLogicWorkerJsCpuProfiler.ts | 15 +- .../ProcedureLogicWorkerNativeNemory.ts | 111 ++-- .../logic-worker/ProcedureLogicWorkerPerf.ts | 102 +++- ide/src/trace/database/sql/Clock.sql.ts | 58 +- ide/src/trace/database/sql/Cpu.sql.ts | 196 +++---- ide/src/trace/database/sql/Func.sql.ts | 291 +++++----- ide/src/trace/database/sql/Irq.sql.ts | 50 +- ide/src/trace/database/sql/Janks.sql.ts | 14 +- ide/src/trace/database/sql/Memory.sql.ts | 74 ++- .../trace/database/sql/ProcessThread.sql.ts | 344 +++++++++--- ide/src/trace/database/sql/Sdk.sql.ts | 33 +- ide/src/trace/database/sql/Smaps.sql.ts | 70 ++- ide/src/trace/database/sql/SqlLite.sql.ts | 372 +++++++----- ide/src/trace/database/sql/dmaFence.sql.ts | 91 +++ .../database/ui-worker/ProcedureWorker.ts | 6 + .../ui-worker/ProcedureWorkerAllAppStartup.ts | 9 +- .../ui-worker/ProcedureWorkerAllStates.ts | 144 +++++ .../ui-worker/ProcedureWorkerAppStartup.ts | 9 +- .../ui-worker/ProcedureWorkerBpftrace.ts | 14 +- .../ui-worker/ProcedureWorkerClock.ts | 12 +- .../ui-worker/ProcedureWorkerCommon.ts | 133 ++++- .../ui-worker/ProcedureWorkerCpuAbility.ts | 3 +- .../ui-worker/ProcedureWorkerCpuProfiler.ts | 9 +- .../ui-worker/ProcedureWorkerDiskIoAbility.ts | 3 +- .../ui-worker/ProcedureWorkerDmaFence.ts | 153 +++++ .../ui-worker/ProcedureWorkerEnergyPower.ts | 15 +- .../ProcedureWorkerFrameAnimation.ts | 8 +- .../ui-worker/ProcedureWorkerFrameDynamic.ts | 12 +- .../ui-worker/ProcedureWorkerFrameSpacing.ts | 12 +- .../database/ui-worker/ProcedureWorkerFreq.ts | 10 +- .../ui-worker/ProcedureWorkerFreqExtend.ts | 191 ++++--- .../database/ui-worker/ProcedureWorkerFunc.ts | 95 ++-- .../ui-worker/ProcedureWorkerGpuCounter.ts | 256 +++++++++ .../database/ui-worker/ProcedureWorkerHeap.ts | 9 +- .../ui-worker/ProcedureWorkerHeapSnapshot.ts | 7 +- .../ui-worker/ProcedureWorkerHitchTime.ts | 26 +- .../database/ui-worker/ProcedureWorkerIrq.ts | 12 +- .../database/ui-worker/ProcedureWorkerJank.ts | 23 +- .../database/ui-worker/ProcedureWorkerLTPO.ts | 28 +- .../ui-worker/ProcedureWorkerMemoryAbility.ts | 3 +- .../ProcedureWorkerPerfCallchains.ts | 2 +- .../ui-worker/ProcedureWorkerPerfTool.ts | 19 +- .../ui-worker/ProcedureWorkerProcess.ts | 6 +- .../ui-worker/ProcedureWorkerSnapshot.ts | 4 +- .../ui-worker/ProcedureWorkerSoInit.ts | 9 +- .../ui-worker/ProcedureWorkerThread.ts | 96 +--- .../ui-worker/cpu/ProcedureWorkerCPU.ts | 54 +- .../cpu/ProcedureWorkerCpuFreqLimits.ts | 10 +- .../ui-worker/cpu/ProcedureWorkerCpuState.ts | 14 +- .../ui-worker/procedureWorkerBinder.ts | 94 +++- 94 files changed, 3731 insertions(+), 1691 deletions(-) create mode 100644 ide/src/trace/database/data-trafic/dmaFenceReceiver.ts create mode 100644 ide/src/trace/database/data-trafic/dmaFenceSender.ts create mode 100644 ide/src/trace/database/data-trafic/process/ProcessTouchEventDispatchDataReceiver.ts create mode 100644 ide/src/trace/database/data-trafic/process/ProcessTouchEventDispatchDataSender.ts create mode 100644 ide/src/trace/database/sql/dmaFence.sql.ts create mode 100644 ide/src/trace/database/ui-worker/ProcedureWorkerAllStates.ts create mode 100644 ide/src/trace/database/ui-worker/ProcedureWorkerDmaFence.ts create mode 100644 ide/src/trace/database/ui-worker/ProcedureWorkerGpuCounter.ts diff --git a/ide/src/trace/SpApplication.ts b/ide/src/trace/SpApplication.ts index 646861cb..301f0b17 100644 --- a/ide/src/trace/SpApplication.ts +++ b/ide/src/trace/SpApplication.ts @@ -22,14 +22,20 @@ import './component/SpHelp'; import { SpQuerySQL } from './component/SpQuerySQL'; import './component/SpQuerySQL'; import { SpSystemTrace } from './component/SpSystemTrace'; -import { LitMainMenu, MenuItem } from '../base-ui/menu/LitMainMenu'; +import { LitMainMenu, MenuGroup, MenuItem } from '../base-ui/menu/LitMainMenu'; import { SpInfoAndStats } from './component/SpInfoAndStas'; import '../base-ui/progress-bar/LitProgressBar'; import { LitProgressBar } from '../base-ui/progress-bar/LitProgressBar'; import { SpRecordTrace } from './component/SpRecordTrace'; import { SpWelcomePage } from './component/SpWelcomePage'; import { LitSearch } from './component/trace/search/Search'; -import { DbPool, threadPool } from './database/SqlLite'; +import { + getThreadPoolTraceBuffer, + getThreadPoolTraceBufferCacheKey, + setThreadPoolTraceBuffer, + threadPool, + threadPool2, +} from './database/SqlLite'; import './component/trace/search/Search'; import './component/SpWelcomePage'; import './component/SpSystemTrace'; @@ -66,6 +72,7 @@ import { indexedDataToBufferData, postLog, readTraceFileBuffer, + TraceMode, } from './SpApplicationPublicFunc'; import { queryExistFtrace } from './database/sql/SqlLite.sql'; import '../base-ui/chart/scatter/LitChartScatter'; @@ -155,6 +162,7 @@ export class SpApplication extends BaseElement { private pageTimStamp: number = 0; private currentPageNum: number = 1; private currentDataTime: string[] = []; + static traceType: String = ''; static get observedAttributes(): Array { return ['server', 'sqlite', 'wasm', 'dark', 'vs', 'query-sql', 'subsection']; @@ -303,8 +311,7 @@ export class SpApplication extends BaseElement { this.initCustomColorHandler(); this.initImportConfigEvent(); this.initSlideMenuEvents(); - // @ts-ignore - this.mainMenu!.menus = [this.initNavigationMenu(), this.initSupportMenus()]; + this.resetMenus(); this.initGlobalEvents(); this.initDocumentListener(); this.initElementsEnd(); @@ -357,9 +364,10 @@ export class SpApplication extends BaseElement { } private openLongTraceFile(ev: unknown, isRecordTrace: boolean = false): void { + const self = this; this.returnOriginalUrl(); this.wasm = true; - this.openFileInit(); + this.openFileInit(true); // @ts-ignore let detail = ev.detail; let initRes = this.longTraceFileInit(isRecordTrace, detail); @@ -378,9 +386,9 @@ export class SpApplication extends BaseElement { ): Promise => { const promises = Array.from(files).map((file) => { if (normalNames.indexOf(file.name.toLowerCase()) >= 0) { - return this.longTraceFileRead(file, true, traceTypePage, readSize, timStamp, allFileSize); + return self.longTraceFileRead(file, true, traceTypePage, readSize, timStamp, allFileSize); } else if (specialNames.indexOf(file.name.toLowerCase()) >= 0) { - return this.longTraceFileRead(file, false, traceTypePage, readSize, timStamp, allFileSize); + return self.longTraceFileRead(file, false, traceTypePage, readSize, timStamp, allFileSize); } else { return; } @@ -404,6 +412,7 @@ export class SpApplication extends BaseElement { allFileSize: number ): Promise => { info('reading long trace file ', file.name); + const self = this; return new Promise((resolve, reject) => { let fr = new FileReader(); let message = { fileType: '', startIndex: 0, endIndex: 0, size: 0 }; @@ -413,12 +422,12 @@ export class SpApplication extends BaseElement { let offset = 0; let sliceLen = 0; let index = 1; - fr.onload = (): void => { + fr.onload = function (): void { let data = fr.result as ArrayBuffer; LongTraceDBUtils.getInstance() .addLongTableData(data, fileType, timStamp, pageNumber, index, offset, sliceLen) .then(() => { - this.longTraceFileReadMessagePush(index, isNormalType, pageNumber, offset, sliceLen, fileType, data); + self.longTraceFileReadMessagePush(index, isNormalType, pageNumber, offset, sliceLen, fileType, data); offset += sliceLen; if (offset < file.size) { index++; @@ -426,11 +435,11 @@ export class SpApplication extends BaseElement { continueReading(); }); }; - const continueReading = (): void => { + function continueReading(): void { if (offset >= file.size) { message.endIndex = index; message.size = file.size; - this.longTraceFileReadMessageHandler(pageNumber, message); + self.longTraceFileReadMessageHandler(pageNumber, message); resolve(true); return; } @@ -442,9 +451,9 @@ export class SpApplication extends BaseElement { let slice = file.slice(offset, offset + sliceLen); readSize += slice.size; let percentValue = ((readSize * 100) / allFileSize).toFixed(2); - this.litSearch!.setPercent('Read in file: ', Number(percentValue)); + self.litSearch!.setPercent('Read in file: ', Number(percentValue)); fr.readAsArrayBuffer(slice); - }; + } continueReading(); fr.onerror = (): void => reject(false); info('read over long trace file ', file.name); @@ -505,8 +514,7 @@ export class SpApplication extends BaseElement { let traceTypePage: Array = []; let allFileSize = 0; let normalTraceNames: Array = []; - let specialTraceNames: Array = []; - //@ts-ignore + let specialTraceNames: Array = []; //@ts-ignore for (let index = 0; index < detail.length; index++) { //@ts-ignore let file = detail[index]; @@ -578,6 +586,7 @@ export class SpApplication extends BaseElement { private openTraceFile(ev: unknown, isClickHandle?: boolean): void { this.returnOriginalUrl(); this.removeAttribute('custom-color'); + this.chartFilter!.setAttribute('hidden', ''); this.customColor!.setAttribute('hidden', ''); this.longTracePage!.style.display = 'none'; this.litSearch!.style.marginLeft = '0px'; @@ -599,6 +608,7 @@ export class SpApplication extends BaseElement { reader.readAsText(typeHeader); reader.onloadend = (event): void => { let headerStr: string = `${reader?.result}`; + SpApplication.traceType = headerStr; if (headerStr.indexOf('SQLite') === 0) { info('Parse trace headerStr sql mode'); this.wasm = false; @@ -613,7 +623,25 @@ export class SpApplication extends BaseElement { }; } + private openDistributedTraceFile(ev: InputEvent): void { + this.openFileInit(true); + this.importConfigDiv!.style.display = 'none'; + this.closeKeyPath!.style.display = 'none'; + // @ts-ignore + let fileList = ev.detail as FileList; + if (fileList.length === 2) { + this.handleDistributedWasmMode(fileList.item(0)!, fileList.item(1)!); + } else { + this.progressEL!.loading = false; + this.litSearch!.setPercent('load distributed trace error', -1); + this.resetMenus(); + this.freshMenuDisable(false); + this.headerDiv!.style.pointerEvents = 'auto'; + } + } + private openLineFileHandler(urlParams: URLSearchParams): void { + Utils.currentTraceMode = TraceMode.NORMAL; this.openFileInit(); this.openMenu(false); let downloadLineFile = urlParams.get('local') ? false : true; @@ -689,7 +717,7 @@ export class SpApplication extends BaseElement { this.litSearch!.setPercent('This File is not supported!', -1); this.progressEL!.loading = false; this.freshMenuDisable(false); - this.mainMenu!.menus!.splice(1, 1); + this.mainMenu!.menus!.splice(2, 1); this.mainMenu!.menus = this.mainMenu!.menus!; this.spSystemTrace!.reset(null); } @@ -776,56 +804,77 @@ export class SpApplication extends BaseElement { ); } - private initNavigationMenu(): unknown { - return { - collapsed: false, - title: 'Navigation', - second: false, - icon: '', - describe: 'Open or record a new trace', - children: [ - { - title: 'Open trace file', - icon: 'folder', - fileChoose: true, - fileHandler: (ev: InputEvent): void => { - this.openTraceFile(ev.detail); + private initNavigationMenu(multiTrace: boolean): MenuGroup[] { + return [ + { + collapsed: false, + title: 'Navigation', + second: false, + icon: 'caret-down', + describe: 'Open or record a new trace', + children: [ + { + title: 'Open trace file', + icon: 'folder', + fileChoose: true, + fileHandler: (ev: InputEvent): void => { + Utils.currentTraceMode = TraceMode.NORMAL; + this.openTraceFile(ev.detail); + }, }, - clickHandler: (hand: unknown): void => { - this.openTraceFile(hand, true); + { + title: 'Record new trace', + icon: 'copyhovered', + clickHandler: (item: MenuItem): void => this.clickHandleByRecordNewTrace(), }, - }, - { - title: 'Open long trace file', - icon: 'folder', - fileChoose: true, - fileHandler: (ev: InputEvent): void => { - this.openLongTraceFile(ev); + { + title: 'Record template', + icon: 'copyhovered', + clickHandler: (item: MenuItem): void => this.clickHandleByRecordTemplate(), }, - clickHandler: (hand: InputEvent): void => { - this.openLongTraceFile(hand, true); + ], + }, + { + collapsed: !multiTrace, + title: 'Open multiple trace', + second: false, + icon: 'caret-down', + describe: 'long trace or distributed trace', + children: [ + { + title: 'Open long trace', + icon: 'folder', + fileChoose: true, + clickHandler: (ev: InputEvent): void => { + Utils.currentTraceMode = TraceMode.LONG_TRACE; + this.openLongTraceFile(ev, true); + }, + fileHandler: (ev: InputEvent): void => { + Utils.currentTraceMode = TraceMode.LONG_TRACE; + this.openLongTraceFile(ev); + }, }, - }, - { - title: 'Record new trace', - icon: 'copyhovered', - clickHandler: (item: MenuItem): void => this.clickHandleByRecordNewTrace(), - }, - { - title: 'Record template', - icon: 'copyhovered', - clickHandler: (item: MenuItem): void => this.clickHandleByRecordTemplate(), - }, - ], - }; + { + title: 'Open distributed trace', + icon: 'folder', + multi: true, + fileChoose: true, + fileHandler: (ev: InputEvent): void => { + Utils.currentTraceMode = TraceMode.DISTRIBUTED; + this.openDistributedTraceFile(ev); + }, + }, + ], + }, + ]; } - private initSupportMenus(): unknown { + private initSupportMenus(): MenuGroup { return { collapsed: false, title: 'Support', second: false, - icon: '', + icon: 'caret-down', describe: 'Support', children: [ { @@ -842,17 +891,7 @@ export class SpApplication extends BaseElement { title: 'Keyboard Shortcuts', icon: 'smart-help', clickHandler: (item: MenuItem): void => this.clickHandleByKeyboardShortcuts(), - }, - { - title: 'Third File', - icon: 'file-fill', - fileModel: this.wasm ? 'wasm' : 'db', - clickHandler: (item: MenuItem): void => { - this.returnOriginalUrl(); - this.search = false; - this.showContent(this.spThirdParty!); - }, - }, + } ], }; } @@ -925,6 +964,7 @@ export class SpApplication extends BaseElement { } private handleSqliteMode(ev: unknown, showFileName: string, fileSize: number, fileName: string): void { + const self = this; let fileSizeStr = (fileSize / 1048576).toFixed(1); postLog(fileName, fileSizeStr); document.title = `${showFileName} (${fileSizeStr}M)`; @@ -932,45 +972,85 @@ export class SpApplication extends BaseElement { threadPool.init('sqlite').then((res) => { let reader = new FileReader(); reader.readAsArrayBuffer(ev as Blob); - reader.onloadend = (ev): void => { + reader.onloadend = function (ev): void { SpApplication.loadingProgress = 0; SpApplication.progressStep = 3; - this.spSystemTrace!.loadDatabaseArrayBuffer( - reader.result as ArrayBuffer, + self.spSystemTrace!.loadDatabaseArrayBuffer( + this.result as ArrayBuffer, '', (command: string, _: number) => { - this.setProgress(command); + self.setProgress(command); }, + false, () => { - this.mainMenu!.menus!.splice(1, this.mainMenu!.menus!.length > 2 ? 1 : 0, { + self.mainMenu!.menus!.splice(2, self.mainMenu!.menus!.length > 2 ? 1 : 0, { collapsed: false, title: 'Current Trace', second: false, - icon: '', + icon: 'caret-down', describe: 'Actions on the current trace', - children: this.getTraceOptionMenus(showFileName, fileSizeStr, fileName, true), + children: self.getTraceOptionMenus(showFileName, fileSizeStr, fileName, true, false), }); - this.mainMenu!.menus!.splice(2, 1, { + self.mainMenu!.menus!.splice(3, 1, { collapsed: false, title: 'Support', second: false, - icon: '', + icon: 'caret-down', describe: 'Support', - children: this.getTraceSupportMenus(), + children: self.getTraceSupportMenus(), }); - this.litSearch!.setPercent('', 101); - this.chartFilter!.setAttribute('mode', ''); - this.progressEL!.loading = false; - this.freshMenuDisable(false); - this.spInfoAndStats!.initInfoAndStatsData(); - this.cutTraceFile!.style.display = 'none'; - this.headerDiv!.style.pointerEvents = 'auto'; + self.litSearch!.setPercent('', 101); + self.chartFilter!.setAttribute('mode', ''); + self.progressEL!.loading = false; + self.freshMenuDisable(false); + self.spInfoAndStats!.initInfoAndStatsData(); + self.cutTraceFile!.style.display = 'none'; + self.headerDiv!.style.pointerEvents = 'auto'; } ); }; }); } + private handleDistributedWasmMode(file1: File, file2: File): void { + this.litSearch!.setPercent('', 1); + document.title = 'Distributed Trace'; + let completeHandler = async (res: unknown): Promise => { + await this.traceLoadCompleteHandler(res, '', '', file1.name, true, file2.name); + }; + let typeHeader = file1.slice(0, 6); + let reader: FileReader | null = new FileReader(); + reader.readAsText(typeHeader); + reader.onloadend = (event): void => { + let headerStr: string = `${reader?.result}`; + let traceType = 'wasm'; + if (headerStr.indexOf('SQLite') === 0) { + traceType = 'sqlite'; + } + Promise.all([threadPool.init(traceType), threadPool2.init(traceType)]).then(() => { + let wasmUrl = `https://${window.location.host.split(':')[0]}:${window.location.port}/application/wasm.json`; + Promise.all([file1.arrayBuffer(), file2.arrayBuffer()]).then((bufArr) => { + this.litSearch!.setPercent('ArrayBuffer loaded ', 2); + SpApplication.loadingProgress = 0; + SpApplication.progressStep = 2; + let buf1 = this.markPositionHandler(bufArr[0]); + let buf2 = this.markPositionHandler(bufArr[1]); + info('initData start Parse Data'); + this.spSystemTrace!.loadDatabaseArrayBuffer( + buf1, + wasmUrl, + (command: string, _: number) => this.setProgress(command), + true, + completeHandler, + buf2, + file1.name, + file2.name + ); + }); + }); + }; + } + private handleWasmMode(ev: unknown, showFileName: string, fileSize: number, fileName: string): void { this.litSearch!.setPercent('', 1); if (fileName.endsWith('.json')) { @@ -983,22 +1063,31 @@ export class SpApplication extends BaseElement { this.chartFilter!.setAttribute('mode', ''); this.progressEL!.loading = false; }); + } else if (fileName.endsWith('.csv')) { + this.progressEL!.loading = true; + this.spSystemTrace!.loadGpuCounter(ev as File).then(() => { + this.showContent(this.spSystemTrace!); + this.litSearch!.setPercent('', 101); + this.freshMenuDisable(false); + this.chartFilter!.setAttribute('mode', ''); + this.progressEL!.loading = false; + }); } else { let fileSizeStr = (fileSize / 1048576).toFixed(1); postLog(fileName, fileSizeStr); document.title = `${showFileName} (${fileSizeStr}M)`; info('Parse trace using wasm mode '); let completeHandler = async (res: unknown): Promise => { - await this.traceLoadCompleteHandler(res, fileSizeStr, showFileName, fileName); + await this.traceLoadCompleteHandler(res, fileSizeStr, showFileName, fileName, false); if (this.markJson) { window.publish(window.SmartEvent.UI.ImportRecord, this.markJson); } }; threadPool.init('wasm').then((res) => { - let reader: FileReader | null = new FileReader(); + let reader: FileReader = new FileReader(); //@ts-ignore reader.readAsArrayBuffer(ev); - reader.onloadend = (ev): void => { + reader.onloadend = (ev): void =>{ info('read file onloadend'); this.litSearch!.setPercent('ArrayBuffer loaded ', 2); let wasmUrl = `https://${window.location.host.split(':')[0]}:${window.location.port}/application/wasm.json`; @@ -1010,6 +1099,7 @@ export class SpApplication extends BaseElement { data, wasmUrl, (command: string, _: number) => this.setProgress(command), + false, completeHandler ); }; @@ -1037,36 +1127,57 @@ export class SpApplication extends BaseElement { res: unknown, fileSize: string, showFileName: string, - fileName: string + fileName: string, + isDistributed: boolean, + fileName2?: string ): Promise { - let existFtrace = await queryExistFtrace(); - let isAllowTrace = true; - if (DbPool.sharedBuffer) { - let traceHeadData = new Uint8Array(DbPool.sharedBuffer!.slice(0, 10)); - let enc = new TextDecoder(); - let headerStr = enc.decode(traceHeadData); - let rowTraceStr = Array.from(new Uint8Array(DbPool.sharedBuffer!.slice(0, 2))) - .map((byte) => byte.toString(16).padStart(2, '0')) - .join(''); - if (headerStr.indexOf('OHOSPROF') !== 0 && rowTraceStr.indexOf('49df') !== 0) { - isAllowTrace = false; + let index = 3; + if (isDistributed) { + //分布式,隐藏 裁剪 trace 和 导出带记录的收藏trace 功能 + this.cutTraceFile!.style.display = 'none'; + this.exportRecord!.style.display = 'none'; + this.litSearch?.setAttribute('distributed', ''); + setThreadPoolTraceBuffer('1', null); + setThreadPoolTraceBuffer('2', null); + } else { + let existFtrace = await queryExistFtrace(); + let isAllowTrace = true; + let sharedBuffer = getThreadPoolTraceBuffer('1'); + if (sharedBuffer) { + let traceHeadData = new Uint8Array(sharedBuffer!.slice(0, 10)); + let enc = new TextDecoder(); + let headerStr = enc.decode(traceHeadData); + let rowTraceStr = Array.from(new Uint8Array(sharedBuffer!.slice(0, 2))) + .map((byte) => byte.toString(16).padStart(2, '0')) + .join(''); + if (headerStr.indexOf('OHOSPROF') !== 0 && rowTraceStr.indexOf('49df') !== 0) { + isAllowTrace = false; + } + this.cutTraceFile!.style.display = 'block'; + this.exportRecord!.style.display = 'block'; + setThreadPoolTraceBuffer('1', null); + } + if (existFtrace.length > 0 && isAllowTrace) { + this.showConvertTraceMenu(fileName); + index = 4; } - this.cutTraceFile!.style.display = 'block'; - DbPool.sharedBuffer = null; - } - let index = 2; - if (existFtrace.length > 0 && isAllowTrace) { - this.showConvertTraceMenu(fileName); - index = 3; } + this.loadTraceCompleteMenuHandler(index); //@ts-ignore if (res.status) { info('loadDatabaseArrayBuffer success'); - //@ts-ignore - window.traceFileName = fileName; - this.showCurrentTraceMenu(fileSize, showFileName, fileName); - this.importConfigDiv!.style.display = Utils.SCHED_SLICE_MAP.size > 0 ? 'block' : 'none'; + if (isDistributed) { + Utils.distributedTrace.push(fileName || 'trace1'); + Utils.distributedTrace.push(fileName2 || 'trace2'); + this.litSearch!.setTraceSelectOptions(); + } else { + (window as any).traceFileName = fileName; + } + this.showCurrentTraceMenu(fileSize, showFileName, fileName, isDistributed); + if (!isDistributed) { + this.importConfigDiv!.style.display = Utils.getInstance().getSchedSliceMap().size > 0 ? 'block' : 'none'; + } this.showContent(this.spSystemTrace!); this.litSearch!.setPercent('', 101); this.chartFilter!.setAttribute('mode', ''); @@ -1075,34 +1186,37 @@ export class SpApplication extends BaseElement { info('loadDatabaseArrayBuffer failed'); //@ts-ignore this.litSearch!.setPercent(res.msg || 'This File is not supported!', -1); + this.resetMenus(); this.freshMenuDisable(false); - this.mainMenu!.menus!.splice(1, 1); - this.mainMenu!.menus = this.mainMenu!.menus!; } this.progressEL!.loading = false; this.headerDiv!.style.pointerEvents = 'auto'; this.spInfoAndStats!.initInfoAndStatsData(); } + private resetMenus(multiTrace: boolean = false): void { + this.mainMenu!.menus = [...this.initNavigationMenu(multiTrace), this.initSupportMenus()]; + } + private showConvertTraceMenu(fileName: string): void { - this.mainMenu!.menus!.splice(2, 1, { + this.mainMenu!.menus!.splice(3, 1, { collapsed: false, title: 'Convert trace', second: false, - icon: '', + icon: 'caret-down', describe: 'Convert to other formats', children: this.pushConvertTrace(fileName), }); } - private showCurrentTraceMenu(fileSize: string, showFileName: string, fileName: string): void { - this.mainMenu!.menus!.splice(1, this.mainMenu!.menus!.length > 2 ? 1 : 0, { + private showCurrentTraceMenu(fileSize: string, showFileName: string, fileName: string, isDistributed: boolean): void { + this.mainMenu!.menus!.splice(2, this.mainMenu!.menus!.length > 2 ? 1 : 0, { collapsed: false, title: 'Current Trace', second: false, - icon: '', + icon: 'caret-down', describe: 'Actions on the current trace', - children: this.getTraceOptionMenus(showFileName, fileSize, fileName, false), + children: this.getTraceOptionMenus(showFileName, fileSize, fileName, false, isDistributed), }); } @@ -1111,7 +1225,7 @@ export class SpApplication extends BaseElement { collapsed: false, title: 'Support', second: false, - icon: '', + icon: 'caret-down', describe: 'Support', children: [ { @@ -1129,16 +1243,6 @@ export class SpApplication extends BaseElement { icon: 'smart-help', clickHandler: (item: MenuItem): void => this.clickHandleByKeyboardShortcuts(), }, - { - title: 'Third File', - icon: 'file-fill', - fileModel: this.wasm ? 'wasm' : 'db', - clickHandler: (item: MenuItem): void => { - this.returnOriginalUrl(); - this.search = false; - this.showContent(this.spThirdParty!); - }, - }, ], }); } @@ -1206,12 +1310,41 @@ export class SpApplication extends BaseElement { const file = new File([fileBlob], this.traceFileName); this.handleWasmMode(file, file.name, file.size, file.name); } + this.refreshLongTraceButtonStyle(); + this.longTracePage!.style.display = 'flex'; }); }); } + private refreshLongTraceButtonStyle(): void { + let pageListDiv = this.shadowRoot?.querySelector('.page-number-list') as HTMLDivElement; + let pageNodeList = pageListDiv.querySelectorAll('div'); + let pageInput = this.shadowRoot?.querySelector('.page-input'); + let previewButton: HTMLDivElement | null | undefined = + this.shadowRoot?.querySelector('#preview-button'); + let nextButton: HTMLDivElement | null | undefined = this.shadowRoot?.querySelector('#next-button'); + let pageConfirmEl = this.shadowRoot?.querySelector('.confirm-button'); + pageInput!.style.pointerEvents = 'auto'; + pageNodeList.forEach((pageItem) => { + pageItem.style.pointerEvents = 'auto'; + }); + nextButton!.style.pointerEvents = 'auto'; + nextButton!.style.opacity = '1'; + previewButton!.style.pointerEvents = 'auto'; + previewButton!.style.opacity = '1'; + if (this.currentPageNum === 1) { + previewButton!.style.pointerEvents = 'none'; + previewButton!.style.opacity = '0.7'; + } else if (this.currentPageNum === this.longTraceHeadMessageList.length) { + nextButton!.style.pointerEvents = 'none'; + nextButton!.style.opacity = '0.7'; + } + // + pageConfirmEl!.style.pointerEvents = 'auto'; + } + private getTraceFileByPage(pageNumber: number): void { - this.openFileInit(); + this.openFileInit(true); if (this.validateGetTraceFileByPage()) { let indexedDbPageNum = pageNumber - 1; let maxTraceFileLength = 400 * 1024 * 1024; @@ -1392,10 +1525,15 @@ export class SpApplication extends BaseElement { }); } - private openFileInit(): void { + private openFileInit(multiTrace: boolean = false): void { clearTraceFileCache(); this.litSearch!.clear(); + Utils.currentSelectTrace = undefined; this.markJson = undefined; + if(!multiTrace){ + this.longTracePage!.style.display = 'none'; + } + this.litSearch?.removeAttribute('distributed'); SpStatisticsHttpUtil.addOrdinaryVisitAction({ event: 'open_trace', action: 'open_trace', @@ -1403,22 +1541,17 @@ export class SpApplication extends BaseElement { info('openTraceFile'); this.headerDiv!.style.pointerEvents = 'none'; this.spSystemTrace!.clearPointPair(); - this.spSystemTrace!.reset((command: string, percent: number) => { + this.spSystemTrace!.reset((command: string, percent: number): void => { this.setProgress(command); }); + threadPool2.reset().then(); window.publish(window.SmartEvent.UI.MouseEventEnable, { mouseEnable: false, }); window.clearTraceRowComplete(); - this.freshMenuDisable(true); SpSchedulingAnalysis.resetCpu(); - if (this.mainMenu!.menus!.length > 3) { - this.mainMenu!.menus!.splice(1, 2); - this.mainMenu!.menus = this.mainMenu!.menus!; - } else if (this.mainMenu!.menus!.length > 2) { - this.mainMenu!.menus!.splice(1, 1); - this.mainMenu!.menus = this.mainMenu!.menus!; - } + this.resetMenus(multiTrace); + this.freshMenuDisable(true); this.showContent(this.spSystemTrace!); this.progressEL!.loading = true; } @@ -1458,7 +1591,7 @@ export class SpApplication extends BaseElement { }); } - private pushConvertTrace(fileName: string): Array { + private pushConvertTrace(fileName: string): Array { let instance = this; let menus = []; menus.push({ @@ -1511,18 +1644,25 @@ export class SpApplication extends BaseElement { fileSize: string, fileName: string, isServer: boolean, + isDistributed: boolean, dbName?: string - ): Array { + ): Array { let menus = [ { - title: `${showFileName} (${fileSize}M)`, + title: isDistributed ? 'Distributed Trace' : `${showFileName} (${fileSize}M)`, icon: 'file-fill', clickHandler: (): void => { this.search = true; this.showContent(this.spSystemTrace!); }, }, - { + ]; + if ( + !isDistributed && + Utils.getInstance().getWinCpuCount() > 0 && + FlagsConfig.getFlagsConfigEnableStatus('SchedulingAnalysis') + ) { + menus.push({ title: 'Scheduling Analysis', icon: 'piechart-circle-fil', clickHandler: (): void => { @@ -1533,10 +1673,12 @@ export class SpApplication extends BaseElement { this.showContent(this.spSchedulingAnalysis!); this.spSchedulingAnalysis!.init(); }, - }, - { + }); + } + if (!isDistributed) { + menus.push({ title: 'Download File', - icon: 'download', + icon: 'download', // @ts-ignore fileModel: this.wasm ? 'wasm' : 'db', clickHandler: (): void => { this.download(this.mainMenu!, fileName, isServer, dbName); @@ -1545,10 +1687,10 @@ export class SpApplication extends BaseElement { action: 'download', }); }, - }, - { + }); + menus.push({ title: 'Download Database', - icon: 'download', + icon: 'download', // @ts-ignore fileModel: this.wasm ? 'wasm' : 'db', clickHandler: (): void => { this.downloadDB(this.mainMenu!, fileName); @@ -1557,17 +1699,13 @@ export class SpApplication extends BaseElement { action: 'download', }); }, - }, - ]; - this.getTraceQuerySqlMenus(menus); - //@ts-ignore - if (window.cpuCount === 0 || !FlagsConfig.getFlagsConfigEnableStatus('SchedulingAnalysis')) { - menus.splice(1, 1); + }); + this.getTraceQuerySqlMenus(menus); } return menus; } - private getTraceSupportMenus(): Array { + private getTraceSupportMenus(): Array { return [ { title: 'Help Documents', @@ -1793,6 +1931,13 @@ export class SpApplication extends BaseElement { private initSearchChangeEvents(): void { let timer: NodeJS.Timeout; this.litSearch!.valueChangeHandler = (value: string): void => { + Utils.currentSelectTrace = this.litSearch?.getSearchTraceId(); + this.litSearch!.currenSearchValue = value; + if(value.length > 0) { + this.progressEL!.loading = true; + } else { + this.progressEL!.loading = false; + } this.litSearch!.list = []; if (timer) { clearTimeout(timer); @@ -1801,12 +1946,16 @@ export class SpApplication extends BaseElement { this.litSearch!.isClearValue = false; if (value.length > 0) { let list = []; - this.progressEL!.loading = true; this.spSystemTrace!.searchCPU(value).then((cpus) => { list = cpus; - this.spSystemTrace!.searchFunction(list, value).then((mixedResults) => { + let asyncFuncArr = this.spSystemTrace!.seachAsyncFunc(value); + this.spSystemTrace!.searchFunction(list, asyncFuncArr, value).then((mixedResults) => { if (this.litSearch!.searchValue !== '') { - this.litSearch!.list = this.spSystemTrace!.searchSdk(mixedResults, value); + if (!Utils.isDistributedMode()) { + this.litSearch!.list = this.spSystemTrace!.searchSdk(mixedResults, value); + } else { + this.litSearch!.list = mixedResults; + } this.litSearch!.index = this.spSystemTrace!.showStruct(false, -1, this.litSearch!.list); } this.progressEL!.loading = false; @@ -1826,7 +1975,9 @@ export class SpApplication extends BaseElement { }; } private initSearchEvents(): void { - this.litSearch!.addEventListener('focus', () => { + this.litSearch!.addEventListener('focus', (e): void => { + Utils.currentSelectTrace = this.litSearch!.getSearchTraceId(); + this.spSystemTrace!.searchTargetTraceHandler(); window.publish(window.SmartEvent.UI.KeyboardEnable, { enable: false, }); @@ -1837,15 +1988,24 @@ export class SpApplication extends BaseElement { }); }); this.litSearch!.addEventListener('previous-data', (ev) => { + if(this.progressEL!.loading) { + return; + } this.litSearch!.index = this.spSystemTrace!.showStruct(true, this.litSearch!.index, this.litSearch!.list); this.litSearch!.blur(); }); this.litSearch!.addEventListener('next-data', (ev) => { + if(this.progressEL!.loading) { + return; + } this.litSearch!.index = this.spSystemTrace!.showStruct(false, this.litSearch!.index, this.litSearch!.list); this.litSearch!.blur(); }); // 翻页事件 this.litSearch!.addEventListener('retarget-data', (ev) => { + if(this.progressEL!.loading) { + return; + } this.litSearch!.index = this.spSystemTrace!.showStruct( true, //@ts-ignore @@ -1856,14 +2016,32 @@ export class SpApplication extends BaseElement { ); this.litSearch!.blur(); }); + this.litSearch!.addEventListener('trace-change', (e): void => { + this.spSystemTrace?.clickEmptyArea(); + this.spSystemTrace!.searchTargetTraceHandler(); + }); this.initSearchChangeEvents(); } private initSystemTraceEvents(): void { this.spSystemTrace?.addEventListener('trace-previous-data', (ev) => { + if(this.progressEL!.loading) { + return; + } + if(this.litSearch!.isSearchInputFocus) { + this.litSearch!.isSearchInputFocus = !this.litSearch!.isSearchInputFocus; + return; + } this.litSearch!.index = this.spSystemTrace!.showStruct(true, this.litSearch!.index, this.litSearch!.list); }); this.spSystemTrace?.addEventListener('trace-next-data', (ev) => { + if(this.progressEL!.loading) { + return; + } + if(this.litSearch!.isSearchInputFocus) { + this.litSearch!.isSearchInputFocus = !this.litSearch!.isSearchInputFocus; + return; + } this.litSearch!.index = this.spSystemTrace!.showStruct(false, this.litSearch!.index, this.litSearch!.list); }); } @@ -1900,6 +2078,8 @@ export class SpApplication extends BaseElement { enable: false, }); this.filterConfig!.style.visibility = 'hidden'; + this.removeAttribute('chart_filter'); + this.chartFilter!.setAttribute('hidden', ''); } this.childComponent!.forEach((node) => { if (this.hasAttribute('chart_filter')) { @@ -1919,14 +2099,11 @@ export class SpApplication extends BaseElement { } private validateFileCacheLost(): void { - caches.has(DbPool.fileCacheKey).then((exist) => { + caches.has(getThreadPoolTraceBufferCacheKey('1')).then((exist): void => { if (!exist) { this.mainMenu!.menus?.forEach((mg) => { - // @ts-ignore - mg.children.forEach((mi: unknown) => { - //@ts-ignore + mg.children.forEach((mi: MenuItem) => { if (mi.title === 'Download File') { - //@ts-ignore mi.disabled = true; } }); @@ -1948,6 +2125,7 @@ export class SpApplication extends BaseElement { if (pageInput) { pageInput.textContent = currentPageNum.toString(); pageInput.value = currentPageNum.toString(); + pageInput.style.pointerEvents = 'none'; } let pageText: string[] = []; if (maxPageNumber > 7) { @@ -1959,17 +2137,6 @@ export class SpApplication extends BaseElement { } } this.pageNodeHandler(pageListDiv, pageText, currentPageNum); - nextButton.style.pointerEvents = 'auto'; - nextButton.style.opacity = '1'; - previewButton.style.pointerEvents = 'auto'; - previewButton.style.opacity = '1'; - if (currentPageNum === 1) { - previewButton.style.pointerEvents = 'none'; - previewButton.style.opacity = '0.7'; - } else if (currentPageNum === maxPageNumber) { - nextButton.style.pointerEvents = 'none'; - nextButton.style.opacity = '0.7'; - } } private pageNodeHandler(pageListDiv: HTMLDivElement, pageText: Array, currentPageNum: number): void { @@ -2229,8 +2396,9 @@ export class SpApplication extends BaseElement { a.download = fileName; a.click(); this.itemIconLoading(mainMenu, 'Current Trace', 'Download Database', true); - let timer = setInterval(() => { - this.itemIconLoading(mainMenu, 'Current Trace', 'Download Database', false); + const self = this; + let timer = setInterval(function () { + self.itemIconLoading(mainMenu, 'Current Trace', 'Download Database', false); clearInterval(timer); }, 4000); }, @@ -2256,9 +2424,10 @@ export class SpApplication extends BaseElement { a.download = fileName; a.click(); window.URL.revokeObjectURL(a.href); + const self = this; this.itemIconLoading(mainMenu, 'Current Trace', 'Download File', true); - let timer = setInterval(() => { - this.itemIconLoading(mainMenu, 'Current Trace', 'Download File', false); + let timer = setInterval(function () { + self.itemIconLoading(mainMenu, 'Current Trace', 'Download File', false); clearInterval(timer); }, 4000); } diff --git a/ide/src/trace/SpApplicationPublicFunc.ts b/ide/src/trace/SpApplicationPublicFunc.ts index 1786b46b..0053c939 100644 --- a/ide/src/trace/SpApplicationPublicFunc.ts +++ b/ide/src/trace/SpApplicationPublicFunc.ts @@ -13,7 +13,13 @@ * limitations under the License. */ -import { DbPool } from './database/SqlLite'; +import { getThreadPoolTraceBufferCacheKey } from './database/SqlLite'; + +export enum TraceMode{ + NORMAL, + LONG_TRACE, + DISTRIBUTED, +} export const applicationHtml: string = `