DashBoard.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <template>
  2. <div>
  3. <a-row :gutter="[16,16]" class="first-row">
  4. <a-col :xl="7" :lg="24" :md="24">
  5. <a-card :title="$gettext('Server Info')">
  6. <p>
  7. <translate>Uptime:</translate>
  8. {{ uptime }}
  9. </p>
  10. <p>
  11. <translate>Load Averages:</translate>
  12. 1min:{{ loadavg?.load1?.toFixed(2) }} |
  13. 5min:{{ loadavg?.load5?.toFixed(2) }} |
  14. 15min:{{ loadavg?.load15?.toFixed(2) }}
  15. </p>
  16. <p>
  17. <translate>OS:</translate>
  18. {{ host.platform }} ({{ host.platformVersion }}
  19. {{ host.os }} {{ host.kernelVersion }}
  20. {{ host.kernelArch }})
  21. </p>
  22. <p v-if="cpu_info">
  23. <translate>CPU:</translate>
  24. {{ cpu_info[0]?.modelName }} * {{ cpu_info.length }}
  25. </p>
  26. </a-card>
  27. </a-col>
  28. <a-col :xl="10" :lg="16" :md="24" class="chart_dashboard">
  29. <a-card :title="$gettext('Memory and Storage')">
  30. <a-row :gutter="[0,16]">
  31. <a-col :xs="24" :sm="24" :md="8">
  32. <radial-bar-chart :name="$gettext('Memory')" :series="[memory_pressure]"
  33. :centerText="memory_used" :bottom-text="memory_total" colors="#36a3eb"/>
  34. </a-col>
  35. <a-col :xs="24" :sm="12" :md="8">
  36. <radial-bar-chart :name="$gettext('Swap')" :series="[memory_swap_percent]"
  37. :centerText="memory_swap_used"
  38. :bottom-text="memory_swap_total" colors="#ff6385"/>
  39. </a-col>
  40. <a-col :xs="24" :sm="12" :md="8">
  41. <radial-bar-chart :name="$gettext('Storage')" :series="[disk_percentage]"
  42. :centerText="disk_used" :bottom-text="disk_total" colors="#87d068"/>
  43. </a-col>
  44. </a-row>
  45. </a-card>
  46. </a-col>
  47. <a-col :xl="7" :lg="8" :sm="24" class="chart_dashboard">
  48. <a-card :title="$gettext('Network Statistics')">
  49. <a-row :gutter="16">
  50. <a-col :span="12">
  51. <a-statistic :value="bytesToSize(net.last_recv)"
  52. :title="$gettext('Network Total Receive')"/>
  53. </a-col>
  54. <a-col :span="12">
  55. <a-statistic :value="bytesToSize(net.last_sent)"
  56. :title="$gettext('Network Total Send')"/>
  57. </a-col>
  58. </a-row>
  59. </a-card>
  60. </a-col>
  61. </a-row>
  62. <a-row class="row-two" :gutter="[16,32]">
  63. <a-col :xl="8" :lg="24" :md="24" :sm="24">
  64. <a-card :title="$gettext('CPU Status')">
  65. <a-statistic :value="cpu" title="CPU">
  66. <template v-slot:suffix>
  67. <span>%</span>
  68. </template>
  69. </a-statistic>
  70. <c-p-u-chart :series="cpu_analytic_series"/>
  71. </a-card>
  72. </a-col>
  73. <a-col :xl="8" :lg="12" :md="24" :sm="24">
  74. <a-card :title="$gettext('Network')">
  75. <a-row :gutter="16">
  76. <a-col :span="12">
  77. <a-statistic :value="bytesToSize(net.recv)"
  78. :title="$gettext('Receive')">
  79. <template v-slot:suffix>
  80. <span>/s</span>
  81. </template>
  82. </a-statistic>
  83. </a-col>
  84. <a-col :span="12">
  85. <a-statistic :value="bytesToSize(net.sent)" :title="$gettext('Send')">
  86. <template v-slot:suffix>
  87. <span>/s</span>
  88. </template>
  89. </a-statistic>
  90. </a-col>
  91. </a-row>
  92. <net-chart :series="net_analytic"/>
  93. </a-card>
  94. </a-col>
  95. <a-col :xl="8" :lg="12" :md="24" :sm="24">
  96. <a-card :title="$gettext('Disk IO')">
  97. <a-row :gutter="16">
  98. <a-col :span="12">
  99. <a-statistic :value="diskIO.writes"
  100. :title="$gettext('Writes')">
  101. <template v-slot:suffix>
  102. <span>/s</span>
  103. </template>
  104. </a-statistic>
  105. </a-col>
  106. <a-col :span="12">
  107. <a-statistic :value="diskIO.reads" :title="$gettext('Reads')">
  108. <template v-slot:suffix>
  109. <span>/s</span>
  110. </template>
  111. </a-statistic>
  112. </a-col>
  113. </a-row>
  114. <disk-chart :series="diskIO_analytic"/>
  115. </a-card>
  116. </a-col>
  117. </a-row>
  118. </div>
  119. </template>
  120. <script>
  121. import ReconnectingWebSocket from 'reconnecting-websocket'
  122. import CPUChart from '@/components/Chart/CPUChart'
  123. import NetChart from '@/components/Chart/NetChart'
  124. import $gettext from '@/lib/translate/gettext'
  125. import RadialBarChart from '@/components/Chart/RadialBarChart'
  126. import DiskChart from '@/components/Chart/DiskChart'
  127. export default {
  128. name: 'DashBoard',
  129. components: {
  130. DiskChart,
  131. RadialBarChart,
  132. NetChart,
  133. CPUChart,
  134. },
  135. data() {
  136. return {
  137. websocket: null,
  138. loading: true,
  139. stat: {},
  140. memory_pressure: 0,
  141. memory_used: '',
  142. memory_cached: '',
  143. memory_free: '',
  144. memory_total: '',
  145. cpu_analytic_series: [{
  146. name: 'CPU User',
  147. data: []
  148. }, {
  149. name: 'CPU Total',
  150. data: []
  151. }],
  152. cpu: 0,
  153. memory_swap_used: '',
  154. memory_swap_total: '',
  155. memory_swap_percent: 0,
  156. disk_percentage: 0,
  157. disk_total: '',
  158. disk_used: '',
  159. net: {
  160. recv: 0,
  161. sent: 0,
  162. last_recv: 0,
  163. last_sent: 0,
  164. },
  165. diskIO: {
  166. writes: 0,
  167. reads: 0,
  168. },
  169. net_analytic: [{
  170. name: $gettext('Receive'),
  171. data: []
  172. }, {
  173. name: $gettext('Send'),
  174. data: []
  175. }],
  176. diskIO_analytic: [{
  177. name: $gettext('Writes'),
  178. data: []
  179. }, {
  180. name: $gettext('Reads'),
  181. data: []
  182. }],
  183. uptime: '',
  184. loadavg: {},
  185. cpu_info: [],
  186. host: {}
  187. }
  188. },
  189. created() {
  190. this.websocket = new ReconnectingWebSocket(this.getWebSocketRoot() + '/analytic?token='
  191. + btoa(this.$store.state.user.token))
  192. this.websocket.onmessage = this.wsOnMessage
  193. this.websocket.onopen = this.wsOpen
  194. this.$api.analytic.init().then(r => {
  195. this.cpu_info = r.cpu.info
  196. this.net.last_recv = r.network.init.bytesRecv
  197. this.net.last_sent = r.network.init.bytesSent
  198. this.host = r.host
  199. r.cpu.user.forEach(u => {
  200. this.cpu_analytic_series[0].data.push([u.x, u.y.toFixed(2)])
  201. })
  202. r.cpu.total.forEach(u => {
  203. this.cpu_analytic_series[1].data.push([u.x, u.y.toFixed(2)])
  204. })
  205. r.network.bytesRecv.forEach(u => {
  206. this.net_analytic[0].data.push([u.x, u.y.toFixed(2)])
  207. })
  208. r.network.bytesSent.forEach(u => {
  209. this.net_analytic[1].data.push([u.x, u.y.toFixed(2)])
  210. })
  211. this.diskIO_analytic[0].data = this.diskIO_analytic[0].data.concat(r.diskIO.writes)
  212. this.diskIO_analytic[1].data = this.diskIO_analytic[1].data.concat(r.diskIO.reads)
  213. })
  214. },
  215. destroyed() {
  216. this.websocket.close()
  217. },
  218. methods: {
  219. wsOpen() {
  220. this.websocket.send('ping')
  221. },
  222. wsOnMessage(m) {
  223. const r = JSON.parse(m.data)
  224. // console.log(r)
  225. this.cpu = r.cpu_system + r.cpu_user
  226. this.cpu = this.cpu.toFixed(2)
  227. const time = new Date().getTime()
  228. this.cpu_analytic_series[0].data.push([time, r.cpu_user.toFixed(2)])
  229. this.cpu_analytic_series[1].data.push([time, this.cpu])
  230. if (this.cpu_analytic_series[0].data.length > 100) {
  231. this.cpu_analytic_series[0].data.shift()
  232. this.cpu_analytic_series[1].data.shift()
  233. }
  234. // mem
  235. this.memory_pressure = r.memory_pressure
  236. this.memory_used = r.memory_used
  237. this.memory_cached = r.memory_cached
  238. this.memory_free = r.memory_free
  239. this.memory_total = r.memory_total
  240. this.memory_swap_percent = r.memory_swap_percent
  241. this.memory_swap_used = r.memory_swap_used
  242. this.memory_swap_total = r.memory_swap_total
  243. // disk
  244. this.disk_percentage = r.disk_percentage
  245. this.disk_used = r.disk_used
  246. this.disk_total = r.disk_total
  247. let uptime = Math.floor(r.uptime)
  248. let uptime_days = Math.floor(uptime / 86400)
  249. uptime -= uptime_days * 86400
  250. let uptime_hours = Math.floor(uptime / 3600)
  251. uptime -= uptime_hours * 3600
  252. this.uptime = uptime_days + 'd ' + uptime_hours + 'h ' + Math.floor(uptime / 60) + 'm'
  253. this.loadavg = r.loadavg
  254. // net
  255. this.net.recv = r.network.bytesRecv - this.net.last_recv
  256. this.net.sent = r.network.bytesSent - this.net.last_sent
  257. this.net.last_recv = r.network.bytesRecv
  258. this.net.last_sent = r.network.bytesSent
  259. this.net_analytic[0].data.push([time, this.net.recv])
  260. this.net_analytic[1].data.push([time, this.net.sent])
  261. if (this.net_analytic[0].data.length > 100) {
  262. this.net_analytic[0].data.shift()
  263. this.net_analytic[1].data.shift()
  264. }
  265. // diskIO
  266. this.diskIO.writes = r.diskIO.writes.y
  267. this.diskIO.reads = r.diskIO.reads.y
  268. this.diskIO_analytic[0].data.push(r.diskIO.writes)
  269. this.diskIO_analytic[1].data.push(r.diskIO.reads)
  270. if (this.diskIO_analytic[0].data.length > 100) {
  271. this.diskIO_analytic[0].data.shift()
  272. this.diskIO_analytic[1].data.shift()
  273. }
  274. }
  275. }
  276. }
  277. </script>
  278. <style lang="less" scoped>
  279. .first-row {
  280. .ant-card {
  281. min-height: 227px;
  282. }
  283. }
  284. .ant-card {
  285. .ant-statistic {
  286. margin: 0 50px 10px 10px
  287. }
  288. .chart {
  289. max-width: 800px;
  290. max-height: 350px;
  291. }
  292. .chart_dashboard {
  293. padding: 60px;
  294. .description {
  295. width: 120px;
  296. text-align: center
  297. }
  298. }
  299. @media (max-width: 512px) {
  300. margin: 10px 0;
  301. .chart_dashboard {
  302. padding: 20px;
  303. }
  304. }
  305. }
  306. </style>