package collector import ( "bytes" "fmt" "strconv" "golang.org/x/crypto/ssh" ) // SSHCollector SSH采集器 type SSHCollector struct { client *ssh.Client } // SSHConfig SSH连接配置 type SSHConfig struct { Host string Port int Username string Password string KeyPath string } // NewSSHCollector 创建新的SSH采集器 func NewSSHCollector(cfg *SSHConfig) (*SSHCollector, error) { // 构建SSH客户端配置 sshConfig := &ssh.ClientConfig{ User: cfg.Username, Auth: []ssh.AuthMethod{}, HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 生产环境中应该使用更安全的HostKeyCallback } // 添加认证方式 if cfg.Password != "" { sshConfig.Auth = append(sshConfig.Auth, ssh.Password(cfg.Password)) } // 连接SSH服务器 addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port) client, err := ssh.Dial("tcp", addr, sshConfig) if err != nil { return nil, err } return &SSHCollector{ client: client, }, nil } // Close 关闭SSH连接 func (c *SSHCollector) Close() error { return c.client.Close() } // executeCommand 执行SSH命令 func (c *SSHCollector) executeCommand(cmd string) (string, error) { // 创建SSH会话 session, err := c.client.NewSession() if err != nil { return "", err } defer session.Close() // 执行命令并获取输出 var stdout bytes.Buffer session.Stdout = &stdout if err := session.Run(cmd); err != nil { return "", err } return stdout.String(), nil } // GetCPUUsage 获取CPU使用率 func (c *SSHCollector) GetCPUUsage() (float64, error) { // 使用top命令获取CPU使用率 cmd := "top -bn1 | grep 'Cpu(s)' | awk '{print $2 + $4}'" output, err := c.executeCommand(cmd) if err != nil { return 0, err } // 解析输出 usage, err := strconv.ParseFloat(output, 64) if err != nil { return 0, err } return usage, nil } // GetMemoryUsage 获取内存使用率 func (c *SSHCollector) GetMemoryUsage() (float64, error) { // 使用free命令获取内存使用情况 cmd := "free | grep Mem | awk '{print ($3/$2)*100}'" output, err := c.executeCommand(cmd) if err != nil { return 0, err } // 解析输出 usage, err := strconv.ParseFloat(output, 64) if err != nil { return 0, err } return usage, nil } // GetDiskUsage 获取磁盘使用率 func (c *SSHCollector) GetDiskUsage(partition string) (float64, error) { // 使用df命令获取磁盘使用情况 cmd := fmt.Sprintf("df -h %s | tail -1 | awk '{print $5}' | sed 's/%%//'", partition) output, err := c.executeCommand(cmd) if err != nil { return 0, err } // 解析输出 usage, err := strconv.ParseFloat(output, 64) if err != nil { return 0, err } return usage, nil }