You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
3.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
}