Exemple #1
0
// freeMemOrSwap is an abstraction of freeMemory and freeSwap, which measures
// if the desired resource has a quantity free above the amount specified
func freeMemOrSwap(input string, swapOrMem string) (exitCode int, exitMessage string) {
	// get numbers and units
	units := wrkutils.GetByteUnits(input)
	re := regexp.MustCompile(`\d+`)
	amountString := re.FindString(input)
	// report errors
	if amountString == "" {
		log.WithFields(log.Fields{
			"input":  input,
			"regexp": re.String(),
		}).Fatal("Configuration error: couldn't extract number from string")
	} else if units == "" {
		log.WithFields(log.Fields{
			"input": input,
		}).Fatal("Configuration error: couldn't extract byte units from string")
	}
	amount := wrkutils.ParseMyInt(amountString)
	actualAmount := getSwapOrMemory("free", swapOrMem, units)
	if actualAmount > amount {
		return 0, ""
	}
	msg := "Free " + swapOrMem + " lower than defined threshold"
	actualString := fmt.Sprint(actualAmount) + units
	return wrkutils.GenericError(msg, input, []string{actualString})

}
Exemple #2
0
// swapUsage checks to see whether or not the system has a swap usage
// percentage below a certain threshold
func swapUsage(parameters []string) (exitCode int, exitMessage string) {
	maxPercentUsed := wrkutils.ParseMyInt(parameters[0])
	actualPercentUsed := getUsedPercent("swap")
	if actualPercentUsed < float32(maxPercentUsed) {
		return 0, ""
	}
	msg := "Swap usage above defined maximum"
	slc := []string{fmt.Sprint(actualPercentUsed)}
	return wrkutils.GenericError(msg, fmt.Sprint(maxPercentUsed), slc)
}
Exemple #3
0
// temp parses the output of lm_sensors and determines if Core 0 (all cores) are
// over a certain threshold as specified in the JSON.
func temp(parameters []string) (exitCode int, exitMessage string) {
	// TODO: check for negative, outrageously high temperatures
	// allCoreTemps returns the temperature of each core
	allCoreTemps := func() (temps []int) {
		cmd := exec.Command("sensors")
		out, err := cmd.CombinedOutput()
		outstr := string(out)
		wrkutils.ExecError(cmd, outstr, err)
		restr := `Core\s\d+:\s+[\+\-](?P<temp>\d+)\.*\d*°C`
		re := regexp.MustCompile(restr)
		for _, line := range regexp.MustCompile(`\n+`).Split(outstr, -1) {
			if re.MatchString(line) {
				// submatch captures only the integer part of the temperature
				matchDict := wrkutils.SubmatchMap(re, line)
				if _, ok := matchDict["temp"]; !ok {
					log.WithFields(log.Fields{
						"regexp":    re.String(),
						"matchDict": matchDict,
						"output":    outstr,
					}).Fatal("Couldn't find any temperatures in `sensors` output")
				}
				tempInt64, err := strconv.ParseInt(matchDict["temp"], 10, 64)
				if err != nil {
					log.WithFields(log.Fields{
						"regexp":    re.String(),
						"matchDict": matchDict,
						"output":    outstr,
						"error":     err.Error(),
					}).Fatal("Couldn't parse integer from `sensors` output")
				}
				temps = append(temps, int(tempInt64))
			}
		}
		return temps
	}
	// getCoreTemp returns an integer temperature for a certain core
	getCoreTemp := func(core int) (temp int) {
		temps := allCoreTemps()
		wrkutils.IndexError("No such core available", core, temps)
		return temps[core]
	}
	max := wrkutils.ParseMyInt(parameters[0])
	temp := getCoreTemp(0)
	if temp < max {
		return 0, ""
	}
	msg := "Core temp exceeds defined maximum"
	return wrkutils.GenericError(msg, max, []string{fmt.Sprint(temp)})
}
// groupID checks to see if a group of a certain name has a given integer id
func groupID(parameters []string) (exitCode int, exitMessage string) {
	name := parameters[0]
	id := wrkutils.ParseMyInt(parameters[1])
	groups := getGroups()
	for _, g := range groups {
		if g.Name == name {
			if g.ID == id {
				return 0, ""
			}
			msg := "Group does not have expected ID"
			return wrkutils.GenericError(msg, fmt.Sprint(id), []string{fmt.Sprint(g.ID)})
		}
	}
	return groupNotFound(name)
}
Exemple #5
0
// cpuUsage checks to see whether or not CPU usage is below a certain %.
func cpuUsage(parameters []string) (exitCode int, exitMessage string) {
	// TODO check that parameters are in range 0 < x < 100
	cpuPercentUsed := func(sampleTime time.Duration) float32 {
		idle0, total0 := getCPUSample()
		time.Sleep(sampleTime)
		idle1, total1 := getCPUSample()
		idleTicks := float32(idle1 - idle0)
		totalTicks := float32(total1 - total0)
		return (100 * (totalTicks - idleTicks) / totalTicks)
	}
	maxPercentUsed := wrkutils.ParseMyInt(parameters[0])
	actualPercentUsed := cpuPercentUsed(3 * time.Second)
	if actualPercentUsed < float32(maxPercentUsed) {
		return 0, ""
	}
	msg := "CPU usage above defined maximum"
	slc := []string{fmt.Sprint(actualPercentUsed)}
	return wrkutils.GenericError(msg, fmt.Sprint(maxPercentUsed), slc)
}
Exemple #6
0
func diskUsage(parameters []string) (exitCode int, exitMessage string) {
	// percentFSUsed gets the percent of the filesystem that is occupied
	percentFSUsed := func(path string) int {
		// get FS info (*nix systems only!)
		var stat syscall.Statfs_t
		syscall.Statfs(path, &stat)

		// blocks * size of block = available size
		totalBytes := stat.Blocks * uint64(stat.Bsize)
		availableBytes := stat.Bavail * uint64(stat.Bsize)
		usedBytes := totalBytes - availableBytes
		percentUsed := int((float64(usedBytes) / float64(totalBytes)) * 100)
		return percentUsed

	}
	maxPercentUsed := wrkutils.ParseMyInt(parameters[1])
	actualPercentUsed := percentFSUsed(parameters[0])
	if actualPercentUsed < maxPercentUsed {
		return 0, ""
	}
	msg := "More disk space used than expected"
	slc := []string{fmt.Sprint(actualPercentUsed) + "%"}
	return wrkutils.GenericError(msg, fmt.Sprint(maxPercentUsed)+"%", slc)
}
Exemple #7
0
// port parses /proc/net/tcp to determine if a given port is in an open state
// and returns an error if it is not.
func port(parameters []string) (exitCode int, exitMessage string) {
	// getHexPorts gets all open ports as hex strings from /proc/net/tcp
	getHexPorts := func() (ports []string) {
		paths := [2]string{"/proc/net/tcp", "/proc/net/udp"}
		for _, path := range paths {
			data := wrkutils.FileToString(path)
			table := tabular.ProbabalisticSplit(data)
			// TODO by header isn't working
			//localAddresses := tabular.GetColumnByHeader("local_address", table)
			localAddresses := tabular.GetAllNoHeader(table)
			portRe := regexp.MustCompile(`([0-9A-F]{8}):([0-9A-F]{4})`)
			for _, address := range localAddresses {
				port := portRe.FindString(address)
				if port != "" {
					if len(port) < 10 {
						log.WithFields(log.Fields{
							"port":   port,
							"length": len(port),
						}).Fatal("Couldn't parse port number in " + path)
					}
					portString := string(port[9:])
					ports = append(ports, portString)
				}
			}
		}
		return ports
	}

	// strHexToDecimal converts from string containing hex number to int
	strHexToDecimal := func(hex string) int {
		portInt, err := strconv.ParseInt(hex, 16, 64)
		if err != nil {
			log.WithFields(log.Fields{
				"number": hex,
				"error":  err.Error(),
			}).Fatal("Couldn't parse hex number")
		}
		return int(portInt)
	}

	// getOpenPorts gets a list of open/listening ports as integers
	getOpenPorts := func() (ports []int) {
		for _, port := range getHexPorts() {
			ports = append(ports, strHexToDecimal(port))
		}
		return ports
	}

	// TODO check if it is in a valid range
	port := wrkutils.ParseMyInt(parameters[0])
	open := getOpenPorts()
	for _, p := range open {
		if p == port {
			return 0, ""
		}
	}
	// convert ports to string to send to wrkutils.GenericError
	var strPorts []string
	for _, port := range open {
		strPorts = append(strPorts, fmt.Sprint(port))
	}
	return wrkutils.GenericError("Port not open", fmt.Sprint(port), strPorts)
}