1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { BaseElement, element } from '../../../../../base-ui/BaseElement'; 17import { LitTable } from '../../../../../base-ui/table/lit-table'; 18import { SelectionParam } from '../../../../bean/BoxSelection'; 19import { Utils } from '../../base/Utils'; 20import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; 21import {getTabPaneFilesystemStatistics} from "../../../../database/sql/SqlLite.sql"; 22 23@element('tabpane-file-statistics') 24export class TabPaneFileStatistics extends BaseElement { 25 private fileStatisticsTbl: LitTable | null | undefined; 26 private selectionParam: SelectionParam | null | undefined; 27 private fileStatisticsProgressEL: LitProgressBar | null | undefined; 28 private fileStatisticsLoadingPage: any; 29 private fileStatisticsLoadingList: number[] = []; 30 private fileStatisticsSource: Array<any> = []; 31 private typeList: Array<string> = ['OPEN', 'CLOSE', 'READ', 'WRITE']; 32 private fileStatisticsSortKey: string = ''; 33 private fileStatisticsSortType: number = 0; 34 35 set data(fileStatisticsSelection: SelectionParam | any) { 36 if (fileStatisticsSelection == this.selectionParam) { 37 return; 38 } 39 this.fileStatisticsProgressEL!.loading = true; 40 this.fileStatisticsLoadingPage.style.visibility = 'visible'; 41 this.selectionParam = fileStatisticsSelection; 42 // @ts-ignore 43 this.fileStatisticsTbl!.shadowRoot!.querySelector('.table').style.height = 44 this.parentElement!.clientHeight - 25 + 'px'; 45 this.queryDataByDB(fileStatisticsSelection); 46 } 47 48 initElements(): void { 49 this.fileStatisticsProgressEL = this.shadowRoot!.querySelector<LitProgressBar>('.file-statistics-progress'); 50 this.fileStatisticsLoadingPage = this.shadowRoot!.querySelector('.file-statistics-loading'); 51 this.fileStatisticsTbl = this.shadowRoot!.querySelector<LitTable>('#tb-file-statistics'); 52 this.fileStatisticsTbl!.addEventListener('column-click', (evt) => { 53 // @ts-ignore 54 this.fileStatisticsSortKey = evt.detail.key; 55 // @ts-ignore 56 this.fileStatisticsSortType = evt.detail.sort; 57 58 let newSource = JSON.parse(JSON.stringify(this.fileStatisticsSource)); 59 if (this.fileStatisticsSortType != 0 && newSource.length > 0) 60 this.sortTable(newSource[0], this.fileStatisticsSortKey); 61 this.fileStatisticsTbl!.recycleDataSource = newSource; 62 }); 63 } 64 65 connectedCallback() { 66 super.connectedCallback(); 67 new ResizeObserver((entries) => { 68 if (this.parentElement!.clientHeight != 0) { 69 // @ts-ignore 70 this.fileStatisticsTbl!.shadowRoot!.querySelector('.table').style.height = 71 this.parentElement!.clientHeight - 25 + 'px'; 72 this.fileStatisticsTbl!.reMeauseHeight(); 73 this.fileStatisticsLoadingPage.style.height = this.parentElement!.clientHeight - 24 + 'px'; 74 } 75 }).observe(this.parentElement!); 76 } 77 78 getInitData(item: any) { 79 return { 80 ...item, 81 title: item.name + '(' + item.pid + ')', 82 logicalWrites: Utils.getBinaryByteWithUnit(item.logicalWrites), 83 logicalReads: Utils.getBinaryByteWithUnit(item.logicalReads), 84 otherFile: Utils.getBinaryByteWithUnit(item.otherFile), 85 allDuration: Utils.getProbablyTime(item.allDuration), 86 minDuration: Utils.getProbablyTime(item.minDuration), 87 maxDuration: Utils.getProbablyTime(item.maxDuration), 88 avgDuration: Utils.getProbablyTime(item.avgDuration), 89 node: { ...item, children: [] }, 90 }; 91 } 92 93 queryDataByDB(val: SelectionParam | any): void { 94 this.fileStatisticsLoadingList.push(1); 95 this.fileStatisticsProgressEL!.loading = true; 96 this.fileStatisticsLoadingPage.style.visibility = 'visible'; 97 getTabPaneFilesystemStatistics( 98 val.leftNs + val.recordStartNs, 99 val.rightNs + val.recordStartNs, 100 val.fileSystemType 101 ).then((result) => { 102 this.fileStatisticsLoadingList.splice(0, 1); 103 if (this.fileStatisticsLoadingList.length == 0) { 104 this.fileStatisticsProgressEL!.loading = false; 105 this.fileStatisticsLoadingPage.style.visibility = 'hidden'; 106 } 107 let fileStatisticsFatherMap = new Map<any, any>(); 108 let fileStatisticsAllNode: any = { 109 title: 'All', 110 count: 0, 111 logicalReads: 0, 112 logicalWrites: 0, 113 otherFile: 0, 114 allDuration: 0, 115 minDuration: 0, 116 maxDuration: 0, 117 avgDuration: '', 118 children: [], 119 }; 120 this.handleResult(result, fileStatisticsFatherMap, fileStatisticsAllNode); 121 fileStatisticsFatherMap.forEach((item) => { 122 item.avgDuration = item.allDuration / item.count; 123 let node = this.getInitData(item); 124 if (item.type < 4) { 125 node.title = this.typeList[item.type]; 126 } else { 127 node.title = item.type; 128 } 129 fileStatisticsAllNode.children.push(node); 130 }); 131 fileStatisticsAllNode.avgDuration = fileStatisticsAllNode.allDuration / fileStatisticsAllNode.count; 132 fileStatisticsAllNode = this.getInitData(fileStatisticsAllNode); 133 fileStatisticsAllNode.title = 'All'; 134 this.fileStatisticsSource = result.length > 0 ? [fileStatisticsAllNode] : []; 135 let newSource = JSON.parse(JSON.stringify(this.fileStatisticsSource)); 136 if (this.fileStatisticsSortType != 0 && result.length > 0) 137 this.sortTable(newSource[0], this.fileStatisticsSortKey); 138 this.fileStatisticsTbl!.recycleDataSource = newSource; 139 }); 140 } 141 142 private handleResult(result: Array<any>, fileStatisticsFatherMap: Map<any, any>, fileStatisticsAllNode: any): void { 143 result.forEach((item, idx) => { 144 if (fileStatisticsFatherMap.has(item.type)) { 145 let fileStatisticsObj = fileStatisticsFatherMap.get(item.type); 146 fileStatisticsObj.count += item.count; 147 fileStatisticsObj.logicalReads += item.logicalReads; 148 fileStatisticsObj.logicalWrites += item.logicalWrites; 149 fileStatisticsObj.otherFile += item.otherFile; 150 fileStatisticsObj.allDuration += item.allDuration; 151 fileStatisticsObj.minDuration = 152 fileStatisticsObj.minDuration <= item.minDuration ? fileStatisticsObj.minDuration : item.minDuration; 153 fileStatisticsObj.maxDuration = 154 fileStatisticsObj.maxDuration >= item.maxDuration ? fileStatisticsObj.maxDuration : item.maxDuration; 155 fileStatisticsObj.children.push(this.getInitData(item)); 156 } else { 157 fileStatisticsFatherMap.set(item.type, { 158 type: item.type, 159 count: item.count, 160 logicalReads: item.logicalReads, 161 logicalWrites: item.logicalWrites, 162 otherFile: item.otherFile, 163 allDuration: item.allDuration, 164 minDuration: item.minDuration, 165 maxDuration: item.maxDuration, 166 children: [this.getInitData(item)], 167 }); 168 } 169 if (idx == 0) { 170 fileStatisticsAllNode.minDuration = item.minDuration; 171 } else { 172 fileStatisticsAllNode.minDuration = 173 fileStatisticsAllNode.minDuration <= item.minDuration 174 ? fileStatisticsAllNode.minDuration 175 : item.minDuration; 176 } 177 fileStatisticsAllNode.count += item.count; 178 fileStatisticsAllNode.logicalReads += item.logicalReads; 179 fileStatisticsAllNode.logicalWrites += item.logicalWrites; 180 fileStatisticsAllNode.otherFile += item.otherFile; 181 fileStatisticsAllNode.allDuration += item.allDuration; 182 fileStatisticsAllNode.maxDuration = 183 fileStatisticsAllNode.maxDuration >= item.maxDuration ? fileStatisticsAllNode.maxDuration : item.maxDuration; 184 }); 185 } 186 187 sortTable(fileStatisticsAllNode: any, key: string) { 188 fileStatisticsAllNode.children.sort((fileStatisticsA: any, fileStatisticsB: any) => { 189 if (this.fileStatisticsSortType == 1) { 190 return fileStatisticsA.node[key] - fileStatisticsB.node[key]; 191 } else if (this.fileStatisticsSortType == 2) { 192 return fileStatisticsB.node[key] - fileStatisticsA.node[key]; 193 } 194 }); 195 fileStatisticsAllNode.children.forEach((item: any) => { 196 item.children.sort((fileStatisticsA: any, fileStatisticsB: any) => { 197 if (this.fileStatisticsSortType == 1) { 198 return fileStatisticsA.node[key] - fileStatisticsB.node[key]; 199 } else if (this.fileStatisticsSortType == 2) { 200 return fileStatisticsB.node[key] - fileStatisticsA.node[key]; 201 } 202 }); 203 }); 204 } 205 206 initHtml(): string { 207 return ` 208 <style> 209 :host{ 210 display: flex; 211 flex-direction: column; 212 padding: 10px 10px; 213 } 214 .file-statistics-progress{ 215 bottom: 5px; 216 position: absolute; 217 height: 1px; 218 left: 0; 219 right: 0; 220 } 221 .file-statistics-loading{ 222 bottom: 0; 223 position: absolute; 224 left: 0; 225 right: 0; 226 width:100%; 227 background:transparent; 228 z-index: 999999; 229 } 230 </style> 231 <lit-table id="tb-file-statistics" style="height: auto" tree> 232 <lit-table-column class="fs-stat-column" width="20%" title="Syscall/Process" data-index="title" key="title" align="flex-start"retract> 233 </lit-table-column> 234 <lit-table-column class="fs-stat-column" width="1fr" title="Count" data-index="count" key="count" align="flex-start" order> 235 </lit-table-column> 236 <lit-table-column class="fs-stat-column" width="1fr" title="Logical Writes" data-index="logicalWrites" key="logicalWrites" align="flex-start" order> 237 </lit-table-column> 238 <lit-table-column class="fs-stat-column" width="1fr" title="Logical Reads" data-index="logicalReads" key="logicalReads" align="flex-start" order> 239 </lit-table-column> 240 <lit-table-column class="fs-stat-column" width="1fr" title="Other Filesystem Bytes" data-index="otherFile" key="otherFile" align="flex-start" order> 241 </lit-table-column> 242 <lit-table-column class="fs-stat-column" width="1fr" title="Duration" data-index="allDuration" key="allDuration" align="flex-start" order> 243 </lit-table-column> 244 <lit-table-column class="fs-stat-column" width="1fr" title="Min Duration" data-index="minDuration" key="minDuration" align="flex-start" order> 245 </lit-table-column> 246 <lit-table-column class="fs-stat-column" width="1fr" title="Avg Duration" data-index="avgDuration" key="avgDuration" align="flex-start" order> 247 </lit-table-column> 248 <lit-table-column class="fs-stat-column" width="1fr" title="Max Duration" data-index="maxDuration" key="maxDuration" align="flex-start" order> 249 </lit-table-column> 250 </lit-table> 251 <lit-progress-bar class="file-statistics-progress"></lit-progress-bar> 252 <div class="file-statistics-loading"></div> 253 `; 254 } 255} 256