小花狸監控之Redis

壹頁書發表於2015-03-19
小花狸監控Redis和主機的狀態

監控主機狀態的程式碼
$GOPATH/src/probe/module/Host.go

package module

import (
    "io/ioutil"
    "net"
    "os/exec"
    "strconv"
    "strings"
    "syscall"
    "time"
)

type Disk struct {
    Name string `json:name`
    All  uint64 `json:all`
    Used uint64 `json:used`
    Free uint64 `json:free`
}

func (this *Disk) DiskUsage() {
    fs := syscall.Statfs_t{}
    err := syscall.Statfs(this.Name, &fs)
    if err != nil {
        this.All = 0
        this.Free = 0
        this.Used = 0
    }
    this.All = fs.Blocks * uint64(fs.Bsize)
    this.Free = fs.Bavail * uint64(fs.Bsize)
    this.Used = this.All - fs.Bfree*uint64(fs.Bsize)
}

type Memory struct {
    AllMemory  uint64 `json:allmemory`
    UsedMemory uint64 `json:usedmemory`
    FreeMemory uint64 `json:freememory`
}

func (this *Memory) MemoryUsage() {
    cmd := exec.Command("/bin/bash", "-c", `free -m | awk 'NR==3 {print $3"TAB"$4}'`)
    stdout, _ := cmd.StdoutPipe()
    cmd.Start()
    bytes, _ := ioutil.ReadAll(stdout)
    data := strings.Split(string(bytes), "TAB")
    this.UsedMemory, _ = strconv.ParseUint(data[0], 10, 64)
    this.FreeMemory, _ = strconv.ParseUint(strings.Trim(data[1], "\n"), 10, 64)
    this.AllMemory = this.UsedMemory + this.FreeMemory
}

type Host struct {
    Ip     string
    Root   Disk `json:root`
    Data   Disk `json:data`
    Dbdata Disk `json:dbdata`
    Memory
    Cpu
    Ts time.Time `json:ts`
}

func getHostAddr() (hostAddr string) {
    addrs, _ := net.InterfaceAddrs()
    for _, addr := range addrs {
        ip := addr.String()
        if !strings.HasPrefix(ip, "127") && !strings.HasPrefix(ip, "192") && !strings.HasSuffix(ip, "128") && !strings.HasSuffix(ip, "64") {
            return ip[0:strings.LastIndex(ip, "/")]
        }
    }
    return "127.0.0.1"
}

func (this *Host) HostUsage() {
    this.Ip = getHostAddr()
    this.MemoryUsage()
    this.Root.DiskUsage()
    this.Data.DiskUsage()
    this.Dbdata.DiskUsage()
    this.Cpu.CpuUsage()
}


type Cpu struct {
    CpuIdle float64
}

func (this *Cpu) CpuUsage() {
    cmd := exec.Command("/bin/bash", "-c", `top -b -n 1 | grep Cpu | awk -F"," '{print $4}' | sed 's/%id//g;s/^ //g'`)
    stdout, _ := cmd.StdoutPipe()
    cmd.Start()
    bytes, _ := ioutil.ReadAll(stdout)
    cpuidle, _ := strconv.ParseFloat(strings.Trim(string(bytes), "\n"), 64)
    this.CpuIdle = cpuidle
}

func NewHost(host *Host) {
    host.Root = Disk{Name: "/"}
    host.Data = Disk{Name: "/data"}
    host.Dbdata = Disk{Name: "/dbdata"}
    host.Ts = time.Now()
    host.HostUsage()
}

監控Redis的程式碼
$GOLANG/src/probe/module/Redis.go

透過反射的方式,監控Redis資訊

package module

import (
    "github.com/garyburd/redigo/redis"
    "io/ioutil"
    "os/exec"
    "reflect"
    "strconv"
    "strings"
    "time"
)

type RedisInfo struct {
    Port                       string
    Connected_clients          int64
    Blocked_clients            int64
    Used_memory                int64
    Role                       string
    Instantaneous_ops_per_sec  int64
    Rejected_connections       int64
    Master_host                string
    Master_port                int64
    Master_link_status         string
    Master_last_io_seconds_ago int64
    Connected_slaves           int64
    Cpu_ratio                  float64
    Master0                    string
    Host                       Host
}

func GetRedisInfo(port string, password string) (redisinfo *RedisInfo) {
    r := &RedisInfo{}
    NewHost(&r.Host)
    r.Port = port
    ref := reflect.ValueOf(r)
    conn, _ := redis.DialTimeout("tcp", ":"+port, 0, 1*time.Second, 1*time.Second)
    conn.Do("AUTH", password)
    defer conn.Close()
    info, _ := redis.String(conn.Do("info"))
    data := strings.Split(info, "\n")
    for _, v := range data {
        if !strings.HasPrefix(v, "#") && !strings.HasPrefix(v, "\r") && strings.Contains(v, ":") {
            result := strings.Split(v, ":")
            field := ref.Elem().FieldByName(strings.Title(result[0]))
            if field.IsValid() {
                switch field.Kind() {
                case reflect.Int64:
                    val, _ := strconv.ParseInt(strings.Trim(result[1], "\r"), 10, 64)
                    field.SetInt(val)
                case reflect.String:
                    field.SetString(strings.Trim(result[1], "\r"))
                }
            }
        }
    }
    r.Cpu_ratio = getCpuInfo(port)
    return r
}


func getCpuInfo(port string) float64 {
    cmd := exec.Command("/bin/bash", "-c", `top -b -n 1 -p $(ps -ef | grep  -w "redis-server\ \*:`+port+`" | awk '{print $2}') | awk '/redis-server/{print $9}' | sed 's/\r//g'`)
    stdout, _ := cmd.StdoutPipe()
    cmd.Start()
    bytes, _ := ioutil.ReadAll(stdout)
    cpuinfo, _ := strconv.ParseFloat(strings.Trim(string(bytes), "\n"), 64)
    return cpuinfo
}


呼叫$GOPATH/src/main.go
package main

import (
    "encoding/json"
    "log"
    "probe/module"
)

func main() {
    r := module.GetRedisInfo("30000", "")
    result, _ := json.Marshal(*r)
    log.Println(string(result))
}

結果
{
    "Port": "30000", 
    "Connected_clients": 3, 
    "Blocked_clients": 0, 
    "Used_memory": 852208, 
    "Role": "master", 
    "Instantaneous_ops_per_sec": 0, 
    "Rejected_connections": 0, 
    "Master_host": "", 
    "Master_port": 0, 
    "Master_link_status": "", 
    "Master_last_io_seconds_ago": 0, 
    "Connected_slaves": 0, 
    "Cpu_ratio": 0, 
    "Master0": "", 
    "Host": {
        "Ip": "172.16.1.78", 
        "Root": {
            "Name": "/", 
            "All": 50519138304, 
            "Used": 6745673728, 
            "Free": 41207181312
        }, 
        "Data": {
            "Name": "/data", 
            "All": 50519138304, 
            "Used": 6745673728, 
            "Free": 41207181312
        }, 
        "Dbdata": {
            "Name": "/dbdata", 
            "All": 0, 
            "Used": 0, 
            "Free": 0
        }, 
        "AllMemory": 7872, 
        "UsedMemory": 947, 
        "FreeMemory": 6925, 
        "CpuIdle": 99.9, 
        "Ts": "2015-03-19T19:08:23.780288023+08:00"
    }
}

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1466480/,如需轉載,請註明出處,否則將追究法律責任。

相關文章