Statistics.vue 4.7 KB

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