• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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