コード例 #1
0
ファイル: initd.go プロジェクト: rquelle/inspeqtor
func detectInitd(root string) (InitSystem, error) {
	ctlpath := root + "etc/init.d/"
	result, err := util.FileExists(ctlpath)
	if err != nil {
		return nil, err
	}

	if !result {
		util.Debug("init.d not detected in " + ctlpath)
		return nil, nil
	}

	matches, err := filepath.Glob(ctlpath + "*")
	if err != nil {
		return nil, err
	}

	if !result {
		util.Debug("init.d not detected in " + ctlpath)
		return nil, nil
	}

	if len(matches) > 0 {
		util.Info("Detected init.d in " + ctlpath)
		return &Initd{ctlpath, root + "var/run/", pidForString}, nil
	}

	util.Info(ctlpath + " exists but appears to be empty")
	return nil, nil
}
コード例 #2
0
ファイル: initd.go プロジェクト: rquelle/inspeqtor
func (i *Initd) LookupService(serviceName string) (*ProcessStatus, error) {
	path := i.ctlPath + serviceName
	result, _ := util.FileExists(path)
	if !result {
		// service script does not exist in etc/init.d, not under
		// init.d control
		return nil, &ServiceError{i.Name(), serviceName, ErrServiceNotFound}
	}

	// First try to find the PID file with same name in /var/run.
	paths := []string{
		i.varrunPath + serviceName + ".pid",
		i.varrunPath + serviceName + "/" + serviceName + ".pid",
	}

	for _, pidpath := range paths {
		st, err := i.readPidFile(pidpath)
		if err != nil {
			util.Info("Error processing PID file %s: %s", pidpath, err.Error())
			continue
		} else if st != nil {
			return st, nil
		} else {
			util.Info("No such pidfile %s", pidpath)
		}
	}

	return &ProcessStatus{0, Down}, nil
}
コード例 #3
0
ファイル: licensing.go プロジェクト: jmptrader/inspeqtor-pro
func verifyLicense(path string) (*License, error) {
	result, err := util.FileExists(path + "/license.bin")
	if err != nil {
		return nil, err
	}

	/*
		  I am Alice.  I have a public/private key.  I generate and encrypt the
			license with my private key and Bob's public key.
		  Bob's private key can decrypt the license.
			You cannot generate a license file unless you have Alice's private key.
	*/
	alicepub := [32]byte{
		0x2c, 0x6b, 0xe8, 0x2e, 0x1f, 0x62, 0x4a, 0x43, 0xe6, 0xd1, 0x69, 0xbc,
		0x11, 0x4c, 0x05, 0x6f, 0xa4, 0xcd, 0x34, 0x8f, 0x9d, 0xdf, 0x07, 0x59,
		0x82, 0x3f, 0x8a, 0x50, 0xcd, 0x20, 0x1e, 0x13,
	}
	bobprv := [32]byte{
		0x97, 0x95, 0xd6, 0xf1, 0xce, 0xf3, 0xb8, 0xf9, 0x05, 0x47, 0x6b, 0xb0,
		0x69, 0x39, 0xad, 0xa5, 0xb3, 0x43, 0xcf, 0xf1, 0x8d, 0x32, 0xeb, 0x04,
		0xc6, 0x6e, 0x64, 0x73, 0x62, 0xd8, 0x3f, 0x1b,
	}
	nonce := [24]byte{
		0x5e, 0xf8, 0x3d, 0xad, 0x43, 0x54, 0x2a, 0xe7, 0x8e, 0x13, 0x6c, 0xd7,
		0x84, 0xd6, 0xc9, 0x61, 0xd6, 0x69, 0xc3, 0xcd, 0x1f, 0xd7, 0x8e, 0xbd,
	}

	if !result {
		fmt.Println("Unlicensed, non-production use only!  Purchase at http://contribsys.com/inspeqtor")
		return &License{}, nil
	}

	enc, err := ioutil.ReadFile(path + "/license.bin")
	if err != nil {
		return nil, err
	}

	dec, ok := box.Open(nil, enc, &nonce, &alicepub, &bobprv)
	if !ok {
		return nil, errors.New("Invalid license file")
	}

	newdoc := &License{}
	err = json.Unmarshal(dec, newdoc)
	if err != nil {
		return nil, errors.New("Corrupt license file?")
	}

	if newdoc.HostLimit > 0 {
		fmt.Printf("Licensed to %s for up to %d hosts\n", newdoc.Org, newdoc.HostLimit)
	} else {
		fmt.Printf("Licensed to %s, unlimited hosts\n", newdoc.Org)
	}
	fmt.Println("")

	return newdoc, nil
}
コード例 #4
0
ファイル: global_parser.go プロジェクト: rquelle/inspeqtor
func ParseGlobal(rootDir string) (*ConfigFile, error) {
	path := rootDir + "/inspeqtor.conf"
	exists, err := util.FileExists(path)
	if err != nil {
		return nil, err
	}

	if exists {
		util.Debug("Parsing " + path)
		data, err := ioutil.ReadFile(path)
		if err != nil {
			return nil, err
		}

		s := lexer.NewLexer([]byte(data))
		p := parser.NewParser()
		obj, err := p.Parse(s)
		if err != nil {
			return nil, err
		}
		ast := obj.(ast.Config)

		config := ConfigFile{Defaults, map[string]*AlertRoute{}}

		config.Variables = ast.Variables
		if val, has := ast.Variables["log_level"]; has {
			util.SetLogLevel(val)
		}
		parseValue(ast, &config.CycleTime, "cycle_time", 15)
		parseValue(ast, &config.DeployLength, "deploy_length", 300)
		parseValue(ast, &config.ExposePort, "expose_port", 4677)

		for _, v := range ast.Routes {
			ar, err := ValidateChannel(v.Name, v.Channel, v.Config)
			if err != nil {
				return nil, err
			}
			if _, ok := config.AlertRoutes[v.Name]; ok {
				return nil, fmt.Errorf("Duplicate alert config for '%s'", v.Name)
			}
			config.AlertRoutes[v.Name] = ar
		}
		return &config, nil
	}

	util.Info("No configuration file found at " + rootDir + "/inspector.conf")
	return &ConfigFile{Defaults, nil}, nil
}
コード例 #5
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
}
コード例 #6
0
ファイル: process.go プロジェクト: rquelle/inspeqtor
func (ps *processStorage) Collect(pid int) error {
	var err error

	ok, err := util.FileExists(ps.path)
	if err != nil {
		return err
	}

	if !ok {
		// we don't have the /proc filesystem, e.g. darwin or freebsd
		// use `ps` output instead.
		err = ps.capturePs(pid)
		if err != nil {
			return err
		}
	} else {
		err = ps.captureVM(pid)
		if err != nil {
			return err
		}

		err = ps.captureCPU(pid)
		if err != nil {
			return err
		}
	}

	for _, fn := range ps.dyncol {
		err = fn(pid, ps)
		if err != nil {
			return err
		}
	}

	for _, x := range ps.daemonSpecific {
		data, err := x.Capture()
		if err != nil {
			return err
		}
		for k, v := range data {
			ps.Save(x.Name(), k, v)
		}
	}
	return nil
}
コード例 #7
0
ファイル: host.go プロジェクト: rquelle/inspeqtor
func (hs *hostStorage) collectCPU() error {
	ok, err := util.FileExists(hs.path + "/stat")
	if err != nil {
		return err
	}

	if ok {
		contents, err := ioutil.ReadFile(hs.path + "/stat")
		if err != nil {
			return err
		}

		lines := strings.Split(string(contents), "\n")
		line := lines[0]
		fields := strings.Fields(line)

		user, _ := strconv.ParseInt(fields[1], 10, 64)
		nice, _ := strconv.ParseInt(fields[2], 10, 64)
		system, _ := strconv.ParseInt(fields[3], 10, 64)
		iowait, _ := strconv.ParseInt(fields[5], 10, 64)
		irq, _ := strconv.ParseInt(fields[6], 10, 64)
		softIrq, _ := strconv.ParseInt(fields[7], 10, 64)
		steal, _ := strconv.ParseInt(fields[8], 10, 64)
		total := user + nice + system + iowait + irq + softIrq + steal

		// These are the five I can envision writing rules against.
		// Open an issue if you want access to the other values.
		hs.Save("cpu", "", float64(total))
		hs.Save("cpu", "user", float64(user))
		hs.Save("cpu", "system", float64(system))
		hs.Save("cpu", "iowait", float64(iowait))
		hs.Save("cpu", "steal", float64(steal))
	} else {
		// TODO
		util.Info("Cannot collect host CPU metrics, not implemented on this platform")
	}
	return nil
}
コード例 #8
0
ファイル: inq_parser.go プロジェクト: rquelle/inspeqtor
/*
Parses the host-specific rules in /etc/inspeqtor/host.inq
*/
func ParseHost(global *ConfigFile, hostInq string) (*Host, error) {
	var host *Host

	result, err := util.FileExists(hostInq)
	if err != nil {
		return nil, err
	}
	if !result {
		return nil, fmt.Errorf("Missing required file: %s", hostInq)
	}

	util.DebugDebug("Parsing " + hostInq)
	data, err := ioutil.ReadFile(hostInq)
	if err != nil {
		return nil, err
	}

	s := lexer.NewLexer([]byte(data))
	p := parser.NewParser()
	obj, err := p.Parse(s)
	if err != nil {
		return nil, err
	}

	switch x := obj.(type) {
	case *ast.HostCheck:
		host, err = BuildHost(global, x)
		if err != nil {
			return nil, err
		}
		util.DebugDebug("Host: %+v", *host)
	default:
		return nil, fmt.Errorf("Invalid host.inq configuration file")
	}

	return host, nil
}
コード例 #9
0
ファイル: upstart.go プロジェクト: rquelle/inspeqtor
func detectUpstart(path string) (InitSystem, error) {
	result, err := util.FileExists(path)
	if err != nil {
		return nil, err
	}

	if !result {
		util.Debug("upstart not detected, no " + path)
		return nil, nil
	}

	matches, err := filepath.Glob(path + "/*.conf")
	if err != nil {
		return nil, err
	}

	if len(matches) > 0 {
		util.Info("Detected upstart in " + path)
		return &Upstart{path, nil}, nil
	}

	util.Debug("upstart not detected, empty " + path)
	return nil, nil
}
コード例 #10
0
ファイル: mysql.go プロジェクト: rquelle/inspeqtor
func (rs *mysqlSource) buildArgs() []string {
	args := []string{"-B"}
	socket := false

	if rs.Socket != "" {
		result, err := util.FileExists(rs.Socket)
		if result && err == nil {
			socket = true
		}
	}

	if socket {
		args = append(args, "-S")
		args = append(args, rs.Socket)
	} else {
		if rs.Hostname != "" {
			args = append(args, "-h")
			args = append(args, rs.Hostname)
		}
		if rs.Port != "" {
			args = append(args, "-P")
			args = append(args, rs.Port)
		}
	}

	if rs.Username != "" {
		args = append(args, "-u")
		args = append(args, rs.Username)
	}
	if rs.Password != "" {
		args = append(args, "-p")
		args = append(args, rs.Password)
	}

	return args
}
コード例 #11
0
ファイル: initd.go プロジェクト: rquelle/inspeqtor
func (i *Initd) readPidFile(path string) (*ProcessStatus, error) {
	result, err := util.FileExists(path)
	if err != nil {
		return nil, err
	}
	if !result {
		return nil, nil
	}
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	pid, err := i.pidParser(data)
	if err != nil {
		return nil, err
	}

	err = syscall.Kill(pid, syscall.Signal(0))
	if err != nil {
		return nil, err
	}
	return &ProcessStatus{pid, Up}, nil
}
コード例 #12
0
ファイル: systemd.go プロジェクト: rquelle/inspeqtor
func detectSystemd(path string) (InitSystem, error) {
	result, err := util.FileExists(path)
	if err != nil {
		return nil, err
	}

	if !result {
		util.Debug("systemd not detected, no " + path)
		return nil, nil
	}

	matches, err := filepath.Glob(path + "/*.conf")
	if err != nil {
		return nil, err
	}

	if len(matches) > 0 {
		util.Info("Detected systemd in " + path)
		return &Systemd{path, "", ""}, nil
	}

	util.Debug("systemd not detected, empty " + path)
	return nil, nil
}
コード例 #13
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
}