diff --git a/backend/app/api/v1/dashboard.go b/backend/app/api/v1/dashboard.go index 0ada8bdb8828..c38db42e588d 100644 --- a/backend/app/api/v1/dashboard.go +++ b/backend/app/api/v1/dashboard.go @@ -2,6 +2,7 @@ package v1 import ( "errors" + "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" "github.com/1Panel-dev/1Panel/backend/constant" @@ -55,25 +56,17 @@ func (b *BaseApi) LoadDashboardBaseInfo(c *gin.Context) { // @Tags Dashboard // @Summary Load dashboard current info // @Description 获取首页实时数据 -// @Accept json -// @Param ioOption path string true "request" -// @Param netOption path string true "request" +// @Accept json、 +// @Param request body dto.DashboardReq true "request" // @Success 200 {object} dto.DashboardCurrent // @Security ApiKeyAuth -// @Router /dashboard/current/:ioOption/:netOption [get] +// @Router /dashboard/current [post] func (b *BaseApi) LoadDashboardCurrentInfo(c *gin.Context) { - ioOption, ok := c.Params.Get("ioOption") - if !ok { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error ioOption in path")) + var req dto.DashboardReq + if err := helper.CheckBindAndValidate(&req, c); err != nil { return } - netOption, ok := c.Params.Get("netOption") - if !ok { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error netOption in path")) - return - } - - data := dashboardService.LoadCurrentInfo(ioOption, netOption) + data := dashboardService.LoadCurrentInfo(req) helper.SuccessWithData(c, data) } diff --git a/backend/app/dto/dashboard.go b/backend/app/dto/dashboard.go index 0acb3866100e..1ade50fbf60e 100644 --- a/backend/app/dto/dashboard.go +++ b/backend/app/dto/dashboard.go @@ -35,6 +35,12 @@ type OsInfo struct { DiskSize int64 `json:"diskSize"` } +type DashboardReq struct { + Scope string `json:"scope"` + IoOption string `json:"ioOption"` + NetOption string `json:"netOption"` +} + type DashboardCurrent struct { Uptime uint64 `json:"uptime"` TimeSinceUptime string `json:"timeSinceUptime"` diff --git a/backend/app/service/dashboard.go b/backend/app/service/dashboard.go index 239843170d7c..45ef228b2ec1 100644 --- a/backend/app/service/dashboard.go +++ b/backend/app/service/dashboard.go @@ -3,6 +3,10 @@ package service import ( "encoding/json" "fmt" + "github.com/1Panel-dev/1Panel/backend/constant" + "github.com/shirou/gopsutil/v3/load" + "github.com/shirou/gopsutil/v3/mem" + "github.com/shirou/gopsutil/v3/net" network "net" "os" "sort" @@ -11,7 +15,6 @@ import ( "time" "github.com/1Panel-dev/1Panel/backend/app/dto" - "github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/global" "github.com/1Panel-dev/1Panel/backend/utils/cmd" "github.com/1Panel-dev/1Panel/backend/utils/copier" @@ -19,9 +22,6 @@ import ( "github.com/shirou/gopsutil/v3/cpu" "github.com/shirou/gopsutil/v3/disk" "github.com/shirou/gopsutil/v3/host" - "github.com/shirou/gopsutil/v3/load" - "github.com/shirou/gopsutil/v3/mem" - "github.com/shirou/gopsutil/v3/net" ) type DashboardService struct{} @@ -29,7 +29,7 @@ type DashboardService struct{} type IDashboardService interface { LoadOsInfo() (*dto.OsInfo, error) LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error) - LoadCurrentInfo(ioOption string, netOption string) *dto.DashboardCurrent + LoadCurrentInfo(req dto.DashboardReq) *dto.DashboardCurrent Restart(operation string) error } @@ -139,79 +139,88 @@ func (u *DashboardService) LoadBaseInfo(ioOption string, netOption string) (*dto baseInfo.CPUCores, _ = cpu.Counts(false) baseInfo.CPULogicalCores, _ = cpu.Counts(true) - baseInfo.CurrentInfo = *u.LoadCurrentInfo(ioOption, netOption) + baseInfo.CurrentInfo = *u.LoadCurrentInfo(dto.DashboardReq{ + Scope: "ioNet", + IoOption: ioOption, + NetOption: netOption, + }) return &baseInfo, nil } -func (u *DashboardService) LoadCurrentInfo(ioOption string, netOption string) *dto.DashboardCurrent { +func (u *DashboardService) LoadCurrentInfo(req dto.DashboardReq) *dto.DashboardCurrent { var currentInfo dto.DashboardCurrent + if req.Scope == "gpu" { + currentInfo.GPUData = loadGPUInfo() + currentInfo.XPUData = loadXpuInfo() + } + hostInfo, _ := host.Info() currentInfo.Uptime = hostInfo.Uptime - currentInfo.TimeSinceUptime = time.Now().Add(-time.Duration(hostInfo.Uptime) * time.Second).Format(constant.DateTimeLayout) - currentInfo.Procs = hostInfo.Procs - - currentInfo.CPUTotal, _ = cpu.Counts(true) - totalPercent, _ := cpu.Percent(100*time.Millisecond, false) - if len(totalPercent) == 1 { - currentInfo.CPUUsedPercent = totalPercent[0] - currentInfo.CPUUsed = currentInfo.CPUUsedPercent * 0.01 * float64(currentInfo.CPUTotal) - } - currentInfo.CPUPercent, _ = cpu.Percent(100*time.Millisecond, true) - - loadInfo, _ := load.Avg() - currentInfo.Load1 = loadInfo.Load1 - currentInfo.Load5 = loadInfo.Load5 - currentInfo.Load15 = loadInfo.Load15 - currentInfo.LoadUsagePercent = loadInfo.Load1 / (float64(currentInfo.CPUTotal*2) * 0.75) * 100 - - memoryInfo, _ := mem.VirtualMemory() - currentInfo.MemoryTotal = memoryInfo.Total - currentInfo.MemoryAvailable = memoryInfo.Available - currentInfo.MemoryUsed = memoryInfo.Used - currentInfo.MemoryUsedPercent = memoryInfo.UsedPercent - - swapInfo, _ := mem.SwapMemory() - currentInfo.SwapMemoryTotal = swapInfo.Total - currentInfo.SwapMemoryAvailable = swapInfo.Free - currentInfo.SwapMemoryUsed = swapInfo.Used - currentInfo.SwapMemoryUsedPercent = swapInfo.UsedPercent - - currentInfo.DiskData = loadDiskInfo() - currentInfo.GPUData = loadGPUInfo() - currentInfo.XPUData = loadXpuInfo() - - if ioOption == "all" { - diskInfo, _ := disk.IOCounters() - for _, state := range diskInfo { - currentInfo.IOReadBytes += state.ReadBytes - currentInfo.IOWriteBytes += state.WriteBytes - currentInfo.IOCount += (state.ReadCount + state.WriteCount) - currentInfo.IOReadTime += state.ReadTime - currentInfo.IOWriteTime += state.WriteTime - } - } else { - diskInfo, _ := disk.IOCounters(ioOption) - for _, state := range diskInfo { - currentInfo.IOReadBytes += state.ReadBytes - currentInfo.IOWriteBytes += state.WriteBytes - currentInfo.IOCount += (state.ReadCount + state.WriteCount) - currentInfo.IOReadTime += state.ReadTime - currentInfo.IOWriteTime += state.WriteTime + if req.Scope == "basic" { + currentInfo.TimeSinceUptime = time.Now().Add(-time.Duration(hostInfo.Uptime) * time.Second).Format(constant.DateTimeLayout) + currentInfo.Procs = hostInfo.Procs + currentInfo.CPUTotal, _ = cpu.Counts(true) + totalPercent, _ := cpu.Percent(100*time.Millisecond, false) + if len(totalPercent) == 1 { + currentInfo.CPUUsedPercent = totalPercent[0] + currentInfo.CPUUsed = currentInfo.CPUUsedPercent * 0.01 * float64(currentInfo.CPUTotal) } + currentInfo.CPUPercent, _ = cpu.Percent(100*time.Millisecond, true) + + loadInfo, _ := load.Avg() + currentInfo.Load1 = loadInfo.Load1 + currentInfo.Load5 = loadInfo.Load5 + currentInfo.Load15 = loadInfo.Load15 + currentInfo.LoadUsagePercent = loadInfo.Load1 / (float64(currentInfo.CPUTotal*2) * 0.75) * 100 + + memoryInfo, _ := mem.VirtualMemory() + currentInfo.MemoryTotal = memoryInfo.Total + currentInfo.MemoryAvailable = memoryInfo.Available + currentInfo.MemoryUsed = memoryInfo.Used + currentInfo.MemoryUsedPercent = memoryInfo.UsedPercent + + swapInfo, _ := mem.SwapMemory() + currentInfo.SwapMemoryTotal = swapInfo.Total + currentInfo.SwapMemoryAvailable = swapInfo.Free + currentInfo.SwapMemoryUsed = swapInfo.Used + currentInfo.SwapMemoryUsedPercent = swapInfo.UsedPercent + currentInfo.DiskData = loadDiskInfo() } - if netOption == "all" { - netInfo, _ := net.IOCounters(false) - if len(netInfo) != 0 { - currentInfo.NetBytesSent = netInfo[0].BytesSent - currentInfo.NetBytesRecv = netInfo[0].BytesRecv + if req.Scope == "ioNet" { + if req.IoOption == "all" { + diskInfo, _ := disk.IOCounters() + for _, state := range diskInfo { + currentInfo.IOReadBytes += state.ReadBytes + currentInfo.IOWriteBytes += state.WriteBytes + currentInfo.IOCount += (state.ReadCount + state.WriteCount) + currentInfo.IOReadTime += state.ReadTime + currentInfo.IOWriteTime += state.WriteTime + } + } else { + diskInfo, _ := disk.IOCounters(req.IoOption) + for _, state := range diskInfo { + currentInfo.IOReadBytes += state.ReadBytes + currentInfo.IOWriteBytes += state.WriteBytes + currentInfo.IOCount += (state.ReadCount + state.WriteCount) + currentInfo.IOReadTime += state.ReadTime + currentInfo.IOWriteTime += state.WriteTime + } } - } else { - netInfo, _ := net.IOCounters(true) - for _, state := range netInfo { - if state.Name == netOption { - currentInfo.NetBytesSent = state.BytesSent - currentInfo.NetBytesRecv = state.BytesRecv + + if req.NetOption == "all" { + netInfo, _ := net.IOCounters(false) + if len(netInfo) != 0 { + currentInfo.NetBytesSent = netInfo[0].BytesSent + currentInfo.NetBytesRecv = netInfo[0].BytesRecv + } + } else { + netInfo, _ := net.IOCounters(true) + for _, state := range netInfo { + if state.Name == req.NetOption { + currentInfo.NetBytesSent = state.BytesSent + currentInfo.NetBytesRecv = state.BytesRecv + } } } } diff --git a/backend/router/ro_dashboard.go b/backend/router/ro_dashboard.go index 7a4109b3259a..81fb014e41cd 100644 --- a/backend/router/ro_dashboard.go +++ b/backend/router/ro_dashboard.go @@ -18,7 +18,7 @@ func (s *DashboardRouter) InitRouter(Router *gin.RouterGroup) { { cmdRouter.GET("/base/os", baseApi.LoadDashboardOsInfo) cmdRouter.GET("/base/:ioOption/:netOption", baseApi.LoadDashboardBaseInfo) - cmdRouter.GET("/current/:ioOption/:netOption", baseApi.LoadDashboardCurrentInfo) + cmdRouter.POST("/current", baseApi.LoadDashboardCurrentInfo) cmdRouter.POST("/system/restart/:operation", baseApi.SystemRestart) } } diff --git a/frontend/src/api/interface/dashboard.ts b/frontend/src/api/interface/dashboard.ts index b6f0a668e84d..5164c68d72fa 100644 --- a/frontend/src/api/interface/dashboard.ts +++ b/frontend/src/api/interface/dashboard.ts @@ -105,4 +105,10 @@ export namespace Dashboard { power: string; memoryUtil: string; } + + export interface DashboardReq { + scope: string; + ioOption: string; + netOption: string; + } } diff --git a/frontend/src/api/modules/dashboard.ts b/frontend/src/api/modules/dashboard.ts index 59697cd44c3b..a42c8c2846e4 100644 --- a/frontend/src/api/modules/dashboard.ts +++ b/frontend/src/api/modules/dashboard.ts @@ -9,8 +9,8 @@ export const loadBaseInfo = (ioOption: string, netOption: string) => { return http.get(`/dashboard/base/${ioOption}/${netOption}`); }; -export const loadCurrentInfo = (ioOption: string, netOption: string) => { - return http.get(`/dashboard/current/${ioOption}/${netOption}`); +export const loadCurrentInfo = (req: Dashboard.DashboardReq) => { + return http.post(`/dashboard/current`, req); }; export const systemRestart = (operation: string) => { diff --git a/frontend/src/views/home/index.vue b/frontend/src/views/home/index.vue index 1007d634acce..0077e4bbb63a 100644 --- a/frontend/src/views/home/index.vue +++ b/frontend/src/views/home/index.vue @@ -309,6 +309,7 @@ const isProductPro = ref(); const searchInfo = reactive({ ioOption: 'all', netOption: 'all', + scope: 'all', }); const baseInfo = ref({ @@ -416,77 +417,151 @@ const onLoadBaseInfo = async (isInit: boolean, range: string) => { } const res = await loadBaseInfo(searchInfo.ioOption, searchInfo.netOption); baseInfo.value = res.data; - currentInfo.value = baseInfo.value.currentInfo; - await onLoadCurrentInfo(); + + const resData = res.data.currentInfo; + currentInfo.value.ioReadBytes = resData.ioReadBytes; + currentInfo.value.ioWriteBytes = resData.ioWriteBytes; + currentInfo.value.ioCount = resData.ioCount; + currentInfo.value.ioReadTime = resData.ioReadTime; + currentInfo.value.ioWriteTime = resData.ioWriteTime; + currentInfo.value.netBytesSent = resData.netBytesSent; + currentInfo.value.netBytesRecv = resData.netBytesRecv; + currentInfo.value.uptime = resData.uptime; + + loadAppCurrentInfo(); isStatusInit.value = false; statusRef.value.acceptParams(currentInfo.value, baseInfo.value, isStatusInit.value); appRef.value.acceptParams(); if (isInit) { timer = setInterval(async () => { if (isActive.value && !globalStore.isOnRestart) { - await onLoadCurrentInfo(); + loadAppCurrentInfo(); } }, 3000); } }; -const onLoadCurrentInfo = async () => { - const res = await loadCurrentInfo(searchInfo.ioOption, searchInfo.netOption); - currentInfo.value.timeSinceUptime = res.data.timeSinceUptime; - - let timeInterval = Number(res.data.uptime - currentInfo.value.uptime) || 3; - currentChartInfo.netBytesSent = - res.data.netBytesSent - currentInfo.value.netBytesSent > 0 - ? Number(((res.data.netBytesSent - currentInfo.value.netBytesSent) / 1024 / timeInterval).toFixed(2)) - : 0; - netBytesSents.value.push(currentChartInfo.netBytesSent); - if (netBytesSents.value.length > 20) { - netBytesSents.value.splice(0, 1); - } +const loadAppCurrentInfo = async () => { + await Promise.all([onLoadCurrentInfo('gpu'), onLoadCurrentInfo('basic'), onLoadCurrentInfo('ioNet')]); + statusRef.value.acceptParams(currentInfo.value, baseInfo.value, isStatusInit.value); +}; - currentChartInfo.netBytesRecv = - res.data.netBytesRecv - currentInfo.value.netBytesRecv > 0 - ? Number(((res.data.netBytesRecv - currentInfo.value.netBytesRecv) / 1024 / timeInterval).toFixed(2)) - : 0; - netBytesRecvs.value.push(currentChartInfo.netBytesRecv); - if (netBytesRecvs.value.length > 20) { - netBytesRecvs.value.splice(0, 1); - } +const onLoadCurrentInfo = async (scope: string) => { + const req = { + scope: scope, + ioOption: searchInfo.ioOption, + netOption: searchInfo.netOption, + }; + const res = await loadCurrentInfo(req); + const resData = res.data; + + if (scope === 'ioNet') { + let timeInterval = Number(res.data.uptime - currentInfo.value.uptime) || 3; + currentChartInfo.netBytesSent = + res.data.netBytesSent - currentInfo.value.netBytesSent > 0 + ? Number(((res.data.netBytesSent - currentInfo.value.netBytesSent) / 1024 / timeInterval).toFixed(2)) + : 0; + console.log('value', res.data.netBytesSent - currentInfo.value.netBytesSent); + console.log( + 'number', + Number(((res.data.netBytesSent - currentInfo.value.netBytesSent) / 1024 / timeInterval).toFixed(2)), + ); + netBytesSents.value.push(currentChartInfo.netBytesSent); - currentChartInfo.ioReadBytes = - res.data.ioReadBytes - currentInfo.value.ioReadBytes > 0 - ? Number(((res.data.ioReadBytes - currentInfo.value.ioReadBytes) / 1024 / 1024 / timeInterval).toFixed(2)) - : 0; - ioReadBytes.value.push(currentChartInfo.ioReadBytes); - if (ioReadBytes.value.length > 20) { - ioReadBytes.value.splice(0, 1); - } + if (netBytesSents.value.length > 20) { + netBytesSents.value.splice(0, 1); + } + + currentChartInfo.netBytesRecv = + res.data.netBytesRecv - currentInfo.value.netBytesRecv > 0 + ? Number(((res.data.netBytesRecv - currentInfo.value.netBytesRecv) / 1024 / timeInterval).toFixed(2)) + : 0; + netBytesRecvs.value.push(currentChartInfo.netBytesRecv); + if (netBytesRecvs.value.length > 20) { + netBytesRecvs.value.splice(0, 1); + } - currentChartInfo.ioWriteBytes = - res.data.ioWriteBytes - currentInfo.value.ioWriteBytes > 0 - ? Number(((res.data.ioWriteBytes - currentInfo.value.ioWriteBytes) / 1024 / 1024 / timeInterval).toFixed(2)) - : 0; - ioWriteBytes.value.push(currentChartInfo.ioWriteBytes); - if (ioWriteBytes.value.length > 20) { - ioWriteBytes.value.splice(0, 1); + currentChartInfo.ioReadBytes = + res.data.ioReadBytes - currentInfo.value.ioReadBytes > 0 + ? Number( + ((res.data.ioReadBytes - currentInfo.value.ioReadBytes) / 1024 / 1024 / timeInterval).toFixed(2), + ) + : 0; + ioReadBytes.value.push(currentChartInfo.ioReadBytes); + if (ioReadBytes.value.length > 20) { + ioReadBytes.value.splice(0, 1); + } + + currentChartInfo.ioWriteBytes = + res.data.ioWriteBytes - currentInfo.value.ioWriteBytes > 0 + ? Number( + ((res.data.ioWriteBytes - currentInfo.value.ioWriteBytes) / 1024 / 1024 / timeInterval).toFixed( + 2, + ), + ) + : 0; + ioWriteBytes.value.push(currentChartInfo.ioWriteBytes); + if (ioWriteBytes.value.length > 20) { + ioWriteBytes.value.splice(0, 1); + } + currentChartInfo.ioCount = Math.round(Number((res.data.ioCount - currentInfo.value.ioCount) / timeInterval)); + let ioReadTime = res.data.ioReadTime - currentInfo.value.ioReadTime; + let ioWriteTime = res.data.ioWriteTime - currentInfo.value.ioWriteTime; + let ioChoose = ioReadTime > ioWriteTime ? ioReadTime : ioWriteTime; + currentChartInfo.ioTime = Math.round(Number(ioChoose / timeInterval)); + + timeIODatas.value.push(dateFormatForSecond(res.data.shotTime)); + if (timeIODatas.value.length > 20) { + timeIODatas.value.splice(0, 1); + } + timeNetDatas.value.push(dateFormatForSecond(res.data.shotTime)); + if (timeNetDatas.value.length > 20) { + timeNetDatas.value.splice(0, 1); + } + loadData(); + + currentInfo.value.ioReadBytes = resData.ioReadBytes; + currentInfo.value.ioWriteBytes = resData.ioWriteBytes; + currentInfo.value.ioCount = resData.ioCount; + currentInfo.value.ioReadTime = resData.ioReadTime; + currentInfo.value.ioWriteTime = resData.ioWriteTime; + + currentInfo.value.netBytesSent = resData.netBytesSent; + currentInfo.value.netBytesRecv = resData.netBytesRecv; } - currentChartInfo.ioCount = Math.round(Number((res.data.ioCount - currentInfo.value.ioCount) / timeInterval)); - let ioReadTime = res.data.ioReadTime - currentInfo.value.ioReadTime; - let ioWriteTime = res.data.ioWriteTime - currentInfo.value.ioWriteTime; - let ioChoose = ioReadTime > ioWriteTime ? ioReadTime : ioWriteTime; - currentChartInfo.ioTime = Math.round(Number(ioChoose / timeInterval)); - - timeIODatas.value.push(dateFormatForSecond(res.data.shotTime)); - if (timeIODatas.value.length > 20) { - timeIODatas.value.splice(0, 1); + if (scope === 'gpu') { + currentInfo.value.gpuData = resData.gpuData; + currentInfo.value.xpuData = resData.xpuData; } - timeNetDatas.value.push(dateFormatForSecond(res.data.shotTime)); - if (timeNetDatas.value.length > 20) { - timeNetDatas.value.splice(0, 1); + if (scope === 'basic') { + currentInfo.value.uptime = resData.uptime; + currentInfo.value.timeSinceUptime = resData.timeSinceUptime; + currentInfo.value.procs = resData.procs; + + currentInfo.value.load1 = resData.load1; + currentInfo.value.load5 = resData.load5; + currentInfo.value.load15 = resData.load15; + currentInfo.value.loadUsagePercent = resData.loadUsagePercent; + + currentInfo.value.cpuPercent = resData.cpuPercent; + currentInfo.value.cpuUsedPercent = resData.cpuUsedPercent; + currentInfo.value.cpuUsed = resData.cpuUsed; + currentInfo.value.cpuTotal = resData.cpuTotal; + + currentInfo.value.memoryTotal = resData.memoryTotal; + currentInfo.value.memoryAvailable = resData.memoryAvailable; + currentInfo.value.memoryUsed = resData.memoryUsed; + currentInfo.value.memoryUsedPercent = resData.memoryUsedPercent; + + currentInfo.value.swapMemoryTotal = resData.swapMemoryTotal; + currentInfo.value.swapMemoryAvailable = resData.swapMemoryAvailable; + currentInfo.value.swapMemoryUsed = resData.swapMemoryUsed; + currentInfo.value.swapMemoryUsedPercent = resData.swapMemoryUsedPercent; + + currentInfo.value.timeSinceUptime = res.data.timeSinceUptime; + currentInfo.value.shotTime = resData.shotTime; + currentInfo.value.diskData = resData.diskData; } - loadData(); - currentInfo.value = res.data; - statusRef.value.acceptParams(currentInfo.value, baseInfo.value, isStatusInit.value); }; function loadUpTime(uptime: number) { diff --git a/frontend/src/views/home/status/index.vue b/frontend/src/views/home/status/index.vue index 086e712d3865..132b8d2c50f1 100644 --- a/frontend/src/views/home/status/index.vue +++ b/frontend/src/views/home/status/index.vue @@ -159,7 +159,9 @@ /> - {{ computeSize(item.used) }} / {{ computeSize(item.total) }} + + {{ computeSize(item.used) }} / {{ computeSize(item.total) }} +