DashBoard.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <template>
  2. <div>
  3. <a-row class="row-two">
  4. <a-col :lg="24" :sm="24">
  5. <a-card style="min-height: 400px" title="服务器状态">
  6. <a-row>
  7. <a-col :lg="12" :sm="24" class="chart">
  8. <a-statistic :value="cpu" style="margin: 0 50px 10px 0" title="CPU">
  9. <template v-slot:suffix>
  10. <span>%</span>
  11. </template>
  12. </a-statistic>
  13. <p>运行时间 {{ uptime }}</p>
  14. <p>系统负载 1min:{{ loadavg.Loadavg1 }} 5min:{{ loadavg.Loadavg5 }}
  15. 15min:{{ loadavg.Loadavg15 }}</p>
  16. <line-chart :chart-data="cpu_analytic" :options="cpu_analytic.options" :height="150"/>
  17. </a-col>
  18. <a-col :lg="6" :sm="8" :xs="12" class="chart_dashboard">
  19. <div>
  20. <a-tooltip
  21. :title="'已使用: '+ memory_used + ' 缓存: ' + memory_cached + ' 空闲:' + memory_free +
  22. ' 物理内存: ' + memory_total">
  23. <a-progress :percent="memory_pressure" strokeColor="rgb(135, 208, 104)" type="dashboard" />
  24. <p class="description">实际内存占用</p>
  25. </a-tooltip>
  26. </div>
  27. </a-col>
  28. <a-col :lg="6" :sm="8" :xs="12" class="chart_dashboard">
  29. <div>
  30. <a-tooltip
  31. :title="'已使用: '+ disk_used + ' / 总共: ' + disk_total">
  32. <a-progress :percent="disk_percentage" type="dashboard" />
  33. <p class="description">存储空间</p>
  34. </a-tooltip>
  35. </div>
  36. </a-col>
  37. </a-row>
  38. </a-card>
  39. </a-col>
  40. </a-row>
  41. </div>
  42. </template>
  43. <script>
  44. import LineChart from "@/components/Chart/LineChart"
  45. export default {
  46. name: "DashBoard",
  47. components: {
  48. LineChart
  49. },
  50. data() {
  51. return {
  52. websocket: null,
  53. loading: true,
  54. stat: {},
  55. memory_pressure: 0,
  56. memory_used: "",
  57. memory_cached: "",
  58. memory_free: "",
  59. memory_total: "",
  60. cpu_analytic: {
  61. datasets: [{
  62. label: 'cpu user',
  63. borderColor: '#36a3eb',
  64. backgroundColor: '#36a3eb',
  65. pointRadius: 0,
  66. data: [],
  67. }, {
  68. label: 'cpu total',
  69. borderColor: '#ff6385',
  70. backgroundColor: '#ff6385',
  71. pointRadius: 0,
  72. data: [],
  73. }],
  74. options: {
  75. responsive: true,
  76. maintainAspectRatio:false,
  77. responsiveAnimationDuration: 0, // 调整大小后的动画持续时间
  78. elements: {
  79. line: {
  80. tension: 0 // 禁用贝塞尔曲线
  81. }
  82. },
  83. scales: {
  84. yAxes: [{
  85. ticks: {
  86. max: 100,
  87. min: 0,
  88. stepSize: 20,
  89. display: true
  90. }
  91. }],
  92. xAxes: [
  93. {
  94. type: "time",
  95. time: {
  96. unit: 'minute',
  97. }
  98. }
  99. ]
  100. }
  101. },
  102. },
  103. cpu: 0,
  104. disk_percentage: 0,
  105. disk_total: "",
  106. disk_used: "",
  107. uptime: "",
  108. loadavg: {}
  109. }
  110. },
  111. created() {
  112. this.websocket = new WebSocket(process.env["VUE_APP_API_WSS_ROOT"] + "/analytic")
  113. this.websocket.onmessage = this.wsOnMessage
  114. this.websocket.onopen = this.wsOpen
  115. this.websocket.onerror = this.wsOnError
  116. },
  117. destroyed() {
  118. window.clearInterval(window.InitSetInterval)
  119. this.websocket.close()
  120. },
  121. methods: {
  122. wsOpen() {
  123. window.InitSetInterval = setInterval(() => {
  124. this.websocket.send("ping")
  125. }, 1000)
  126. },
  127. wsOnError() {
  128. this.websocket = new WebSocket(process.env["VUE_APP_API_WSS_ROOT"] + "/analytic")
  129. },
  130. wsOnMessage(m) {
  131. const r = JSON.parse(m.data)
  132. console.log(r)
  133. this.cpu = r.cpu_system + r.cpu_user
  134. const time = new Date()
  135. //this.cpu_analytic.labels.push(time)
  136. this.cpu_analytic.datasets[0].data
  137. .push({x: time, y: r.cpu_user})
  138. this.cpu_analytic.datasets[1].data
  139. .push({x: time, y: this.cpu})
  140. if (this.cpu_analytic.datasets[0].data.length > 30) {
  141. this.cpu_analytic.datasets[0].data.shift()
  142. this.cpu_analytic.datasets[1].data.shift()
  143. }
  144. this.cpu = this.cpu.toFixed(2)
  145. this.memory_pressure = r.memory_pressure
  146. this.memory_used = r.memory_used
  147. this.memory_cached = r.memory_cached
  148. this.memory_free = r.memory_free
  149. this.memory_total = r.memory_total
  150. this.disk_percentage = r.disk_percentage
  151. this.disk_used = r.disk_used
  152. this.disk_total = r.disk_total
  153. let uptime = Math.floor(r.uptime)
  154. let uptime_days = Math.floor(uptime / 86400)
  155. uptime -= uptime_days * 86400
  156. let uptime_hours = Math.floor(uptime / 3600)
  157. uptime -= uptime_hours * 3600
  158. this.uptime = uptime_days + 'd ' + uptime_hours + 'h ' + Math.floor(uptime/60) + 'm'
  159. this.loadavg = r.loadavg
  160. }
  161. }
  162. }
  163. </script>
  164. <style lang="less" scoped>
  165. .ant-card {
  166. margin: 10px;
  167. @media (max-width: 512px) {
  168. margin: 10px 0;
  169. }
  170. .chart {
  171. max-height: 300px;
  172. }
  173. .chart_dashboard {
  174. padding: 50px;
  175. .description {
  176. width: 120px;
  177. text-align: center
  178. }
  179. }
  180. }
  181. </style>