@@ -114,6 +114,17 @@ type InstanceEvent struct {
114114 Logs string `json:"logs,omitempty"` // 日志内容,仅当Type为log时有效
115115}
116116
117+ // SystemInfo 系统信息结构体
118+ type SystemInfo struct {
119+ CPU int `json:"cpu"` // CPU使用率 (%)
120+ RAM int `json:"ram"` // 内存使用率 (%)
121+ NetRX uint64 `json:"netrx"` // 网络接收字节数
122+ NetTX uint64 `json:"nettx"` // 网络发送字节数
123+ DiskR uint64 `json:"diskr"` // 磁盘读取字节数
124+ DiskW uint64 `json:"diskw"` // 磁盘写入字节数
125+ SysUp uint64 `json:"sysup"` // 系统运行时间(秒)
126+ }
127+
117128// TCPingResult TCPing结果结构体
118129type TCPingResult struct {
119130 Target string `json:"target"`
@@ -653,6 +664,11 @@ func (m *Master) handleInfo(w http.ResponseWriter, r *http.Request) {
653664 "arch" : runtime .GOARCH ,
654665 "cpu" : - 1 ,
655666 "ram" : - 1 ,
667+ "netrx" : uint64 (0 ),
668+ "nettx" : uint64 (0 ),
669+ "diskr" : uint64 (0 ),
670+ "diskw" : uint64 (0 ),
671+ "sysup" : uint64 (0 ),
656672 "ver" : m .version ,
657673 "name" : m .hostname ,
658674 "uptime" : uint64 (time .Since (m .startTime ).Seconds ()),
@@ -663,27 +679,40 @@ func (m *Master) handleInfo(w http.ResponseWriter, r *http.Request) {
663679 }
664680
665681 if runtime .GOOS == "linux" {
666- cpu , ram := getLinuxSysInfo ()
667- info ["cpu" ] = cpu
668- info ["ram" ] = ram
682+ sysInfo := getLinuxSysInfo ()
683+ info ["cpu" ] = sysInfo .CPU
684+ info ["ram" ] = sysInfo .RAM
685+ info ["netrx" ] = sysInfo .NetRX
686+ info ["nettx" ] = sysInfo .NetTX
687+ info ["diskr" ] = sysInfo .DiskR
688+ info ["diskw" ] = sysInfo .DiskW
689+ info ["sysup" ] = sysInfo .SysUp
669690 }
670691
671692 writeJSON (w , http .StatusOK , info )
672693}
673694
674695// getLinuxSysInfo 获取Linux系统信息
675- func getLinuxSysInfo () (cpu , ram int ) {
696+ func getLinuxSysInfo () SystemInfo {
697+ info := SystemInfo {
698+ CPU : - 1 ,
699+ RAM : - 1 ,
700+ NetRX : 0 ,
701+ NetTX : 0 ,
702+ DiskR : 0 ,
703+ DiskW : 0 ,
704+ SysUp : 0 ,
705+ }
706+
676707 if runtime .GOOS != "linux" {
677- return - 1 , - 1
708+ return info
678709 }
679710
680711 // CPU使用率:解析/proc/loadavg
681712 if data , err := os .ReadFile ("/proc/loadavg" ); err == nil {
682713 if fields := strings .Fields (string (data )); len (fields ) > 0 {
683714 if load , err := strconv .ParseFloat (fields [0 ], 64 ); err == nil {
684- cpu = min (int (load * 100 ), 100 )
685- } else {
686- cpu = - 1
715+ info .CPU = min (int (load * 100 ), 100 )
687716 }
688717 }
689718 }
@@ -704,13 +733,64 @@ func getLinuxSysInfo() (cpu, ram int) {
704733 }
705734 }
706735 if memTotal > 0 {
707- ram = min (int ((memTotal - memFree )* 100 / memTotal ), 100 )
708- } else {
709- ram = - 1
736+ info .RAM = min (int ((memTotal - memFree )* 100 / memTotal ), 100 )
737+ }
738+ }
739+
740+ // 网络I/O:解析/proc/net/dev
741+ if data , err := os .ReadFile ("/proc/net/dev" ); err == nil {
742+ for _ , line := range strings .Split (string (data ), "\n " )[2 :] {
743+ if fields := strings .Fields (line ); len (fields ) >= 10 {
744+ ifname := strings .TrimSuffix (fields [0 ], ":" )
745+ // 排除项
746+ if strings .HasPrefix (ifname , "lo" ) || strings .HasPrefix (ifname , "veth" ) ||
747+ strings .HasPrefix (ifname , "docker" ) || strings .HasPrefix (ifname , "podman" ) ||
748+ strings .HasPrefix (ifname , "br-" ) || strings .HasPrefix (ifname , "virbr" ) {
749+ continue
750+ }
751+ if val , err := strconv .ParseUint (fields [1 ], 10 , 64 ); err == nil {
752+ info .NetRX += val
753+ }
754+ if val , err := strconv .ParseUint (fields [9 ], 10 , 64 ); err == nil {
755+ info .NetTX += val
756+ }
757+ }
758+ }
759+ }
760+
761+ // 磁盘I/O:解析/proc/diskstats
762+ if data , err := os .ReadFile ("/proc/diskstats" ); err == nil {
763+ for line := range strings .SplitSeq (string (data ), "\n " ) {
764+ if fields := strings .Fields (line ); len (fields ) >= 14 {
765+ deviceName := fields [2 ]
766+ // 排除项
767+ if strings .Contains (deviceName , "loop" ) || strings .Contains (deviceName , "ram" ) ||
768+ strings .HasPrefix (deviceName , "dm-" ) || strings .HasPrefix (deviceName , "md" ) {
769+ continue
770+ }
771+ if matched , _ := regexp .MatchString (`\d+$` , deviceName ); matched {
772+ continue
773+ }
774+ if val , err := strconv .ParseUint (fields [5 ], 10 , 64 ); err == nil {
775+ info .DiskR += val * 512
776+ }
777+ if val , err := strconv .ParseUint (fields [9 ], 10 , 64 ); err == nil {
778+ info .DiskW += val * 512
779+ }
780+ }
781+ }
782+ }
783+
784+ // 系统运行时间:解析/proc/uptime
785+ if data , err := os .ReadFile ("/proc/uptime" ); err == nil {
786+ if fields := strings .Fields (string (data )); len (fields ) > 0 {
787+ if uptime , err := strconv .ParseFloat (fields [0 ], 64 ); err == nil {
788+ info .SysUp = uint64 (uptime )
789+ }
710790 }
711791 }
712792
713- return cpu , ram
793+ return info
714794}
715795
716796// handleInstances 处理实例集合请求
@@ -1533,9 +1613,14 @@ func generateOpenAPISpec() string {
15331613 "arch": {"type": "string", "description": "System architecture"},
15341614 "cpu": {"type": "integer", "description": "CPU usage percentage"},
15351615 "ram": {"type": "integer", "description": "RAM usage percentage"},
1616+ "netrx": {"type": "integer", "format": "int64", "description": "Network received bytes"},
1617+ "nettx": {"type": "integer", "format": "int64", "description": "Network transmitted bytes"},
1618+ "diskr": {"type": "integer", "format": "int64", "description": "Disk read bytes"},
1619+ "diskw": {"type": "integer", "format": "int64", "description": "Disk write bytes"},
1620+ "sysup": {"type": "integer", "format": "int64", "description": "System uptime in seconds"},
15361621 "ver": {"type": "string", "description": "NodePass version"},
15371622 "name": {"type": "string", "description": "Hostname"},
1538- "uptime": {"type": "integer", "format": "int64", "description": "Uptime in seconds"},
1623+ "uptime": {"type": "integer", "format": "int64", "description": "API uptime in seconds"},
15391624 "log": {"type": "string", "description": "Log level"},
15401625 "tls": {"type": "string", "description": "TLS code"},
15411626 "crt": {"type": "string", "description": "Certificate path"},
0 commit comments