diff --git a/backend/app/dto/container.go b/backend/app/dto/container.go index 20045b946..f9974d50e 100644 --- a/backend/app/dto/container.go +++ b/backend/app/dto/container.go @@ -63,8 +63,16 @@ type ContainerUpgrade struct { } type ContainerListStats struct { - ContainerID string `json:"containerID"` + ContainerID string `json:"containerID"` + + CPUTotalUsage uint64 `json:"cpuTotalUsage"` + SystemUsage uint64 `json:"systemUsage"` CPUPercent float64 `json:"cpuPercent"` + PercpuUsage int `json:"percpuUsage"` + + MemroyCache uint64 `json:"memoryCache"` + MemoryUsage uint64 `json:"memoryUsage"` + MemoryLimit uint64 `json:"memoryLimit"` MemoryPercent float64 `json:"memoryPercent"` } diff --git a/backend/app/service/container.go b/backend/app/service/container.go index f9400bb32..c21f5e62a 100644 --- a/backend/app/service/container.go +++ b/backend/app/service/container.go @@ -208,8 +208,7 @@ func (u *ContainerService) ContainerListStats() ([]dto.ContainerListStats, error wg.Add(len(list)) for i := 0; i < len(list); i++ { go func(item types.Container) { - cpu, mem := loadCpuAndMem(client, item.ID) - datas = append(datas, dto.ContainerListStats{CPUPercent: cpu, MemoryPercent: mem, ContainerID: item.ID}) + datas = append(datas, loadCpuAndMem(client, item.ID)) wg.Done() }(list[i]) } @@ -766,26 +765,36 @@ func pullImages(ctx context.Context, client *client.Client, image string) error return nil } -func loadCpuAndMem(client *client.Client, container string) (float64, float64) { +func loadCpuAndMem(client *client.Client, container string) dto.ContainerListStats { + data := dto.ContainerListStats{ + ContainerID: container, + } res, err := client.ContainerStats(context.Background(), container, false) if err != nil { - return 0, 0 + return data } body, err := io.ReadAll(res.Body) if err != nil { res.Body.Close() - return 0, 0 + return data } res.Body.Close() var stats *types.StatsJSON if err := json.Unmarshal(body, &stats); err != nil { - return 0, 0 + return data } - CPUPercent := calculateCPUPercentUnix(stats) - MemPercent := calculateMemPercentUnix(stats.MemoryStats) - return CPUPercent, MemPercent + data.CPUTotalUsage = stats.CPUStats.CPUUsage.TotalUsage - stats.PreCPUStats.CPUUsage.TotalUsage + data.SystemUsage = stats.CPUStats.SystemUsage - stats.PreCPUStats.SystemUsage + data.CPUPercent = calculateCPUPercentUnix(stats) + data.PercpuUsage = len(stats.CPUStats.CPUUsage.PercpuUsage) + + data.MemroyCache = stats.MemoryStats.Stats["cache"] + data.MemoryUsage = stats.MemoryStats.Usage + data.MemoryLimit = stats.MemoryStats.Limit + data.MemoryPercent = calculateMemPercentUnix(stats.MemoryStats) + return data } func checkPortStats(ports []dto.PortHelper) (nat.PortMap, error) { diff --git a/frontend/src/api/interface/container.ts b/frontend/src/api/interface/container.ts index 787e63fad..8e1b37821 100644 --- a/frontend/src/api/interface/container.ts +++ b/frontend/src/api/interface/container.ts @@ -70,7 +70,13 @@ export namespace Container { } export interface ContainerListStats { containerID: string; + cpuTotalUsage: number; + systemUsage: number; cpuPercent: number; + percpuUsage: number; + memoryCache: number; + memoryUsage: number; + memoryLimit: number; memoryPercent: number; } export interface ContainerStats { diff --git a/frontend/src/assets/iconfont/iconfont.css b/frontend/src/assets/iconfont/iconfont.css index 447ddad71..4ec831599 100644 --- a/frontend/src/assets/iconfont/iconfont.css +++ b/frontend/src/assets/iconfont/iconfont.css @@ -1,9 +1,9 @@ @font-face { font-family: "panel"; /* Project id 3575356 */ - src: url('iconfont.woff2?t=1687338712846') format('woff2'), - url('iconfont.woff?t=1687338712846') format('woff'), - url('iconfont.ttf?t=1687338712846') format('truetype'), - url('iconfont.svg?t=1687338712846#panel') format('svg'); + src: url('iconfont.woff2?t=1695287081776') format('woff2'), + url('iconfont.woff?t=1695287081776') format('woff'), + url('iconfont.ttf?t=1695287081776') format('truetype'), + url('iconfont.svg?t=1695287081776#panel') format('svg'); } .panel { @@ -14,6 +14,10 @@ -moz-osx-font-smoothing: grayscale; } +.p-xiangqing:before { + content: "\e677"; +} + .p-onedrive:before { content: "\e601"; } diff --git a/frontend/src/assets/iconfont/iconfont.js b/frontend/src/assets/iconfont/iconfont.js index ccdf3fa1c..7442e9db6 100644 --- a/frontend/src/assets/iconfont/iconfont.js +++ b/frontend/src/assets/iconfont/iconfont.js @@ -1 +1 @@ -window._iconfont_svg_string_3575356='',function(c){var l=(l=document.getElementsByTagName("script"))[l.length-1],h=l.getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var a,t,v,p,i,z=function(l,h){h.parentNode.insertBefore(l,h)};if(h&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}a=function(){var l,h=document.createElement("div");h.innerHTML=c._iconfont_svg_string_3575356,(h=h.getElementsByTagName("svg")[0])&&(h.setAttribute("aria-hidden","true"),h.style.position="absolute",h.style.width=0,h.style.height=0,h.style.overflow="hidden",h=h,(l=document.body).firstChild?z(h,l.firstChild):l.appendChild(h))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(a,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),a()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(v=a,p=c.document,i=!1,o(),p.onreadystatechange=function(){"complete"==p.readyState&&(p.onreadystatechange=null,m())})}function m(){i||(i=!0,v())}function o(){try{p.documentElement.doScroll("left")}catch(l){return void setTimeout(o,50)}m()}}(window); \ No newline at end of file +window._iconfont_svg_string_3575356='',function(c){var l=(l=document.getElementsByTagName("script"))[l.length-1],h=l.getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var a,t,v,p,i,z=function(l,h){h.parentNode.insertBefore(l,h)};if(h&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}a=function(){var l,h=document.createElement("div");h.innerHTML=c._iconfont_svg_string_3575356,(h=h.getElementsByTagName("svg")[0])&&(h.setAttribute("aria-hidden","true"),h.style.position="absolute",h.style.width=0,h.style.height=0,h.style.overflow="hidden",h=h,(l=document.body).firstChild?z(h,l.firstChild):l.appendChild(h))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(a,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),a()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(v=a,p=c.document,i=!1,o(),p.onreadystatechange=function(){"complete"==p.readyState&&(p.onreadystatechange=null,m())})}function m(){i||(i=!0,v())}function o(){try{p.documentElement.doScroll("left")}catch(l){return void setTimeout(o,50)}m()}}(window); \ No newline at end of file diff --git a/frontend/src/assets/iconfont/iconfont.json b/frontend/src/assets/iconfont/iconfont.json index 951ee1a03..e729e5a2c 100644 --- a/frontend/src/assets/iconfont/iconfont.json +++ b/frontend/src/assets/iconfont/iconfont.json @@ -5,6 +5,13 @@ "css_prefix_text": "p-", "description": "", "glyphs": [ + { + "icon_id": "10293150", + "name": "详情", + "font_class": "xiangqing", + "unicode": "e677", + "unicode_decimal": 58999 + }, { "icon_id": "13015332", "name": "onedrive", diff --git a/frontend/src/assets/iconfont/iconfont.svg b/frontend/src/assets/iconfont/iconfont.svg index 9b44b1eff..c32e34650 100644 --- a/frontend/src/assets/iconfont/iconfont.svg +++ b/frontend/src/assets/iconfont/iconfont.svg @@ -14,6 +14,8 @@ /> + + diff --git a/frontend/src/assets/iconfont/iconfont.ttf b/frontend/src/assets/iconfont/iconfont.ttf index 32cd9a78e..7766786e1 100644 Binary files a/frontend/src/assets/iconfont/iconfont.ttf and b/frontend/src/assets/iconfont/iconfont.ttf differ diff --git a/frontend/src/assets/iconfont/iconfont.woff b/frontend/src/assets/iconfont/iconfont.woff index 40a4e87d0..6b8503536 100644 Binary files a/frontend/src/assets/iconfont/iconfont.woff and b/frontend/src/assets/iconfont/iconfont.woff differ diff --git a/frontend/src/assets/iconfont/iconfont.woff2 b/frontend/src/assets/iconfont/iconfont.woff2 index a4de294df..e0cb84fdf 100644 Binary files a/frontend/src/assets/iconfont/iconfont.woff2 and b/frontend/src/assets/iconfont/iconfont.woff2 differ diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index ec380a47f..feffd004d 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -525,6 +525,12 @@ const message = { 'Clearing logs requires restarting the container, and this operation cannot be rolled back. Do you want to continue?', newName: 'New name', source: 'Resource rate', + cpuUsage: 'CPU Usage', + cpuTotal: 'CPU Total', + core: 'Core', + memUsage: 'Memory Usage', + memTotal: 'Memory Limit', + memCache: 'Memory Cache', ip: 'IP address', cpuShare: 'CPU Share', cpuShareHelper: diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index c491d4d6d..b791f3e53 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -511,6 +511,12 @@ const message = { cleanLogHelper: '清空日誌需要重啟容器,該操作無法回滾,是否繼續?', newName: '新名稱', source: '資源使用率', + cpuUsage: 'CPU 使用', + cpuTotal: 'CPU 總計', + core: '核心數', + memUsage: '內存使用', + memTotal: '內存限額', + memCache: '緩存使用', ip: 'IP 地址', cpuShare: 'CPU 權重', cpuShareHelper: '容器默認份額為 1024 個 CPU,增大可使當前容器獲得更多的 CPU 時間', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index c28794110..37265758a 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -511,6 +511,12 @@ const message = { cleanLogHelper: '清空日志需要重启容器,该操作无法回滚,是否继续?', newName: '新名称', source: '资源使用率', + cpuUsage: 'CPU 使用', + cpuTotal: 'CPU 总计', + core: '核心数', + memUsage: '内存使用', + memTotal: '内存限额', + memCache: '缓存使用', ip: 'IP 地址', cpuShare: 'CPU 权重', cpuShareHelper: '容器默认份额为 1024 个 CPU,增大可使当前容器获得更多的 CPU 时间', diff --git a/frontend/src/views/container/container/index.vue b/frontend/src/views/container/container/index.vue index 4a8966b10..ff9577715 100644 --- a/frontend/src/views/container/container/index.vue +++ b/frontend/src/views/container/container/index.vue @@ -92,9 +92,69 @@