From cd94db8350d7dcb0eadcd489e1998ab94f611451 Mon Sep 17 00:00:00 2001 From: zhangzengfei <zhangzengfei@iotlink.com> Date: 星期五, 21 五月 2021 14:04:57 +0800 Subject: [PATCH] 完善系统监控 --- src/pages/systemMonitor/index/App.vue | 715 +++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 593 insertions(+), 122 deletions(-) diff --git a/src/pages/systemMonitor/index/App.vue b/src/pages/systemMonitor/index/App.vue index 73ad2c8..88437be 100644 --- a/src/pages/systemMonitor/index/App.vue +++ b/src/pages/systemMonitor/index/App.vue @@ -3,66 +3,193 @@ <el-tabs id="systemMonitor" v-model="activeName"> <el-tab-pane label="鍗曞厓" name="proc"> <div class="form-title"> - <b>绠楁硶鍗曞厓</b>(姝e湪杩涜5涓畻娉曞崟鍏�) + <b>绠楁硶鍗曞厓</b> + (姝e湪杩涜{{algoProcessData.length}}涓畻娉曞崟鍏�) + <el-table :data="algoProcessData" style="width: 100%"> + <el-table-column prop="desc" label="鍚嶇О" width="180"></el-table-column> + <el-table-column label="CPU" width="180"> + <template slot-scope="scope"> + <span>{{ scope.row.cpu.toFixed(2)}} %</span> + </template> + </el-table-column> + <el-table-column label="鍐呭瓨"> + <template slot-scope="scope"> + <span>{{ scope.row.mem.toFixed(2)}} %</span> + </template> + </el-table-column> + <el-table-column prop="disk" label="纭洏"></el-table-column> + <el-table-column label="绠楀姏"> + <template slot-scope="scope"> + <span>{{ scope.row.gpu}} M</span> + </template> + </el-table-column> + <el-table-column prop="net" label="缃戠粶"></el-table-column> + </el-table> </div> - <el-divider></el-divider> - <div class="form-title"> - <b>搴旂敤鍗曞厓</b>(姝e湪杩涜5涓簲鐢ㄥ崟鍏�) + <div class="form-title" style="margin-top:20px"> + <b>搴旂敤鍗曞厓</b> + (姝e湪杩涜{{appProcessData.length}}涓簲鐢ㄥ崟鍏�) + <el-table :data="appProcessData" style="width: 100%"> + <el-table-column prop="desc" label="鍚嶇О" width="180"></el-table-column> + <el-table-column prop="cpu" label="CPU" width="180"></el-table-column> + <el-table-column prop="mem" label="鍐呭瓨"></el-table-column> + <el-table-column prop="disk" label="纭洏"></el-table-column> + <el-table-column prop="gpu" label="绠楀姏"></el-table-column> + <el-table-column prop="net" label="缃戠粶"></el-table-column> + </el-table> </div> - <el-divider></el-divider> </el-tab-pane> <el-tab-pane label="鎬ц兘" name="top"> <div class="column-left" ref="left"> <div class="resize-bar"> - <div class="ax_default"> - <div class="ax_default_pic"></div> - <div>CPU</div> - <div>100%</div> + <div + :class="['ax_default', activeChartItem == 'cpu' ?'selected': '']" + @click="setActiveChartItem('cpu')" + > + <div class="ax_default_pic color-cpu"></div> + <div class="ax_default_text">CPU</div> + <div class="ax_default_subtext">{{cpuUsedPercent}}%</div> </div> - <div class="ax_default"> - <div class="ax_default_pic"></div> - <div>鍐呭瓨</div> - <div>100%</div> + <div + :class="['ax_default', activeChartItem == 'mem' ?'selected': '']" + @click="setActiveChartItem('mem')" + > + <div class="ax_default_pic color-mem"></div> + <div class="ax_default_text">鍐呭瓨</div> + <div class="ax_default_subtext">{{memUsedPercent}}%</div> </div> - <div class="ax_default"> - <div class="ax_default_pic"></div> - <div>纾佺洏</div> - <div>100%</div> + <div + :class="['ax_default', activeChartItem == 'gpu' ?'selected': '']" + @click="setActiveChartItem('gpu')" + > + <div class="ax_default_pic color-gpu"></div> + <div class="ax_default_text">绠楀姏</div> + <div class="ax_default_subtext">{{gpuUsedPercent}}%</div> </div> - <div class="ax_default"> - <div class="ax_default_pic"></div> - <div>绠楀姏</div> - <div>100%</div> + <div + :class="['ax_default', activeChartItem == 'net' ?'selected': '']" + @click="setActiveChartItem('net')" + > + <div class="ax_default_pic color-net"></div> + <div class="ax_default_text">缃戠粶</div> + <div class="ax_default_subtext">{{netSend | byteConver}} / {{netRecive | byteConver}}</div> </div> - <div class="ax_default"> - <div class="ax_default_pic"></div> - <div>缃戠粶</div> - <div>100%</div> + <div + v-for="(v, k) in disks" + :key="k" + :class="['ax_default', activeChartItem == ('disk|' + k) ?'selected': '']" + @click="setActiveChartItem('disk|'+k)" + > + <div class="ax_default_pic color-disk"></div> + <div class="ax_default_text">纾佺洏 {{k}}</div> + <div class="ax_default_subtext">{{v.info.total | byteConver}}</div> </div> </div> <div class="resize-line"></div> </div> + <div class="column-right"> + <div class="max-val">{{yAxisMaxVal}}</div> <div ref="graphs" class="graphs-chart"></div> + + <div v-show="activeChartItem == 'cpu'"> + <div class="ax_default_label"> + <b>鍗犵敤鐜�</b> + <p>{{cpuUsedPercent}}%</p> + </div> + <div class="ax_default_label"> + <b>涓婚</b> + <p>{{cpuMaxRate}}Ghz</p> + </div> + <div class="ax_default_label"> + <b>鎻掓Ы</b> + <p>{{cpuCount}}</p> + </div> + <div class="ax_default_label"> + <b>鍐呮牳</b> + <p>{{cpuCore}}</p> + </div> + </div> + + <div v-show="activeChartItem == 'mem'"> + <div class="ax_default_label"> + <b>浣跨敤涓�</b> + <p>{{memUsed}}G</p> + </div> + <div class="ax_default_label"> + <b>宸茬紦瀛�</b> + <p>{{memCache}}G</p> + </div> + <div class="ax_default_label"> + <b>鍙敤</b> + <p>{{memFree}}G</p> + </div> + </div> + + <div v-show="activeChartItem == 'net'"> + <div class="ax_default_label"> + <b>鎺ユ敹</b> + <p>{{netRecive |byteConver}}</p> + </div> + <div class="ax_default_label"> + <b>鍙戦��</b> + <p>{{netSend |byteConver}}</p> + </div> + <div class="ax_default_label"> + <b>IP鍦板潃</b> + <p>{{ipAddr}}</p> + </div> + <div class="ax_default_label" style="margin-left: 19px;"> + <b>MAC鍦板潃</b> + <p>{{macAddr}}</p> + </div> + </div> + + <div v-show="isDisk"> + <div class="ax_default_label"> + <b>瀹归噺</b> + <p>{{activeDisk.total |byteConver}}</p> + </div> + <div class="ax_default_label"> + <b>宸茬敤</b> + <p>{{activeDisk.used |byteConver}}</p> + </div> + <div class="ax_default_label"> + <b>鍙敤</b> + <p>{{activeDisk.free |byteConver}}</p> + </div> + <div class="ax_default_label"> + <b>璇诲彇閫熷害</b> + <p>{{ioRead | byteConver}}</p> + </div> + <div class="ax_default_label"> + <b>鍐欏叆閫熷害</b> + <p>{{ioWrite | byteConver}}</p> + </div> + </div> </div> </el-tab-pane> <el-tab-pane label="鏈嶅姟" name="service"> - <el-table height="93%" :data="services" border :cell-style="cellStyle"> - <el-table-column label="鍚嶇О" align="center" show-overflow-tooltip> + <el-table :data="vasystemServicesData"> + <el-table-column label="鍚嶇О" show-overflow-tooltip> <template slot-scope="scope"> <span>{{ scope.row.name}}</span> </template> </el-table-column> - <el-table-column label="鐘舵��" prop="status" align="center" width="130px"></el-table-column> - <el-table-column label="鎻忚堪" prop="text" align="center"></el-table-column> + <el-table-column label="鐘舵��" prop="status"> + <template slot-scope="scope"> + <span>{{ scope.row.pid == 0 ? "鏈惎鍔�" : "宸插惎鍔�" }}</span> + </template> + </el-table-column> + <el-table-column label="鎻忚堪" prop="desc"></el-table-column> </el-table> </el-tab-pane> </el-tabs> @@ -71,66 +198,15 @@ <script> import echarts from "echarts"; -import { showSystemStates } from "../api/api" +import { showSystemStates, showService, showProcesses } from "../api/api" export default { components: { - - - }, - data() { - return { - activeName: "proc", - eChartsObj: {}, - eChartsBaseOpt: { - animation: false, - xAxis: { - type: "category", - boundaryGap: false, - data: Array.from({ length: 100 }, () => 0), - axisLabel: { - show: false - }, - axisTick: { - show: false - } - }, - yAxis: { - type: 'value', - axisLabel: { - show: false - }, - axisTick: { - show: false - } - }, - series: [ - { - type: 'line', - symbol: 'none', - data: Array.from({ length: 100 }, () => 0), - // smooth: true, - areaStyle: {} - } - ] - }, - services: [ - { - name: "绯荤粺閰嶇疆鏈嶅姟", - status: "宸插惎鍔�", - text: "瀹炵幇绯荤粺鐨勯�氱敤鍔熻兘閰嶇疆" - - } - ] - }; - }, - mounted() { - this.initChart(); - if (!this.isShow('vindicate:device')) { - this.activeName = "dbvdc" - } }, computed: { + isDisk() { + return this.activeChartItem.indexOf("disk") == 0 + }, isAdmin() { if ( sessionStorage.getItem('userInfo') && @@ -144,7 +220,248 @@ return false; } }, + filters: { + byteConver(limit) { + var size = ""; + if (limit < 1024) { //濡傛灉灏忎簬0.1KB杞寲鎴怋 + size = limit + "B"; + } else if (limit < 1024 * 1024) {//濡傛灉灏忎簬0.1MB杞寲鎴怟B + size = (limit / 1024).toFixed(2) + "KB"; + } else if (limit < 1024 * 1024 * 1024) { //濡傛灉灏忎簬0.1GB杞寲鎴怣B + size = (limit / (1024 * 1024)).toFixed(2) + "MB"; + } else if (limit < 1024 * 1024 * 1024 * 1024) { //鍏朵粬杞寲鎴怗B + size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB"; + } else { + size = (limit / (1024 * 1024 * 1024 * 1024)).toFixed(2) + "TB"; + } + + var sizestr = size + ""; + var len = sizestr.indexOf("\."); + var dec = sizestr.substr(len + 1, 2); + if (dec == "00") {//褰撳皬鏁扮偣鍚庝负00鏃� 鍘绘帀灏忔暟閮ㄥ垎 + return sizestr.substring(0, len) + sizestr.substr(len + 3, 2); + } + + return sizestr; + } + }, + data() { + return { + activeName: "proc", + activeChartItem: "cpu", + yAxisMaxVal: "100%", + algoProcessData: [], + appProcessData: [], + vasystemServicesData: [], + eChartsObj: {}, + eChartsBaseOpt: { + title: { + top: 10, + }, + animation: false, + grid: { + show: true, + left: '1%', + right: '4%', + bottom: '3%', + containLabel: true, + borderWidth: 2, + borderColor: '#000' + }, + xAxis: { + type: "category", + boundaryGap: false, + data: Array.from({ length: 60 }, () => 0), + // show: false, + axisLabel: { + show: false + }, + axisTick: { + show: false + }, + splitLine: { + show: true, + interval: 5, + lineStyle: { + width: 1, + type: 'solid' + } + } + }, + yAxis: { + type: 'value', + // show: false, + axisLine: { + show: false + }, + axisLabel: { + show: false + }, + axisTick: { + show: false + } + }, + series: [ + { + type: 'line', + symbol: 'none', + data: Array.from({ length: 60 }, () => 0), + // smooth: true, + itemStyle: {}, + areaStyle: {} + } + ] + }, + cpuUtilizations: Array.from({ length: 60 }, () => 0), + memUtilizations: Array.from({ length: 60 }, () => 0), + gpuUtilizations: Array.from({ length: 60 }, () => 0), + diskIOWriteCount: Array.from({ length: 60 }, () => 0), + diskIOReadCount: Array.from({ length: 60 }, () => 0), + netReciveCount: Array.from({ length: 60 }, () => 0), + netSendCount: Array.from({ length: 60 }, () => 0), + cpuModel: "", + cpuUsedPercent: 0, + cpuMaxRate: 0, + cpuCount: 0, + cpuCore: 0, + memTotal: 0, + memUsed: 0, + memFree: 0, + memCache: 0, + memUsedPercent: 0, + netSend: 0, + netRecive: 0, + ipAddr: "", + macAddr: "", + gpuUsedPercent: 0, + disks: {}, + activeDisk: {}, + ioRead: 0, + ioWrite: 0 + }; + }, + mounted() { + this.dataCollection(); + this.initChart(); + }, methods: { + // 寰幆閲囬泦鎵�鏈夋暟鎹� + dataCollection() { + this.serviceCollect(); + this.procCollect(); + setTimeout(() => { + this.dataCollection(); + }, 5000) + }, + serviceCollect() { + showService().then(rsp => { + if (rsp && rsp.success) { + rsp.data.sort(function (obj1, obj2) { + var val1 = obj1.name + var val2 = obj2.name + if (val1 < val2) { + return -1 + } else if (val1 > val2) { + return 1 + } else { + return 0 + } + }) + this.vasystemServicesData = rsp.data; + } + }).catch(() => { }) + + }, + procCollect() { + showProcesses().then(rsp => { + if (rsp && rsp.success) { + if (rsp.data.algos) + this.algoProcessData = rsp.data.algos; + + if (rsp.data.apps) + this.appProcessData = rsp.data.apps; + } + + }).catch(() => { }) + }, + getSystemState() { + showSystemStates().then(rsp => { + if (rsp && rsp.success) { + // 澶勭悊cpu + this.cpuUtilizations = this.cpuUtilizations.slice(1); + this.cpuUtilizations.push(rsp.data.cpu.toFixed(2)); + this.cpuUsedPercent = this.cpuUtilizations[59]; + if (rsp.data.cpu_info) { + this.cpuMaxRate = (rsp.data.cpu_info[0].mhz / 1024).toFixed(2); + this.cpuModel = rsp.data.cpu_info[0].modelName; + this.cpuCore = Number(rsp.data.cpu_info[rsp.data.cpu_info.length - 1].coreId) + 1; + this.cpuCount = (rsp.data.cpu_info.length / this.cpuCore).toFixed(0); + } + + // 鍐呭瓨 + this.memUtilizations = this.memUtilizations.slice(1); + this.memUtilizations.push(rsp.data.mem.usedPercent.toFixed(2)); + this.memTotal = (rsp.data.mem.total / 1024 / 1024 / 1000).toFixed(0); + this.memUsed = (rsp.data.mem.used / 1024 / 1024 / 1000).toFixed(2); + this.memFree = (rsp.data.mem.free / 1024 / 1024 / 1000).toFixed(2); + this.memCache = ((rsp.data.mem.cached + rsp.data.mem.buffers) / 1024 / 1024 / 1000).toFixed(2); + this.memUsedPercent = rsp.data.mem.usedPercent.toFixed(2); + + // 绠楀姏 + this.gpuUtilizations = this.gpuUtilizations.slice(1); + this.gpuUtilizations.push(rsp.data.gpu.toFixed(2)); + this.gpuUsedPercent = this.gpuUtilizations[59]; + + // 缃戠粶 + this.netReciveCount = this.netReciveCount.slice(1); + this.netReciveCount.push(rsp.data.net.bytesRecv); + this.netSendCount = this.netSendCount.slice(1); + this.netSendCount.push(rsp.data.net.bytesSent); + + this.netRecive = this.netReciveCount[59]; + this.netSend = this.netSendCount[59]; + this.macAddr = rsp.data.net.mac; + if (rsp.data.net.addr.length) { + this.ipAddr = rsp.data.net.addr[0].addr; + } + + // 纾佺洏 + rsp.data.disk.sort(function (obj1, obj2) { + var val1 = obj1.name; + var val2 = obj2.name; + if (val1 < val2) { + return -1; + } else if (val1 > val2) { + return 1; + } else { + return 0; + } + }) + + rsp.data.disk.forEach(d => { + if (d.name in this.disks) { + this.disks[d.name].readBytes = this.disks[d.name].readBytes.slice(1); + this.disks[d.name].readBytes.push(d.readBytes); + this.disks[d.name].writeBytes = this.disks[d.name].writeBytes.slice(1); + this.disks[d.name].writeBytes.push(d.writeBytes); + } else { + this.disks[d.name] = {}; + this.disks[d.name]["info"] = d.info; + this.disks[d.name]["readBytes"] = Array.from({ length: 60 }, () => 0); + this.disks[d.name]["writeBytes"] = Array.from({ length: 60 }, () => 0); + } + }); + + // this.disks = rsp.data.disk; + } + + + this.setChartData(); + setTimeout(() => { + this.getSystemState(); + }, 1000) + }) + }, isShow(authority) { if (this.isAdmin) { return true @@ -162,20 +479,105 @@ this.$moment(array[1]).format("YYYY-MM-DD") ]; }, + setActiveChartItem(item) { + this.activeChartItem = item; + this.eChartsObj.clear(); + this.setChartData(); + }, initChart() { this.eChartsObj = echarts.init(this.$refs.graphs); - this.eChartsObj.setOption(this.eChartsBaseOpt); - this.cpuMonitor() + this.getSystemState(); }, - cpuMonitor() { - let rate = Math.floor(Math.random() * 100); - let data = this.eChartsBaseOpt.series[0].data.slice(1); - data.push(rate) - this.eChartsBaseOpt.series[0].data = data; - this.eChartsObj.setOption(this.eChartsBaseOpt); - setTimeout(() => { - this.cpuMonitor() - }, 1000) + setChartData() { + let option = JSON.parse(JSON.stringify(this.eChartsBaseOpt)); + switch (this.activeChartItem) { + case 'cpu': + this.yAxisMaxVal = this.cpuModel; + option.title.text = "CPU"; + option.title.subtext = "%鍗犵敤鐜�"; + option.yAxis.max = 100; + option.yAxis.min = 0; + option.grid.borderColor = "#8aadd0"; + option.series[0].itemStyle.color = "#8aadd0"; + option.series[0].areaStyle.color = "#a8d4ff"; + option.series[0].data = this.cpuUtilizations; + + break; + case 'mem': + this.yAxisMaxVal = this.memTotal + "G"; + option.title.text = "鍐呭瓨"; + option.title.subtext = "鍐呭瓨浣跨敤閲�"; + option.yAxis.max = 100; + option.yAxis.min = 0; + option.grid.borderColor = "#ff9900"; + option.series[0].itemStyle.color = "#ff9900"; + option.series[0].areaStyle.color = "#f7bb88"; + option.series[0].data = this.memUtilizations; + break; + case 'gpu': + this.yAxisMaxVal = "100%"; + option.title.text = "绠楀姏"; + option.title.subtext = "%浣跨敤鐜�"; + option.yAxis.max = 100; + option.yAxis.min = 0; + option.grid.borderColor = "#bc84d8"; + option.series[0].itemStyle.color = "#bc84d8"; + option.series[0].areaStyle.color = "#de9dff"; + option.series[0].data = this.gpuUtilizations; + break; + case 'net': + this.yAxisMaxVal = ""; + option.title.text = "缃戠粶"; + option.title.subtext = "缃戠粶璐熻浇"; + option.grid.borderColor = "#4696da"; + option.series[0].itemStyle.color = "#ffa16a"; + option.series[0].areaStyle.color = "#d68658"; + option.series[0].data = this.netReciveCount; + option.series.push({ + type: 'line', + symbol: 'none', + data: this.netSendCount, + // smooth: true, + itemStyle: { + color: "#4696da" + }, + areaStyle: { + color: "#4eacfd" + } + }) + break; + default: + if (this.activeChartItem.indexOf("disk|") == 0) { + let dev = this.activeChartItem.split("|")[1]; + + this.yAxisMaxVal = ""; + option.title.text = "纾佺洏"; + option.title.subtext = "纾佺洏浼犺緭閫熺巼"; + option.grid.borderColor = "#33cc66"; + option.series[0].itemStyle.color = "#4696da"; + option.series[0].areaStyle.color = "#4eacfd"; + option.series[0].data = this.disks[dev].readBytes; + option.series.push({ + type: 'line', + symbol: 'none', + data: this.disks[dev].writeBytes, + // smooth: true, + itemStyle: { + color: "#33ff66" + }, + areaStyle: { + color: "#33cc66" + } + }) + + this.activeDisk = this.disks[dev].info; + this.ioRead = this.disks[dev].readBytes[59]; + this.ioWrite = this.disks[dev].writeBytes[59]; + } + break; + } + + this.eChartsObj.setOption(option); } } @@ -195,24 +597,35 @@ } .graphs-chart { - height: 380px; - width: 450px; + height: 500px; + width: 900px; + margin-left: 15px; // border: 1px solid rgb(69, 69, 172); } + .column-left { background-color: #fff; position: relative; float: left; } + .column-right { //overflow: hidden; overflow-y: hidden; overflow-x: auto; } - .resize-bar { - width: 200px; - height: 400px; + + .max-val { + position: absolute; + right: 4%; + top: 8%; } + + .resize-bar { + width: 238px; + height: 610px; + } + /* 鎷栨嫿绾� */ .resize-line { position: absolute; @@ -225,41 +638,98 @@ } .ax_default { - font-family: "Arial Normal", "Arial"; - font-weight: 400; - font-style: normal; - font-size: 13px; - text-align: center; - line-height: normal; - width: 200px; - height: 50px; - font-size: 16px; + width: 207px; + height: 45px; + padding: 10px; + font-size: 15px; + margin: 5px; cursor: pointer; - margin-bottom: 15px; + } + + .selected { + background: inherit; + background-color: #cde8ff; + border: none; + border-radius: 8px; } .ax_default_pic { position: absolute; border-width: 0px; - width: 65px; + width: 66px; height: 45px; - background: inherit; - background-color: rgba(255, 255, 255, 0); box-sizing: border-box; - border-width: 1px; - border-style: solid; - border-color: rgba(255, 153, 0, 1); - border-radius: 0px; - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; + border: 1px solid rgba(255, 153, 0, 1); + background-repeat: no-repeat; + background-position: bottom; } + .color-cpu { + border-color: #8aadd0; + background-image: url("/images/systemMonitor/cpu.png"); + } + + .color-mem { + border-color: #ff9900; + background-image: url("/images/systemMonitor/mem.png"); + } + + .color-gpu { + border-color: #bc84d8; + background-image: url("/images/systemMonitor/gpu.png"); + } + + .color-net { + border-color: #4696da; + background-image: url("/images/systemMonitor/net.png"); + } + + .color-disk { + border-color: #33cc66; + background-image: url("/images/systemMonitor/disk.png"); + } + + .ax_default_text { + position: relative; + text-align: left; + margin-left: 72px; + } + + .ax_default_subtext { + font-size: 13px; + margin-left: 72px; + line-height: 35px; + color: #4e4d4d; + text-align: left; + } + + .ax_default_label { + width: 120px; + font-size: 15px; + display: inline-block; + float: left; + + b { + font-family: "鎬濇簮榛戜綋"; + font-weight: 400; + font-style: normal; + color: #a1a1a1; + } + + p { + margin-top: 5px; + } + } + .ax_label_flex { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + } .s-system-monitor-breadcrumb { height: 5%; box-sizing: border-box; border: 1px solid #e4e7ed; - box-shadow: #e4e7ed 0px 0px 9px inset; box-shadow: #e4e7ed 0px 0px 9px inset; border-radius: 5px; } @@ -296,12 +766,13 @@ } } } + .el-tabs__content { height: calc(100% - 64px); width: calc(100% - 20px); box-sizing: border-box; overflow-y: auto; - padding: 10px 40px !important; + padding: 10px 10px !important; .el-tab-pane { width: 100%; .s-title { -- Gitblit v1.8.0