DashBoard.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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="$gettext('Server status')">
  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><translate>Uptime</translate> {{ uptime }}</p>
  14. <p><translate>Load averages</translate> 1min:{{ loadavg.load1 }} 5min:{{ loadavg.load5 }}
  15. 15min:{{ loadavg.load15 }}</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="$gettext('Used:') + memory_used + $gettext('Cached:') +
  22. memory_cached + $gettext('Free:') + memory_free +
  23. $gettext('Physical memory:') + memory_total">
  24. <a-progress :percent="memory_pressure" strokeColor="rgb(135, 208, 104)"
  25. type="dashboard"/>
  26. <p class="description" v-translate>Memory</p>
  27. </a-tooltip>
  28. </div>
  29. </a-col>
  30. <a-col :lg="6" :sm="8" :xs="12" class="chart_dashboard">
  31. <div>
  32. <a-tooltip
  33. :title="$gettext('Used:')+ disk_used +
  34. ' / '+ $gettext('Total:') + disk_total">
  35. <a-progress :percent="disk_percentage" type="dashboard"/>
  36. <p class="description" v-translate>Storage</p>
  37. </a-tooltip>
  38. </div>
  39. </a-col>
  40. </a-row>
  41. </a-card>
  42. </a-col>
  43. </a-row>
  44. </div>
  45. </template>
  46. <script>
  47. import LineChart from '@/components/Chart/LineChart'
  48. import ReconnectingWebSocket from 'reconnecting-websocket'
  49. export default {
  50. name: 'DashBoard',
  51. components: {
  52. LineChart
  53. },
  54. data() {
  55. return {
  56. websocket: null,
  57. loading: true,
  58. stat: {},
  59. memory_pressure: 0,
  60. memory_used: '',
  61. memory_cached: '',
  62. memory_free: '',
  63. memory_total: '',
  64. cpu_analytic: {
  65. datasets: [{
  66. label: 'cpu user',
  67. borderColor: '#36a3eb',
  68. backgroundColor: '#36a3eb',
  69. pointRadius: 0,
  70. data: [],
  71. }, {
  72. label: 'cpu total',
  73. borderColor: '#ff6385',
  74. backgroundColor: '#ff6385',
  75. pointRadius: 0,
  76. data: [],
  77. }],
  78. options: {
  79. responsive: true,
  80. maintainAspectRatio: false,
  81. responsiveAnimationDuration: 0, // 调整大小后的动画持续时间
  82. elements: {
  83. line: {
  84. tension: 0 // 禁用贝塞尔曲线
  85. }
  86. },
  87. scales: {
  88. yAxes: [{
  89. ticks: {
  90. max: 100,
  91. min: 0,
  92. stepSize: 20,
  93. display: true
  94. }
  95. }],
  96. xAxes: [
  97. {
  98. type: 'time',
  99. time: {
  100. unit: 'minute',
  101. }
  102. }
  103. ]
  104. }
  105. },
  106. },
  107. cpu: 0,
  108. disk_percentage: 0,
  109. disk_total: '',
  110. disk_used: '',
  111. uptime: '',
  112. loadavg: {}
  113. }
  114. },
  115. created() {
  116. this.websocket = new ReconnectingWebSocket(this.getWebSocketRoot() + '/analytic?token='
  117. + btoa(this.$store.state.user.token))
  118. this.websocket.onmessage = this.wsOnMessage
  119. this.websocket.onopen = this.wsOpen
  120. const time = new Date()
  121. for (let i = 0; i < 120; i++) {
  122. this.cpu_analytic.datasets[0].data.push({x: time, y: 0})
  123. this.cpu_analytic.datasets[1].data.push({x: time, y: 0})
  124. }
  125. },
  126. destroyed() {
  127. this.websocket.close()
  128. },
  129. methods: {
  130. wsOpen() {
  131. this.websocket.send('ping')
  132. },
  133. wsOnMessage(m) {
  134. const r = JSON.parse(m.data)
  135. // console.log(r)
  136. this.cpu = r.cpu_system + r.cpu_user
  137. const time = new Date()
  138. this.cpu_analytic.datasets[0].data
  139. .push({x: time, y: r.cpu_user})
  140. this.cpu_analytic.datasets[1].data
  141. .push({x: time, y: this.cpu})
  142. if (this.cpu_analytic.datasets[0].data.length > 120) {
  143. this.cpu_analytic.datasets[0].data.shift()
  144. this.cpu_analytic.datasets[1].data.shift()
  145. }
  146. this.cpu = this.cpu.toFixed(2)
  147. this.memory_pressure = r.memory_pressure
  148. this.memory_used = r.memory_used
  149. this.memory_cached = r.memory_cached
  150. this.memory_free = r.memory_free
  151. this.memory_total = r.memory_total
  152. this.disk_percentage = r.disk_percentage
  153. this.disk_used = r.disk_used
  154. this.disk_total = r.disk_total
  155. let uptime = Math.floor(r.uptime)
  156. let uptime_days = Math.floor(uptime / 86400)
  157. uptime -= uptime_days * 86400
  158. let uptime_hours = Math.floor(uptime / 3600)
  159. uptime -= uptime_hours * 3600
  160. this.uptime = uptime_days + 'd ' + uptime_hours + 'h ' + Math.floor(uptime / 60) + 'm'
  161. this.loadavg = r.loadavg
  162. }
  163. }
  164. }
  165. </script>
  166. <style lang="less" scoped>
  167. .ant-card {
  168. .chart {
  169. max-height: 300px;
  170. }
  171. .chart_dashboard {
  172. padding: 60px;
  173. .description {
  174. width: 120px;
  175. text-align: center
  176. }
  177. }
  178. @media (max-width: 512px) {
  179. margin: 10px 0;
  180. .chart_dashboard {
  181. padding: 20px;
  182. }
  183. }
  184. }
  185. </style>