package main import ( "fmt" "github.com/gocarina/gocsv" "io" "log" "net" "net/http" "os" "strconv" "strings" "time" ) func main() { monitorsFile, err := os.OpenFile(OUTPUTFILE, os.O_RDWR|os.O_CREATE, os.ModePerm) if err != nil { panic(err) } defer monitorsFile.Close() monitors := []*Monitor{} hosts, err := GetHostListFromCSV() if err != nil { fmt.Println(err) } totalHosts := len(hosts) count := 0 log.Println("本次要处理主机数量: ", totalHosts) for _, host := range hosts { fmt.Println(host) var errorflag string serverIP := strClean(host.IP) if !isTCPOpen(serverIP, host.Port) { count += 1 log.Println(count, "/", totalHosts, "端口不通: ", serverIP, host.Port) continue } cpuCore, cpuUsage, err1 := getCPUInfo(serverIP, host.Port) memTotal, memUsage, err2 := getMemoryInfo(serverIP, host.Port) nodeLoad1, nodeLoad5, nodeLoad15, err3 := getLoadInfo(serverIP, host.Port) if err1 != nil || err2 != nil || err3 != nil { fmt.Println("host error: ", err) errorflag = "error" } monitors = append(monitors, &Monitor{ IP: serverIP, Port: host.Port, CPUCore: cpuCore, CPUUsage: cpuUsage, MemTotal: memTotal, MemUsage: memUsage, NodeLoad1: nodeLoad1, NodeLoad5: nodeLoad5, NodeLoad15: nodeLoad15, ERROR: errorflag, }) count += 1 log.Println(count, "/", totalHosts, " handled: ", serverIP) } err = gocsv.MarshalFile(&monitors, monitorsFile) // Use this to save the CSV back to the file if err != nil { panic(err) } } func getMetrics(ip, port string) (string, error) { // 发送HTTP请求获取Node Exporter的metrics数据 address := "http://" + ip + ":" + port + "/metrics" response, err := http.Get(address) if err != nil { log.Println("无法发送HTTP请求:", err) //log.Fatal("无法发送HTTP请求:", err) return "", err } defer response.Body.Close() // 读取响应内容 body, err := io.ReadAll(response.Body) if err != nil { log.Println("无法读取响应内容:", err) //log.Fatal("无法读取响应内容:", err) return "", err } return string(body), nil } // 从指标行中提取指标值,并将其转换为浮点数类型 func extractMetricValue(value string) (float64, error) { // 去除指标值的单位(此处假设单位为'count') value = strings.Split(value, " ")[0] // 将指标值转换为浮点数类型并返回 return parseFloat(value) } // 将字符串转换为浮点数类型,并处理可能的错误情况 func parseFloat(value string) (float64, error) { f, err := strconv.ParseFloat(value, 64) if err != nil { return 0, err } return f, nil } func strClean(str string) string { str = strings.ReplaceAll(str, " ", "") str = strings.ReplaceAll(str, ",", "") str = strings.ReplaceAll(str, "\"", "") return str } func isTCPOpen(ip, port string) bool { // 尝试在指定端口上建立连接 address := ip + ":" + port conn, err := net.DialTimeout("tcp", address, time.Millisecond*10) if err != nil { return false } defer conn.Close() return true }