mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-13 00:54:53 +08:00
feat: enhance system_info tool with uptime, cpu model and load avg
This commit is contained in:
@@ -9,7 +9,7 @@ import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type SystemInfoTool struct {}
|
||||
type SystemInfoTool struct{}
|
||||
|
||||
func NewSystemInfoTool() *SystemInfoTool {
|
||||
return &SystemInfoTool{}
|
||||
@@ -20,25 +20,48 @@ func (t *SystemInfoTool) Name() string {
|
||||
}
|
||||
|
||||
func (t *SystemInfoTool) Description() string {
|
||||
return "Get current system status (CPU, RAM, Disk)."
|
||||
return "Get current system status (CPU, RAM, Disk, Uptime)."
|
||||
}
|
||||
|
||||
func (t *SystemInfoTool) Parameters() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"type": "object",
|
||||
"type": "object",
|
||||
"properties": map[string]interface{}{},
|
||||
}
|
||||
}
|
||||
|
||||
func (t *SystemInfoTool) Execute(ctx context.Context, args map[string]interface{}) (string, error) {
|
||||
info := fmt.Sprintf("System Info:\n")
|
||||
info += fmt.Sprintf("OS: %s %s\n", runtime.GOOS, runtime.GOARCH)
|
||||
var sb strings.Builder
|
||||
sb.WriteString("System Info:\n")
|
||||
sb.WriteString(fmt.Sprintf("OS: %s %s\n", runtime.GOOS, runtime.GOARCH))
|
||||
|
||||
// Uptime
|
||||
if data, err := os.ReadFile("/proc/uptime"); err == nil {
|
||||
var up, idle float64
|
||||
fmt.Sscanf(string(data), "%f %f", &up, &idle)
|
||||
days := int(up / 86400)
|
||||
hours := int(up) % 86400 / 3600
|
||||
mins := int(up) % 3600 / 60
|
||||
sb.WriteString(fmt.Sprintf("Uptime: %dd %dh %dm\n", days, hours, mins))
|
||||
}
|
||||
|
||||
// Load Average
|
||||
if data, err := os.ReadFile("/proc/loadavg"); err == nil {
|
||||
info += fmt.Sprintf("Load Avg: %s", string(data))
|
||||
} else {
|
||||
info += "Load Avg: N/A\n"
|
||||
sb.WriteString(fmt.Sprintf("Load Avg: %s", string(data)))
|
||||
}
|
||||
|
||||
// CPU Model
|
||||
if data, err := os.ReadFile("/proc/cpuinfo"); err == nil {
|
||||
lines := strings.Split(string(data), "\n")
|
||||
for _, line := range lines {
|
||||
if strings.HasPrefix(line, "model name") {
|
||||
parts := strings.SplitN(line, ":", 2)
|
||||
if len(parts) > 1 {
|
||||
sb.WriteString(fmt.Sprintf("CPU: %s\n", strings.TrimSpace(parts[1])))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RAM from /proc/meminfo
|
||||
@@ -55,31 +78,25 @@ func (t *SystemInfoTool) Execute(ctx context.Context, args map[string]interface{
|
||||
}
|
||||
}
|
||||
if total > 0 {
|
||||
// fallback if Available not present (older kernels)
|
||||
if available == 0 {
|
||||
available = free // very rough approximation
|
||||
available = free
|
||||
}
|
||||
used := total - available
|
||||
info += fmt.Sprintf("RAM: Used %.2f GB / Total %.2f GB (%.2f%%)\n",
|
||||
float64(used)/1024/1024, float64(total)/1024/1024, float64(used)/float64(total)*100)
|
||||
sb.WriteString(fmt.Sprintf("RAM: Used %.2f GB / Total %.2f GB (%.2f%%)\n",
|
||||
float64(used)/1024/1024, float64(total)/1024/1024, float64(used)/float64(total)*100))
|
||||
}
|
||||
} else {
|
||||
info += "RAM: N/A\n"
|
||||
}
|
||||
|
||||
// Disk usage for /
|
||||
var stat syscall.Statfs_t
|
||||
if err := syscall.Statfs("/", &stat); err == nil {
|
||||
// Cast to uint64 to avoid overflow/type mismatch
|
||||
bsize := uint64(stat.Bsize)
|
||||
total := stat.Blocks * bsize
|
||||
free := stat.Bfree * bsize
|
||||
used := total - free
|
||||
info += fmt.Sprintf("Disk (/): Used %.2f GB / Total %.2f GB (%.2f%%)\n",
|
||||
float64(used)/1024/1024/1024, float64(total)/1024/1024/1024, float64(used)/float64(total)*100)
|
||||
} else {
|
||||
info += "Disk: N/A\n"
|
||||
sb.WriteString(fmt.Sprintf("Disk (/): Used %.2f GB / Total %.2f GB (%.2f%%)\n",
|
||||
float64(used)/1024/1024/1024, float64(total)/1024/1024/1024, float64(used)/float64(total)*100))
|
||||
}
|
||||
|
||||
return info, nil
|
||||
return sb.String(), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user