//get vm info func RunGetVmInfo(repo model.Repo, logger logger.Logger, vmDeviceId uint) (string, error) { vmDevice, err := repo.GetVmDeviceById(vmDeviceId) if err != nil { return "", err } device, err := repo.GetDeviceById(vmDevice.DeviceID) if err != nil { return "", err } var cmdFormat = `LANG=C virsh --connect qemu+ssh://root@%s/system dominfo %s` var cmd = fmt.Sprintf(cmdFormat, device.Ip, vmDevice.Hostname) logger.Debugf("get vm info:%s", cmd) var runResult = "执行脚本:\n" + cmd bytes, err := util.ExecScript(cmd) logger.Debugf("result:%s", string(bytes)) runResult += "\n\n" + "执行结果:\n" + string(bytes) if err != nil { logger.Errorf("error:%s", err.Error()) runResult += "\n\n" + "错误信息:\n" + err.Error() return "", errors.New(runResult) } return string(bytes), nil }
func GetMetric(params interface{}, log *logger.Logger) interface{} { difference := make(map[string]uint64) device := params.(string) device_type := getDeviceType(device) new_metrics := initLastMetrics(device) metrics, err := getDiskMetrics(device, device_type) if new_metrics { log.Log("debug", "New metrics, sending zeroes") } if err != nil { log.Log("crit", fmt.Sprintf("%s", err)) } for metric, value := range metrics { if new_metrics { difference[metric] = 0 } else { difference[metric] = value - readMetric(device, metric) if int64(value-readMetric(device, metric)) < 0 { difference[metric] = 0 } } writeMetric(device, metric, value) } return difference }
func readUnixSocket(path string, log *logger.Logger) interface{} { fi, err := os.Stat(path) if err != nil && os.IsNotExist(err) { log.Log("crit", "Could not locate unix socket for json_poll at path: "+path) return nil } if fi.Mode()&os.ModeSocket != os.ModeSocket { log.Log("crit", path+" is not a unix socket for json_poll") return nil } client := &http.Client{ Transport: &http.Transport{ Dial: func(network, addr string) (net.Conn, error) { return net.Dial("unix", path) }, }, } req, _ := http.NewRequest("GET", "http://localhost", nil) req.Close = true return doRequest(req, client, log) }
// NewRepo 创建mysql数据实现实例 func NewRepo(conf *config.Config, log logger.Logger) (*MySQLRepo, error) { var connection string if conf.Repo.ConnectionIsCrypted != "" { str, err := util.RSADecrypt(conf.Rsa.PrivateKey, conf.Repo.ConnectionIsCrypted) if err != nil { return nil, err } connection = str } else if conf.Repo.Connection != "" { connection = conf.Repo.Connection } if connection == "" { return nil, errors.New("请先配置好数据库连接信息!") } db, err := gorm.Open("mysql", connection) if err != nil { log.Errorf("database connection failed:%s", err.Error()) return nil, err } db.LogMode(true) repo := &MySQLRepo{ conf: conf, log: log, db: &db, } return repo, nil }
//get vm pool info func RunGetVmHostPoolInfo(repo model.Repo, logger logger.Logger, conf *config.Config, deviceId uint) (string, error) { device, err := repo.GetDeviceById(deviceId) if err != nil { return "", err } storage := conf.Vm.Storage if storage == "" { storage = "guest_images_lvm" } var cmdFormat = `LANG=C virsh --connect qemu+ssh://root@%s/system pool-info %s` var cmd = fmt.Sprintf(cmdFormat, device.Ip, storage) logger.Debugf("get vm host pool info:%s", cmd) var runResult = "执行脚本:\n" + cmd bytes, err := util.ExecScript(cmd) logger.Debugf("result:%s", string(bytes)) runResult += "\n\n" + "执行结果:\n" + string(bytes) if err != nil { logger.Errorf("error:%s", err.Error()) runResult += "\n\n" + "错误信息:\n" + err.Error() return "", errors.New(runResult) } return string(bytes), nil }
func GetMetric(params interface{}, log *logger.Logger) interface{} { var loadavg [3]C.double log.Log("debug", "Calling getloadavg()") C.getloadavg(&loadavg[0], 3) return loadavg }
func GetMetric(params interface{}, log *logger.Logger) interface{} { res, err := gm.ProcessMemoryUsage(params.(string)) if err != nil { log.Log("crit", err.Error()) return nil } return res }
func GetMetric(params interface{}, log *logger.Logger) interface{} { result, err := gm.MemoryUsage() if err != nil { log.Log("crit", err.Error()) return nil } return result }
func GetMetric(params interface{}, log *logger.Logger) interface{} { results, err := ioUsage.Metric(params.(string)) if err != nil { log.Log("crit", err.Error()) return nil } return results }
func readURL(url string, log *logger.Logger) interface{} { req, err := http.NewRequest("GET", url, nil) req.Close = true if err != nil { log.Log("crit", fmt.Sprintf("URL '%s' is malformed: %s", url, err.Error())) return nil } return doRequest(req, &http.Client{}, log) }
func Start(listen string, config types.CirconusConfig, log *logger.Logger) error { go query.ResultPoller(config, log) log.Log("info", "Starting Web Service") s := &http.Server{ Addr: listen, Handler: &WebHandler{Config: config, Logger: log}, } return s.ListenAndServe() }
func ResultPoller(config types.CirconusConfig, log *logger.Logger) { log.Log("info", "Starting Result Poller") interval_duration := time.Second * time.Duration(config.PollInterval) for { start := time.Now() AllPlugins(config, log) duration := time.Now().Sub(start) if duration < interval_duration { time.Sleep(interval_duration - duration) } } }
func AllPlugins(config types.CirconusConfig, log *logger.Logger) { rwmutex.Lock() defer rwmutex.Unlock() if pluginResults == nil { pluginResults = make(types.PluginResultCollection) } log.Log("debug", "Querying All Plugins") for key, _ := range config.Plugins { pluginResults[key] = Plugin(key, config, log) } log.Log("debug", "Done Querying All Plugins") }
func Plugin(name string, config types.CirconusConfig, log *logger.Logger) types.PluginResult { log.Log("debug", fmt.Sprintf("Plugin %s Requested", name)) item, ok := config.Plugins[name] if ok { t, ok := types.Plugins[item.Type] if ok { log.Log("debug", fmt.Sprintf("Plugin %s exists, running", name)) return t(item.Params, log) } } return nil }
func getJiffies(log *logger.Logger) (jiffies int64, cpus int64) { content, err := ioutil.ReadFile("/proc/stat") if err != nil { log.Log("crit", fmt.Sprintf("While processing the cpu_usage package: %s")) return 0, 0 } lines := strings.Split(string(content), "\n") for _, line := range lines { if strings.Index(line, "cpu ") == 0 { /* cpu with no number is the aggregate of all of them -- this is what we * want to parse */ parts := strings.Split(line, " ") /* 2 - 11 are the time aggregates */ for x := 2; x <= 11; x++ { /* 5 is the idle time, which we don't want */ if x == 5 { continue } /* integer all the things */ part, err := strconv.Atoi(parts[x]) if err != nil { log.Log("crit", fmt.Sprintf("Could not convert integer from string while processing cpu_usage: %s", parts[x])) return 0, 0 } jiffies += int64(part) } } else if strings.Index(line, "cpu") == 0 { /* cpu with a number is the specific time -- cheat and use this for the * processor count since we've already read it */ cpus++ } } return jiffies, cpus }
//delete noVNC token file func RunDeleteVmNoVncTokenFile(repo model.Repo, logger logger.Logger, vmDeviceId uint) error { vmDevice, err := repo.GetVmDeviceById(vmDeviceId) if err != nil { return err } var dir = "/etc/cloudboot-server/novnc-tokens" var file = vmDevice.Hostname logger.Debugf("delete vm novnc token file:%s", dir+"/"+file) if util.FileExist(dir + "/" + file) { err := os.Remove(dir + "/" + file) if err != nil { logger.Errorf("error:%s", err.Error()) return err } } return nil }
//create noVNC token file func RunCreateVmNoVncTokenFile(repo model.Repo, logger logger.Logger, vmDeviceId uint) error { vmDevice, err := repo.GetVmDeviceById(vmDeviceId) if err != nil { return err } device, err := repo.GetDeviceById(vmDevice.DeviceID) if err != nil { return err } var newHostname = strings.Replace(vmDevice.Hostname, ":", "_", -1) var strFormat = `%s: %s:%s` var str = fmt.Sprintf(strFormat, newHostname, device.Ip, vmDevice.VncPort) var dir = "/etc/cloudboot-server/novnc-tokens" var file = vmDevice.Hostname if !util.FileExist(dir) { err := os.MkdirAll(dir, 0777) if err != nil { return err } } //文件已存在,先删除 if util.FileExist(dir + "/" + file) { err := os.Remove(dir + "/" + file) if err != nil { return err } } logger.Debugf("create vm novnc token file %s:%s", dir+"/"+file, str) bytes := []byte(str) errCreate := ioutil.WriteFile(dir+"/"+file, bytes, 0644) if errCreate != nil { logger.Errorf("error:%s", errCreate.Error()) return errCreate } return nil }
//test connect vm host func RunTestConnectVmHost(repo model.Repo, logger logger.Logger, deviceId uint) (string, error) { device, err := repo.GetDeviceById(deviceId) if err != nil { return "", err } var cmdFormat = `LANG=C ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=3 root@%s 'w'` var cmd = fmt.Sprintf(cmdFormat, device.Ip) logger.Debugf("test connect vm host:%s", cmd) var runResult = "执行脚本:\n" + cmd bytes, err := util.ExecScript(cmd) logger.Debugf("result:%s", string(bytes)) runResult += "\n\n" + "执行结果:\n" + string(bytes) if err != nil { logger.Errorf("error:%s", err.Error()) runResult += "\n\n" + "错误信息:\n" + err.Error() return "", errors.New(runResult) } return string(bytes), nil }
func GetMetric(params interface{}, log *logger.Logger) interface{} { total := uint(0) page_size := uint(C.get_pgsz()) for _, pid := range util.GetPids(params.(string), log) { path := "/proc/" + pid + "/statm" f, err := os.Open(path) if err != nil { log.Log("crit", "Could not open "+path+": "+err.Error()) return nil } defer f.Close() content, err := ioutil.ReadAll(f) if err != nil { log.Log("crit", "Could not read from "+path+": "+err.Error()) return nil } parts := strings.Split(string(content), " ") mem, err := strconv.Atoi(parts[1]) if err != nil { log.Log("crit", "Trouble converting resident size "+parts[1]+" to integer: "+err.Error()) return nil } total += uint(mem) * page_size } return total }
func GetCidrInfo(network string, logger logger.Logger) (map[string]string, error) { network = strings.TrimSpace(network) result := make(map[string]string) list := strings.Split(network, "/") if len(list) != 2 { return result, errors.New("网段格式不正确") } isValidate, err := regexp.MatchString("^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)$", list[0]) if err != nil { return result, err } if !isValidate { return result, errors.New("IP格式不正确") } logger.Debugf("get network info:%s", network) minIp, maxIp := GetCidrIpRange(network) logger.Debugf("get ip range:%s~%s", minIp, maxIp) result["MinIP"] = minIp result["MaxIP"] = maxIp mask, err := strconv.Atoi(list[1]) if err != nil { return result, err } logger.Debugf("get mask:%d", mask) if mask <= 0 || mask >= 32 { logger.Error("掩码位不正确!") return result, errors.New("掩码位不正确!") } result["Mask"] = GetCidrIpMask(mask) result["IPNum"] = fmt.Sprintf("%d", GetCidrHostNum(mask)) logger.Debugf("ip nums:%s", result["IPNum"]) return result, nil }
func doRequest(req *http.Request, client *http.Client, log *logger.Logger) interface{} { var json_out interface{} resp, err := client.Do(req) defer resp.Body.Close() if err != nil { log.Log("crit", fmt.Sprintf("Could not contact resource at URL '%s': %s", req.URL.String(), err.Error())) return nil } out, err := ioutil.ReadAll(resp.Body) if err != nil { log.Log("crit", fmt.Sprintf("Error while gathering output from URL '%s': %s", req.URL.String(), err.Error())) return nil } err = json.Unmarshal(out, &json_out) if err != nil { log.Log("crit", fmt.Sprintf("Error while marshalling content: %s: %s", string(out), err.Error())) return nil } return json_out }
func GetMetric(params interface{}, log *logger.Logger) interface{} { path := C.CString(params.(string)) stat := C.go_statvfs(path) readonly := C.go_fs_readonly(path) log.Log("debug", fmt.Sprintf("blocks size on %s: %v", string(*path), stat.f_bsize)) log.Log("debug", fmt.Sprintf("blocks total on %s: %v", string(*path), stat.f_blocks)) log.Log("debug", fmt.Sprintf("blocks free on %s: %v", string(*path), stat.f_bavail)) defer C.free(unsafe.Pointer(stat)) defer C.free(unsafe.Pointer(path)) blocks := uint64(stat.f_blocks) avail := uint64(stat.f_bavail) free := float64(0) if avail != 0 { free = math.Ceil(((float64(blocks) - float64(avail)) / float64(blocks)) * 100) } return [4]interface{}{ free, avail * uint64(stat.f_frsize), blocks * uint64(stat.f_frsize), readonly == 1, } }
func GetMetric(params interface{}, log *logger.Logger) interface{} { array_params := params.([]interface{}) command := make([]string, len(array_params)) var json_out interface{} for i, param := range array_params { command[i] = param.(string) } log.Log("debug", fmt.Sprintf("Command executing: %v", command)) cmd := exec.Command(command[0], command[1:]...) out, err := cmd.Output() if err != nil { log.Log("crit", fmt.Sprintf("Error while gathering output for command `%s`: %s", command, err)) return nil } err = json.Unmarshal(out, &json_out) if err != nil { log.Log("crit", fmt.Sprintf("Error while marshalling content: %s", string(out))) return nil } return json_out }
func GetMetric(params interface{}, log *logger.Logger) interface{} { new_metrics := false device := params.(string) if last_metrics == nil { rwmutex.Lock() last_metrics = make(map[string]map[string]uint64) rwmutex.Unlock() new_metrics = true } if last_metrics[device] == nil { rwmutex.Lock() last_metrics[device] = make(map[string]uint64) rwmutex.Unlock() new_metrics = true } if new_metrics { log.Log("debug", "New instance, sending zeroes") } metrics := make(map[string]uint64) difference := make(map[string]uint64) base_path := fmt.Sprintf(file_pattern, device) for fn, metric := range file_map { log.Log("debug", fmt.Sprintf("Reading file: %s", fn)) result, err := readFile(base_path, fn) log.Log("debug", fmt.Sprintf("Got result: %s", result)) if err == nil { metrics[metric] = result } else { metrics[metric] = 0 } } for metric, value := range metrics { if new_metrics { difference[metric] = 0 rwmutex.Lock() last_metrics[device][metric] = value rwmutex.Unlock() } else { rwmutex.RLock() difference[metric] = value - last_metrics[device][metric] rwmutex.RUnlock() rwmutex.Lock() last_metrics[device][metric] = value rwmutex.Unlock() } } return difference }
func GetMetric(params interface{}, log *logger.Logger) interface{} { log.Log("debug", "Reading /proc/meminfo") content, err := ioutil.ReadFile("/proc/meminfo") var total, buffers, cached, free, swap_total, swap_free int if err != nil { log.Log("crit", fmt.Sprintf("While processing the mem_usage package: %s", err)) return map[string]interface{}{} } lines := strings.Split(string(content), "\n") for _, line := range lines { parts := strings.Split(line, " ") id := len(parts) - 2 switch parts[0] { case "MemTotal:": total, err = strconv.Atoi(parts[id]) case "MemFree:": free, err = strconv.Atoi(parts[id]) case "Cached:": cached, err = strconv.Atoi(parts[id]) case "Buffers:": buffers, err = strconv.Atoi(parts[id]) case "SwapTotal:": swap_total, err = strconv.Atoi(parts[id]) case "SwapFree:": swap_free, err = strconv.Atoi(parts[id]) } if err != nil { log.Log("crit", fmt.Sprintf("Could not convert integer from string while processing cpu_usage: %s", parts[id])) return map[string]interface{}{} } } return map[string]interface{}{ "Total": total * 1024, "Free": (buffers + cached + free) * 1024, "Used": total*1024 - ((buffers + cached + free) * 1024), "Swap Total": swap_total * 1024, "Swap Free": swap_free * 1024, } }
func GetMetric(params interface{}, log *logger.Logger) interface{} { sock_type := params.(string) found_sock_type := false for _, val := range SOCK_TYPES { if sock_type == val { found_sock_type = true break } } if !found_sock_type { log.Log("crit", "Invalid socket type: "+sock_type) return nil } f, err := os.Open("/proc/self/net/" + sock_type) if err != nil { log.Log("crit", "Could not open socket information for "+sock_type+": "+err.Error()) return nil } defer f.Close() content, err := ioutil.ReadAll(f) if err != nil { log.Log("crit", "Trouble reading socket information for type "+sock_type+": "+err.Error()) return nil } lines := strings.Split(string(content), "\n") return len(lines) - 1 // there's a one line header in these files }
func GetPids(process string, log *logger.Logger) []string { pids := []string{} dir, err := os.Open("/proc") if err != nil { log.Log("crit", "Could not open /proc for reading: "+err.Error()) return nil } defer dir.Close() proc_files, err := dir.Readdirnames(0) if err != nil { log.Log("crit", "Could not read directory names from /proc: "+err.Error()) return nil } all_pids := []string{} // XXX totally cheating here -- the only all-numeric filenames in this dir // will be pid directories. This should be faster than 4 bajillion stat // calls (that I'd have to do this to anyway). for _, fn := range proc_files { _, err := strconv.Atoi(fn) if err == nil { all_pids = append(all_pids, fn) } } for _, pid := range all_pids { path := "/proc/" + pid + "/cmdline" file, err := os.Open(path) if err != nil { log.Log("crit", "Could not open "+path+": "+err.Error()) return nil } defer file.Close() cmdline, err := ioutil.ReadAll(file) if err != nil { log.Log("crit", "Could not read from "+path+": "+err.Error()) return nil } cmdline_parts := strings.Split(string(cmdline), "\x00") if len(cmdline_parts) > 1 { cmdline_parts = cmdline_parts[0 : len(cmdline_parts)-1] } string_cmd := strings.Join(cmdline_parts, " ") if string_cmd == process { pids = append(pids, pid) } } return pids }