458458 <template v-if =" service_metrics " >
459459 <!-- Current Values Summary -->
460460 <v-row class =" mb-4" >
461- <v-col cols =" 6" sm =" 3 " >
461+ <v-col cols =" 6" sm =" 4 " md = " 2 " >
462462 <v-card outlined class =" text-center pa-3" >
463- <div class =" text-h5 primary--text" >
463+ <div class =" text-h6 primary--text" >
464464 {{ (service_metrics.cpu_percent ?? 0).toFixed(1) }}%
465465 </div >
466466 <div class =" text-caption grey--text" >
467467 CPU
468468 </div >
469469 </v-card >
470470 </v-col >
471- <v-col cols =" 6" sm =" 3 " >
471+ <v-col cols =" 6" sm =" 4 " md = " 2 " >
472472 <v-card outlined class =" text-center pa-3" >
473- <div class =" text-h5 success--text" >
473+ <div class =" text-h6 success--text" >
474474 {{ (service_metrics.memory_mb ?? 0).toFixed(1) }} MB
475475 </div >
476476 <div class =" text-caption grey--text" >
477477 Memory
478478 </div >
479479 </v-card >
480480 </v-col >
481- <v-col cols =" 6" sm =" 3 " >
481+ <v-col cols =" 6" sm =" 4 " md = " 2 " >
482482 <v-card outlined class =" text-center pa-3" >
483- <div class =" text-h5 warning--text" >
483+ <div class =" text-h6 info--text" >
484+ {{ (service_metrics.swap_mb ?? 0).toFixed(1) }} MB
485+ </div >
486+ <div class =" text-caption grey--text" >
487+ Swap
488+ </div >
489+ </v-card >
490+ </v-col >
491+ <v-col cols =" 6" sm =" 4" md =" 2" >
492+ <v-card outlined class =" text-center pa-3" >
493+ <div class =" text-h6 warning--text" >
484494 {{ (service_metrics.io_read_rate_mbps ?? 0).toFixed(2) }} MB/s
485495 </div >
486496 <div class =" text-caption grey--text" >
487- I/O Read
497+ Disk Read
488498 </div >
489499 </v-card >
490500 </v-col >
491- <v-col cols =" 6" sm =" 3 " >
501+ <v-col cols =" 6" sm =" 4 " md = " 2 " >
492502 <v-card outlined class =" text-center pa-3" >
493- <div class =" text-h5 " style =" color : #9C27B0 " >
503+ <div class =" text-h6 " style =" color : #9C27B0 " >
494504 {{ (service_metrics.io_write_rate_mbps ?? 0).toFixed(2) }} MB/s
495505 </div >
496506 <div class =" text-caption grey--text" >
497- I/O Write
507+ Disk Write
508+ </div >
509+ </v-card >
510+ </v-col >
511+ <v-col cols =" 6" sm =" 4" md =" 2" >
512+ <v-card outlined class =" text-center pa-3" >
513+ <div class =" text-h6" style =" color : #00BCD4 " >
514+ {{ formatNetRate(service_metrics.net_rx_rate_mbps, service_metrics.net_tx_rate_mbps) }}
515+ </div >
516+ <div class =" text-caption grey--text" >
517+ Network
498518 </div >
499519 </v-card >
500520 </v-col >
544564 </div >
545565 </v-card >
546566
547- <!-- I/O Chart -->
548- <v-card outlined class =" pa-3" >
567+ <!-- Swap Chart -->
568+ <v-card outlined class =" mb-4 pa-3" >
569+ <div class =" d-flex align-center mb-2" >
570+ <v-icon small color =" info" class =" mr-2" >
571+ mdi-swap-horizontal
572+ </v-icon >
573+ <span class =" text-subtitle-2" >Swap Usage</span >
574+ <v-spacer />
575+ <span class =" text-caption grey--text" >
576+ Peak: {{ (service_metrics.swap_peak_mb ?? 0).toFixed(1) }} MB
577+ </span >
578+ </div >
579+ <apexchart
580+ v-if =" metrics_history.length > 1"
581+ type =" area"
582+ height =" 150"
583+ :options =" swapChartOptions"
584+ :series =" swapChartSeries"
585+ />
586+ <div v-else class =" text-center grey--text py-4" >
587+ Collecting data...
588+ </div >
589+ </v-card >
590+
591+ <!-- Disk I/O Chart -->
592+ <v-card outlined class =" mb-4 pa-3" >
549593 <div class =" d-flex align-center mb-2" >
550594 <v-icon small color =" warning" class =" mr-2" >
551595 mdi-harddisk
552596 </v-icon >
553- <span class =" text-subtitle-2" >I/O Rate </span >
597+ <span class =" text-subtitle-2" >Disk I/O</span >
554598 <v-spacer />
555599 <span class =" text-caption grey--text" >
556600 Total: R {{ (service_metrics.io_read_mb ?? 0).toFixed(1) }} MB /
568612 Collecting data...
569613 </div >
570614 </v-card >
615+
616+ <!-- Network I/O Chart -->
617+ <v-card outlined class =" pa-3" >
618+ <div class =" d-flex align-center mb-2" >
619+ <v-icon small style =" color : #00BCD4 " class =" mr-2" >
620+ mdi-network
621+ </v-icon >
622+ <span class =" text-subtitle-2" >Network I/O</span >
623+ <v-spacer />
624+ <span class =" text-caption grey--text" >
625+ Total: RX {{ (service_metrics.net_rx_mb ?? 0).toFixed(1) }} MB /
626+ TX {{ (service_metrics.net_tx_mb ?? 0).toFixed(1) }} MB
627+ </span >
628+ </div >
629+ <apexchart
630+ v-if =" metrics_history.length > 1"
631+ type =" area"
632+ height =" 150"
633+ :options =" networkChartOptions"
634+ :series =" networkChartSeries"
635+ />
636+ <div v-else class =" text-center grey--text py-4" >
637+ Collecting data...
638+ </div >
639+ </v-card >
571640 </template >
572641 <div v-else class =" text-center grey--text pa-8" >
573642 No metrics available for this service
@@ -769,6 +838,46 @@ export default Vue.extend({
769838 },
770839 ]
771840 },
841+ swapChartOptions(): Record <string , unknown > {
842+ return {
843+ ... this .baseChartOptions ,
844+ colors: [' #2196F3' ],
845+ yaxis: {
846+ min: 0 ,
847+ labels: { formatter : (val : number ) => ` ${val .toFixed (0 )} MB ` },
848+ title: { text: ' Swap MB' },
849+ },
850+ }
851+ },
852+ swapChartSeries(): { name: string ; data: [number , number ][] }[] {
853+ return [{
854+ name: ' Swap' ,
855+ data: this .metrics_history .map ((m ) => [new Date (m .timestamp ).getTime (), m .swap_mb ?? 0 ]),
856+ }]
857+ },
858+ networkChartOptions(): Record <string , unknown > {
859+ return {
860+ ... this .baseChartOptions ,
861+ colors: [' #00BCD4' , ' #E91E63' ],
862+ yaxis: {
863+ min: 0 ,
864+ labels: { formatter : (val : number ) => ` ${val .toFixed (2 )} MB/s ` },
865+ title: { text: ' Net Rate' },
866+ },
867+ }
868+ },
869+ networkChartSeries(): { name: string ; data: [number , number ][] }[] {
870+ return [
871+ {
872+ name: ' RX' ,
873+ data: this .metrics_history .map ((m ) => [new Date (m .timestamp ).getTime (), m .net_rx_rate_mbps ?? 0 ]),
874+ },
875+ {
876+ name: ' TX' ,
877+ data: this .metrics_history .map ((m ) => [new Date (m .timestamp ).getTime (), m .net_tx_rate_mbps ?? 0 ]),
878+ },
879+ ]
880+ },
772881 },
773882
774883 watch: {
@@ -795,6 +904,13 @@ export default Vue.extend({
795904 },
796905
797906 methods: {
907+ formatNetRate(rx ? : number , tx ? : number ): string {
908+ const rxVal = rx ?? 0
909+ const txVal = tx ?? 0
910+ if (rxVal < 0.01 && txVal < 0.01 ) return ' 0'
911+ return ` ${rxVal .toFixed (1 )}/${txVal .toFixed (1 )} `
912+ },
913+
798914 async fetchServices(): Promise <void > {
799915 await back_axios ({
800916 method: ' get' ,
0 commit comments