因为服务器比较多,以前都是喜欢用perl写程序,后来发现部署的时候还要安装perl环境,实在太麻烦了,所以改用go编程,把go编译发后,复制到服务器就可以运行,还真的挻方便的。
之前已经用go写了一个mysql 主从同步,检查从服务器是否出错的程序,如果同步出错就可以在zabbix里警告了,把mysql密码写到程序里,再编译,这样比脚本语言要安全很多,而且不用添加一个用户。
原因是这样的,有很多服务器,有很大一部分是普通硬盘,普通硬盘就很容易出问题,因为服务器上面没有办法做badblock 检查(太耗IO资源了),但是检查S.M.A.R.T状态可以提前预知硬盘故障,还是有点用,好过没有,对吧。
程序是基于linux的,window 改改也能用,主要是先检查/dev/sda…b…c…d 循环检查系统有多少个硬盘,再检查状态,如果程序返回1 则正常,程序返回0 表示有硬盘出问题了。
package main import ( "bytes" "flag" "fmt" "log" "os" "os/exec" "strings" ) func PathExists(path string) (bool, error) { _, err := os.Stat(path) if err == nil { return true, nil } if os.IsNotExist(err) { return false, nil } return false, err } func smartctl(dev string, debug int) int { path, err := exec.LookPath("smartctl") if err != nil { log.Fatal(err) } cmd := exec.Command(path, "-H", dev) var out bytes.Buffer cmd.Stdout = &out err = cmd.Run() if err != nil { log.Fatal(err) } //fmt.Printf("%s\n", out.String()) if strings.Contains(out.String(), "OK") || strings.Contains(out.String(), "PASSED") { if debug == 1 { fmt.Printf("%s test ok\n", dev) } return 1 } return 0 } func main() { debug := flag.Int("debug", 0, "to debug -debug 1 ") flag.Parse() for _, drive := range "abcd" { //dev:=fmt.Sprintf("/dev/sd%s",drive) dev := "/dev/sd" + string(drive) //fmt.Println(dev) if ok, _ := PathExists(dev); ok { mystat := smartctl(dev, *debug) if mystat ==0 { fmt.Print(0) os.Exit(-1) } } } fmt.Print(1) }