예제 #1
0
func (l *Launchd) Restart(serviceName string) error {
	path := l.resolvePlist(serviceName)
	if path == "" {
		return &ServiceError{l.Name(), serviceName, ErrServiceNotFound}
	}

	cmd := exec.Command("launchctl", "unload", path)
	sout, err := util.SafeRun(cmd)
	if err != nil {
		return &ServiceError{l.Name(), serviceName, err}
	}

	lines, err := util.ReadLines(sout)
	if len(lines) != 0 {
		return &ServiceError{l.Name(), serviceName, errors.New("Unexpected output: " + strings.Join(lines, "\n"))}
	}

	cmd = exec.Command("launchctl", "load", path)
	sout, err = util.SafeRun(cmd)
	if err != nil {
		return &ServiceError{l.Name(), serviceName, err}
	}

	lines, err = util.ReadLines(sout)
	if len(lines) != 0 {
		return &ServiceError{l.Name(), serviceName, errors.New("Unexpected output: " + strings.Join(lines, "\n"))}
	}
	return nil
}
예제 #2
0
func (l *Launchd) LookupService(serviceName string) (*ProcessStatus, error) {
	cmd := exec.Command("launchctl", "list")
	sout, err := util.SafeRun(cmd)
	if err != nil {
		return nil, &ServiceError{l.Name(), serviceName, err}
	}

	lines, err := util.ReadLines(sout)
	if err != nil {
		return nil, &ServiceError{l.Name(), serviceName, err}
	}

	for _, line := range lines {
		if strings.Contains(line, serviceName) {
			util.Debug("launchctl found " + serviceName)
			parts := strings.SplitN(line, "\t", 3)
			pid, err := strconv.ParseInt(parts[0], 10, 32)
			if err != nil {
				return nil, &ServiceError{l.Name(), serviceName, err}
			}

			return &ProcessStatus{int(pid), Up}, nil
		}
	}

	path := l.resolvePlist(serviceName)
	if path != "" {
		return &ProcessStatus{0, Down}, nil
	}

	return nil, &ServiceError{l.Name(), serviceName, ErrServiceNotFound}
}
예제 #3
0
func (s *Systemd) LookupService(serviceName string) (*ProcessStatus, error) {
	var sout []byte
	var err error

	if len(s.dummyOutput) != 0 {
		sout = []byte(s.dummyOutput)
	} else {
		cmd := exec.Command("systemctl", "show", "-p", "MainPID", serviceName)
		sout, err = util.SafeRun(cmd)
	}

	if err != nil {
		return nil, &ServiceError{s.Name(), serviceName, ErrServiceNotFound}
	}
	lines, err := util.ReadLines(sout)
	if len(lines) != 1 {
		return nil, &ServiceError{s.Name(), serviceName, errors.New("Unexpected output: " + strings.Join(lines, "\n"))}
	}

	// Output will be "MainPID=1234" or
	// "MainPID=0" if service does not exist.
	line := lines[0]
	fields := strings.Split(line, "=")
	if fields[1] != "0" {
		pid, err := strconv.ParseInt(fields[1], 10, 32)
		if err != nil {
			return nil, &ServiceError{s.Name(), serviceName, err}
		}
		return &ProcessStatus{int(pid), Up}, nil
	}

	if len(s.dummyOutput2) != 0 {
		sout = []byte(s.dummyOutput2)
	} else {
		cmd := exec.Command("systemctl", "is-enabled", serviceName)
		sout, err = util.SafeRun(cmd)
	}

	if err != nil || string(sout) != "enabled\n" {
		return nil, &ServiceError{s.Name(), serviceName, ErrServiceNotFound}
	}
	return &ProcessStatus{0, Down}, nil
}
예제 #4
0
func (u *Upstart) LookupService(serviceName string) (*ProcessStatus, error) {
	matches, err := filepath.Glob(u.path + "/" + serviceName + ".conf")
	if err != nil {
		return nil, &ServiceError{u.Name(), serviceName, err}
	}

	if len(matches) == 0 {
		return nil, &ServiceError{u.Name(), serviceName, ErrServiceNotFound}
	}

	var sout []byte
	if u.dummyOutput != nil {
		sout = []byte(*u.dummyOutput)
	} else {
		cmd := exec.Command("initctl", "status", serviceName)
		sout, err = util.SafeRun(cmd)
		if err != nil {
			return nil, &ServiceError{u.Name(), serviceName, err}
		}
	}

	lines, err := util.ReadLines(sout)
	if len(lines) != 1 {
		return nil, &ServiceError{u.Name(), serviceName, errors.New("Unexpected output: " + strings.Join(lines, "\n"))}
	}

	// mysql start/running, process 14190
	// sshdgenkeys stop/waiting
	line := lines[0]
	if strings.Contains(line, "Unknown job") {
		return nil, &ServiceError{u.Name(), serviceName, ErrServiceNotFound}
	}

	results := pidScanner.FindStringSubmatch(line)

	if len(results) == 4 && len(results[3]) > 0 {
		pid, err := strconv.ParseInt(results[3], 10, 32)
		if err != nil {
			return nil, &ServiceError{u.Name(), serviceName, err}
		}
		return &ProcessStatus{int(pid), Up}, nil
	}

	if len(results) == 4 {
		switch {
		case results[1] == "start":
			return &ProcessStatus{0, Starting}, nil
		case results[1] == "stop":
			return &ProcessStatus{0, Down}, nil
		}
	}

	return nil, &ServiceError{u.Name(), serviceName, errors.New("Unknown upstart output: " + line)}
}
예제 #5
0
파일: initd.go 프로젝트: rquelle/inspeqtor
func (i *Initd) serviceCommand(serviceName string, command string, timeout time.Duration) error {
	path := i.ctlPath + serviceName
	cmd := exec.Command(path, command)
	_, err := util.SafeRun(cmd, timeout)

	if err != nil {
		return &ServiceError{i.Name(), serviceName, err}
	}

	return nil
}
예제 #6
0
func (s *Systemd) serviceCommand(serviceName string, command string, timeout time.Duration) error {
	if len(s.dummyOutput) == 0 {
		cmd := exec.Command("systemctl", command, serviceName)
		_, err := util.SafeRun(cmd, timeout)
		if err != nil {
			return &ServiceError{s.Name(), serviceName, err}
		}
	}

	return nil
}
예제 #7
0
/*
 * So many hacks in this.  OSX support can be seen as "bad" at best.
 */
