Statistics.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <script setup lang="ts">
  2. import { ref, onMounted } from "vue";
  3. import { useStore } from "vuex";
  4. import { useRoute } from "vue-router";
  5. import ws from "@/ws";
  6. const store = useStore();
  7. const route = useRoute();
  8. const { socket } = store.state.websockets;
  9. const modules = ref([]);
  10. const activeModule = ref();
  11. const init = () => {
  12. socket.dispatch("utils.getModules", res => {
  13. if (res.status === "success") modules.value = res.data.modules;
  14. });
  15. if (route.query.moduleName) {
  16. socket.dispatch("utils.getModule", route.query.moduleName, res => {
  17. if (res.status === "success")
  18. activeModule.value = {
  19. runningJobs: res.data.runningJobs,
  20. jobStatistics: res.data.jobStatistics
  21. };
  22. });
  23. }
  24. };
  25. onMounted(() => {
  26. ws.onConnect(init);
  27. });
  28. </script>
  29. <template>
  30. <div class="admin-tab container">
  31. <page-metadata title="Admin | Statistics" />
  32. <div class="card tab-info">
  33. <div class="info-row">
  34. <h1>Statistics</h1>
  35. <p>Analyze backend server job statistics</p>
  36. </div>
  37. </div>
  38. <div class="card">
  39. <h4>Average Logs</h4>
  40. <hr class="section-horizontal-rule" />
  41. <div class="card-content">
  42. <table class="table">
  43. <thead>
  44. <tr>
  45. <th>Name</th>
  46. <th>Status</th>
  47. <th>Stage</th>
  48. <th>Jobs in queue</th>
  49. <th>Jobs in progress</th>
  50. <th>Jobs paused</th>
  51. <th>Concurrency</th>
  52. </tr>
  53. </thead>
  54. <tbody>
  55. <tr
  56. v-for="moduleItem in modules"
  57. :key="moduleItem.name"
  58. >
  59. <td>
  60. <router-link
  61. :to="'?moduleName=' + moduleItem.name"
  62. >{{ moduleItem.name }}</router-link
  63. >
  64. </td>
  65. <td>{{ moduleItem.status }}</td>
  66. <td>{{ moduleItem.stage }}</td>
  67. <td>{{ moduleItem.jobsInQueue }}</td>
  68. <td>{{ moduleItem.jobsInProgress }}</td>
  69. <td>{{ moduleItem.jobsPaused }}</td>
  70. <td>{{ moduleItem.concurrency }}</td>
  71. </tr>
  72. </tbody>
  73. </table>
  74. </div>
  75. </div>
  76. <div v-if="activeModule" class="card">
  77. <h4>Running Tasks</h4>
  78. <hr class="section-horizontal-rule" />
  79. <div class="card-content">
  80. <table class="table">
  81. <thead>
  82. <tr>
  83. <th>Name</th>
  84. <th>Payload</th>
  85. </tr>
  86. </thead>
  87. <tbody>
  88. <tr
  89. v-for="job in activeModule.runningTasks"
  90. :key="JSON.stringify(job)"
  91. >
  92. <td>{{ job.name }}</td>
  93. <td>
  94. {{ JSON.stringify(job.payload) }}
  95. </td>
  96. </tr>
  97. </tbody>
  98. </table>
  99. </div>
  100. </div>
  101. <div v-if="activeModule" class="card">
  102. <h4>Paused Tasks</h4>
  103. <hr class="section-horizontal-rule" />
  104. <div class="card-content">
  105. <table class="table">
  106. <thead>
  107. <tr>
  108. <th>Name</th>
  109. <th>Payload</th>
  110. </tr>
  111. </thead>
  112. <tbody>
  113. <tr
  114. v-for="job in activeModule.pausedTasks"
  115. :key="JSON.stringify(job)"
  116. >
  117. <td>{{ job.name }}</td>
  118. <td>
  119. {{ JSON.stringify(job.payload) }}
  120. </td>
  121. </tr>
  122. </tbody>
  123. </table>
  124. </div>
  125. </div>
  126. <div v-if="activeModule" class="card">
  127. <h4>Queued Tasks</h4>
  128. <hr class="section-horizontal-rule" />
  129. <div class="card-content">
  130. <table class="table">
  131. <thead>
  132. <tr>
  133. <th>Name</th>
  134. <th>Payload</th>
  135. </tr>
  136. </thead>
  137. <tbody>
  138. <tr
  139. v-for="job in activeModule.queuedTasks"
  140. :key="JSON.stringify(job)"
  141. >
  142. <td>{{ job.name }}</td>
  143. <td>
  144. {{ JSON.stringify(job.payload) }}
  145. </td>
  146. </tr>
  147. </tbody>
  148. </table>
  149. </div>
  150. </div>
  151. <div v-if="activeModule">
  152. <div class="card">
  153. <h4>Average Logs</h4>
  154. <hr class="section-horizontal-rule" />
  155. <div class="card-content">
  156. <table class="table">
  157. <thead>
  158. <tr>
  159. <th>Job name</th>
  160. <th>Successful</th>
  161. <th>Failed</th>
  162. <th>Total</th>
  163. <th>Average timing</th>
  164. </tr>
  165. </thead>
  166. <tbody>
  167. <tr
  168. v-for="(
  169. job, jobName
  170. ) in activeModule.jobStatistics"
  171. :key="jobName"
  172. >
  173. <td>{{ jobName }}</td>
  174. <td>
  175. {{ job.successful }}
  176. </td>
  177. <td>
  178. {{ job.failed }}
  179. </td>
  180. <td>
  181. {{ job.total }}
  182. </td>
  183. <td>
  184. {{ job.averageTiming }}
  185. </td>
  186. </tr>
  187. </tbody>
  188. </table>
  189. </div>
  190. </div>
  191. </div>
  192. </div>
  193. </template>
  194. <style lang="less" scoped>
  195. .night-mode {
  196. .table {
  197. color: var(--light-grey-2);
  198. background-color: var(--dark-grey-3);
  199. thead tr {
  200. background: var(--dark-grey-3);
  201. td {
  202. color: var(--white);
  203. }
  204. }
  205. tbody tr:hover {
  206. background-color: var(--dark-grey-4) !important;
  207. }
  208. tbody tr:nth-child(even) {
  209. background-color: var(--dark-grey-2);
  210. }
  211. strong {
  212. color: var(--light-grey-2);
  213. }
  214. }
  215. }
  216. td {
  217. vertical-align: middle;
  218. }
  219. </style>