func (ps *processStorage) capturePs(pid int) error {
	cmd := exec.Command("ps", "So", "rss,time,utime", "-p", strconv.Itoa(pid))
	sout, err := util.SafeRun(cmd)
	if err != nil {
		return err
	}

	lines, err := util.ReadLines(sout)
	if err != nil {
		return err
	}

	if len(lines) < 2 {
		return errors.New("Insufficient output from ps")
	}

	fields := strings.Fields(lines[1])
	val, err := strconv.ParseInt(fields[0], 10, 64)
	if err != nil {
		return err
	}

	ps.Save("memory", "rss", float64(1024*val))

	times := timeRegexp.FindStringSubmatch(fields[1])
	if times == nil {
		util.Debug("Unable to parse CPU time in " + lines[1])
		return nil
	}
	min, _ := strconv.ParseUint(times[1], 10, 32)
	sec, _ := strconv.ParseUint(times[2], 10, 32)
	cs, _ := strconv.ParseUint(times[3], 10, 32)

	ticks := min*60*100 + sec*100 + cs

	times = timeRegexp.FindStringSubmatch(fields[2])
	if times == nil {
		util.Debug("Unable to parse User time in " + lines[1])
		return nil
	}
	min, _ = strconv.ParseUint(times[1], 10, 32)
	sec, _ = strconv.ParseUint(times[2], 10, 32)
	cs, _ = strconv.ParseUint(times[3], 10, 32)

	uticks := min*60*100 + sec*100 + cs

	ps.Save("cpu", "user", float64(uticks))
	ps.Save("cpu", "system", float64(ticks-uticks))

	return nil
}
예제 #8
0
파일: host.go 프로젝트: rquelle/inspeqtor
func (hs *hostStorage) collectDisk(path string) error {
	var lines []string

	if path == "" {
		cmd := exec.Command("df", "-P")
		sout, err := util.SafeRun(cmd)
		if err != nil {
			return err
		}
		lines, err = util.ReadLines(sout)
		if err != nil {
			return err
		}
	} else {
		data, err := ioutil.ReadFile(path)
		if err != nil {
			return err
		}
		lines, err = util.ReadLines(data)
		if err != nil {
			return err
		}
	}

	usage := map[string]float64{}

	for _, line := range lines {
		if line[0] == '/' {
			items := strings.Fields(line)
			if len(items) < 5 {
				util.Debug("Cannot parse df output: %v", items)
				continue
			}
			pct := items[4]
			if pct[len(pct)-1] == '%' {
				val, err := strconv.ParseInt(pct[0:len(pct)-1], 10, 32)
				if err != nil {
					util.Debug("Cannot parse df output: " + line)
				}
				usage[items[len(items)-1]] = float64(val)
			}

		}
	}

	for name, used := range usage {
		hs.saveType("disk", name, used, Gauge)
	}
	return nil
}
예제 #9
0
파일: host.go 프로젝트: rquelle/inspeqtor
func (hs *hostStorage) collectLoadAverage() error {
	// TODO make this a one-time check so we don't incur the overhead
	// on every cycle.
	ok, err := util.FileExists(hs.path + "/loadavg")
	if err != nil {
		return err
	}

	var loadavgString string
	if ok {
		contentBytes, err := ioutil.ReadFile(hs.path + "/loadavg")
		if err != nil {
			return err
		}
		loadavgString = string(contentBytes)
	} else {
		cmd := exec.Command("sysctl", "-n", "vm.loadavg")
		cmd.Env = []string{"LANG=C"}
		sout, err := util.SafeRun(cmd)
		if err != nil {
			return err
		}
		lines, err := util.ReadLines(sout)
		if err != nil {
			return err
		}
		loadavgString = lines[0][2 : len(lines[0])-2] // trim braces
	}

	slices := strings.Split(loadavgString, " ")
	load1, err := strconv.ParseFloat(slices[0], 64)
	if err != nil {
		return err
	}
	load5, err := strconv.ParseFloat(slices[1], 64)
	if err != nil {
		return err
	}
	load15, err := strconv.ParseFloat(slices[2], 64)
	if err != nil {
		return err
	}

	hs.Save("load", "1", load1)
	hs.Save("load", "5", load5)
	hs.Save("load", "15", load15)
	return nil
}
예제 #10
0
파일: types.go 프로젝트: rquelle/inspeqtor
func execCmd(command string, args []string, stdin []byte) ([]byte, error) {
	cmd := exec.Command(command, args...)
	if stdin != nil {
		in, err := cmd.StdinPipe()
		if err != nil {
			return nil, err
		}
		_, err = in.Write(stdin)
		in.Close()
		if err != nil {
			return nil, err
		}
	}

	return util.SafeRun(cmd)
}
예제 #11
0
func (u *Upstart) serviceCommand(serviceName string, command string, timeout time.Duration, expectedLines int) error {
	var err error
	var sout []byte

	if u.dummyOutput != nil {
		sout = []byte(*u.dummyOutput)
	} else {
		cmd := exec.Command("initctl", command, serviceName)
		sout, err = util.SafeRun(cmd, timeout)
		if err != nil {
			return &ServiceError{u.Name(), serviceName, err}
		}
	}

	lines, err := util.ReadLines(sout)
	if len(lines) != expectedLines {
		return &ServiceError{u.Name(), serviceName, errors.New("Unexpected output: " + strings.Join(lines, "\n"))}
	}
	return nil
}
예제 #12
0
파일: host.go 프로젝트: rquelle/inspeqtor
func (hs *hostStorage) collectMemory() error {
	ok, err := util.FileExists(hs.path + "/meminfo")
	if err != nil {
		return err
	}

	if ok {
		contentBytes, err := ioutil.ReadFile(hs.path + "/meminfo")
		if err != nil {
			return err
		}
		lines := strings.Split(string(contentBytes), "\n")

		memMetrics := make(map[string]float64)
		for _, line := range lines {
			if line == "" {
				continue
			}

			results := meminfoParser.FindStringSubmatch(line)
			if results == nil {
				util.Warn("Unknown input: " + line)
				continue
			}
			val, err := strconv.ParseInt(results[2], 10, 64)
			if err != nil {
				util.Warn("Unexpected input: " + results[2] + " in " + line)
				return err
			}
			memMetrics[results[1]] = float64(val)
		}

		free := memMetrics["SwapFree"]
		total := memMetrics["SwapTotal"]
		if free == 0 {
			hs.Save("swap", "", 100)
		} else if free == total {
			hs.Save("swap", "", 0)
		} else {
			hs.Save("swap", "", float64(100-int8(100*(float64(free)/float64(total)))))
		}
	} else {
		cmd := exec.Command("sysctl", "-n", "vm.swapusage")
		cmd.Env = []string{"LANG=C"}
		sout, err := util.SafeRun(cmd)
		if err != nil {
			return err
		}
		lines, err := util.ReadLines(sout)
		if err != nil {
			return err
		}

		rest := lines[0]
		matches := swapRegexp.FindStringSubmatch(rest)
		total := matches[1]
		rest = matches[2]

		matches = swapRegexp.FindStringSubmatch(rest)
		used := matches[1]

		tot, err := strconv.ParseFloat(total[0:len(total)-1], 64)
		if err != nil {
			return err
		}
		usd, err := strconv.ParseFloat(used[0:len(used)-1], 64)
		if err != nil {
			return err
		}

		t := normalizeSwap(tot, rune(total[len(total)-1]))
		u := normalizeSwap(usd, rune(used[len(used)-1]))
		if t == 0 {
			hs.Save("swap", "", 100)
		} else {
			hs.Save("swap", "", float64(100*(u/t)))
		}
	}

	return nil
}