예제 #1
0
func checkConnection(args []string) *checkers.Checker {
	opts := connectionOpts{}
	psr := flags.NewParser(&opts, flags.Default)
	psr.Usage = "connection [OPTIONS]"
	_, err := psr.ParseArgs(args)
	if err != nil {
		os.Exit(1)
	}

	db, err := sql.Open(opts.getDriverAndDataSourceName())
	if err != nil {
		return checkers.Unknown(err.Error())
	}
	defer db.Close()

	statActivityCount := 0
	err = db.QueryRow("SELECT COUNT(*) AS cnt FROM pg_stat_activity").Scan(&statActivityCount)
	if err != nil {
		return checkers.Unknown(err.Error())
	}

	checkSt := checkers.OK
	msg := fmt.Sprintf("%d connections", statActivityCount)
	if statActivityCount > opts.Crit {
		checkSt = checkers.CRITICAL
	} else if statActivityCount > opts.Warn {
		checkSt = checkers.WARNING
	}
	return checkers.NewChecker(checkSt, msg)
}
예제 #2
0
func checkConnection(args []string) *checkers.Checker {
	opts := connectionOpts{}
	psr := flags.NewParser(&opts, flags.Default)
	psr.Usage = "connection [OPTIONS]"
	_, err := psr.ParseArgs(args)
	if err != nil {
		os.Exit(1)
	}
	db := newMySQL(opts.mysqlSetting)
	err = db.Connect()
	if err != nil {
		return checkers.Unknown("couldn't connect DB")
	}
	defer db.Close()

	rows, res, err := db.Query("SHOW GLOBAL STATUS LIKE 'Threads_Connected'")
	if err != nil {
		return checkers.Unknown("couldn't execute query")
	}

	idxValue := res.Map("Value")
	threadsConnected := rows[0].Int64(idxValue)

	checkSt := checkers.OK
	msg := fmt.Sprintf("%d connections", threadsConnected)
	if threadsConnected > opts.Crit {
		checkSt = checkers.CRITICAL
	} else if threadsConnected > opts.Warn {
		checkSt = checkers.WARNING
	}
	return checkers.NewChecker(checkSt, msg)
}
예제 #3
0
func checkPing(opts solrOpts) *checkers.Checker {
	uri := opts.createBaseURL() + "/admin/ping?wt=json"
	resp, err := http.Get(uri)
	if err != nil {
		return checkers.Unknown("couldn't get access to " + uri)
	}
	defer resp.Body.Close()

	dec := json.NewDecoder(resp.Body)
	var stats map[string]interface{}
	err = dec.Decode(&stats)
	if err != nil {
		return checkers.Unknown("couldn't parse JSON at " + uri)
	}

	status, ok := stats["status"].(string)
	if !ok {
		return checkers.Unknown("couldn't find status in JSON at " + uri)
	}

	checkSt := checkers.OK
	msg := fmt.Sprintf("%s %s", opts.Core, status)
	if status != "OK" {
		checkSt = checkers.CRITICAL
	}
	return checkers.NewChecker(checkSt, msg)
}
예제 #4
0
func (opts *sshOpts) run() *checkers.Checker {
	// prevent changing output of some commands
	os.Setenv("LANG", "C")
	os.Setenv("LC_ALL", "C")

	config, err := opts.makeClientConfig()
	if err != nil {
		return checkers.Unknown(err.Error())
	}

	start := time.Now()
	client, err := opts.dial(config)
	if err != nil {
		if addrerr, ok := err.(*net.AddrError); ok {
			if addrerr.Timeout() {
				elapsed := time.Now().Sub(start)
				return opts.checkTimeoutError(elapsed, err)
			} else if addrerr.Temporary() {
				return checkers.Warning(err.Error())
			}
		}
		return checkers.Critical(err.Error())
	}
	session, err := client.NewSession()
	if err != nil {
		return checkers.Critical(err.Error())
	}
	err = session.Close()
	if err != nil {
		return checkers.Unknown(err.Error())
	}
	elapsed := time.Now().Sub(start)
	return opts.checkTimeout(elapsed)
}
예제 #5
0
func checkSlave(args []string) *checkers.Checker {
	opts := redisSetting{}
	psr := flags.NewParser(&opts, flags.Default)
	psr.Usage = "slave [OPTIONS]"
	_, err := psr.ParseArgs(args)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	c, info, err := connectRedisGetInfo(opts)
	if err != nil {
		return checkers.Unknown(err.Error())
	}
	defer c.Close()

	if status, ok := (*info)["master_link_status"]; ok {
		msg := fmt.Sprintf("master_link_status: %s", status)

		switch status {
		case "up":
			return checkers.Ok(msg)
		case "down":
			return checkers.Critical(msg)
		default:
			return checkers.Unknown(msg)
		}

	} else {
		// it may be a master!
		return checkers.Unknown("couldn't get master_link_status")
	}
}
예제 #6
0
func checkUptime(args []string) *checkers.Checker {
	opts := uptimeOpts{}
	psr := flags.NewParser(&opts, flags.Default)
	psr.Usage = "uptime [OPTIONS]"
	_, err := psr.ParseArgs(args)
	if err != nil {
		os.Exit(1)
	}
	db := newMySQL(opts.mysqlSetting)
	err = db.Connect()
	if err != nil {
		return checkers.Unknown("couldn't connect DB")
	}
	defer db.Close()

	rows, res, err := db.Query("SHOW GLOBAL STATUS LIKE 'Uptime'")
	if err != nil {
		return checkers.Unknown("couldn't execute query")
	}

	idxValue := res.Map("Value")
	upTime := rows[0].Int64(idxValue)

	checkSt := checkers.OK
	msg := fmt.Sprintf("up %s", uptime2str(upTime))
	if opts.Crit > 0 && upTime < opts.Crit {
		checkSt = checkers.CRITICAL
	} else if opts.Warn > 0 && upTime < opts.Warn {
		checkSt = checkers.WARNING
	}
	return checkers.NewChecker(checkSt, msg)
}
예제 #7
0
func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		os.Exit(1)
	}

	var queue int64
	queueStr := "0"
	monitor := newMonitor(opts.Warning, opts.Critical)

	result := checkers.OK

	if opts.Mta == "postfix" {
		out, err := exec.Command("mailq").Output()

		if err != nil {
			return checkers.Unknown(err.Error())
		}

		outs := strings.Split(string(out), "\n")
		line := outs[len(outs)-2]

		re := regexp.MustCompile(`-- \d+ Kbytes in (\d+) Requests.`)
		if re.MatchString(line) {
			queueStr = re.ReplaceAllString(line, "$1")
			queue, err = strconv.ParseInt(queueStr, 10, 64)
		}
	} else if opts.Mta == "qmail" {
		out, err := exec.Command("qmail-qstat").Output()

		if err != nil {
			return checkers.Unknown(err.Error())
		}

		outs := strings.Split(string(out), "\n")
		line := outs[0]

		re := regexp.MustCompile(`^messages in queue: (\d+)`)
		if re.MatchString(line) {
			queueStr = re.ReplaceAllString(line, "$1")
			queue, err = strconv.ParseInt(queueStr, 10, 64)
		}
	} else {
		return checkers.Unknown(fmt.Sprintf("%s: specified mta's check is not implemented.", opts.Mta))
	}

	if monitor.checkWarning(queue) {
		result = checkers.WARNING
	}

	if monitor.checkCritical(queue) {
		result = checkers.CRITICAL
	}

	msg := fmt.Sprintf(queueStr)
	return checkers.NewChecker(result, msg)
}
예제 #8
0
func (opts *options) run() *checkers.Checker {
	missingInstances, missingMembers, err := check(opts)
	if err != nil {
		return checkers.Unknown(err.Error())
	}

	if len(missingInstances) != 0 {
		var ipAddrs []string
		for _, instance := range missingInstances {
			ipAddrs = append(ipAddrs, aws.StringValue(instance.PrivateIpAddress))
		}

		return checkers.Critical(fmt.Sprintf("%d instance(s) left from Consul cluster: %v", len(ipAddrs), ipAddrs))
	}

	if len(missingMembers) != 0 {
		var ipAddrs []string
		for _, member := range missingMembers {
			ipAddrs = append(ipAddrs, fmt.Sprintf("%s(%s)", member.Node, member.Address))
		}

		return checkers.Warning(fmt.Sprintf("%d instance(s) not properly tagged: %v", len(ipAddrs), ipAddrs))
	}

	return checkers.Ok("OK")
}
func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		return checkers.Critical(err.Error())
	}

	offset, err := getNtpOffset()
	if err != nil {
		return checkers.Unknown(err.Error())
	}

	var chkSt checkers.Status
	var msg string
	if opts.Crit < math.Abs(offset) {
		msg = fmt.Sprintf("ntp offset is over %f(actual) > %f(threshold)", math.Abs(offset), opts.Crit)
		chkSt = checkers.CRITICAL
	} else if opts.Warn < math.Abs(offset) {
		msg = fmt.Sprintf("ntp offset is over %f(actual) > %f(threshold)", math.Abs(offset), opts.Warn)
		chkSt = checkers.WARNING
	} else {
		msg = fmt.Sprintf("ntp offset is %f(actual) < %f(warning threshold), %f(critial threshold)", offset, opts.Warn, opts.Crit)
		chkSt = checkers.OK
	}

	return checkers.NewChecker(chkSt, msg)
}
예제 #10
0
func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		os.Exit(1)
	}

	stat, err := os.Stat(opts.File)
	if err != nil {
		if opts.IgnoreMissing {
			return checkers.Ok("No such file, but ignore missing is set.")
		}
		return checkers.Unknown(err.Error())
	}

	monitor := newMonitor(opts.WarningAge, opts.WarningSize, opts.CriticalAge, opts.CriticalSize)

	result := checkers.OK

	mtime := stat.ModTime()
	age := time.Now().Unix() - mtime.Unix()
	size := stat.Size()

	if monitor.CheckWarning(age, size) {
		result = checkers.WARNING
	}

	if monitor.CheckCritical(age, size) {
		result = checkers.CRITICAL
	}

	msg := fmt.Sprintf("%s is %d seconds old (%02d:%02d:%02d) and %d bytes.\n", opts.File, age, mtime.Hour(), mtime.Minute(), mtime.Second(), size)
	return checkers.NewChecker(result, msg)
}
예제 #11
0
func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		os.Exit(1)
	}
	ut, err := uptime.Get()
	if err != nil {
		return checkers.Unknown(fmt.Sprintf("Faild to fetch uptime metrics: %s", err))
	}
	checkSt := checkers.OK
	if opts.WarnUnder != nil && *opts.WarnUnder > ut {
		checkSt = checkers.WARNING
	}
	if opts.WarnOver != nil && *opts.WarnOver < ut {
		checkSt = checkers.WARNING
	}
	if opts.CritUnder != nil && *opts.CritUnder > ut {
		checkSt = checkers.CRITICAL
	}
	if opts.CritOver != nil && *opts.CritOver < ut {
		checkSt = checkers.CRITICAL
	}
	dur := time.Duration(ut * float64(time.Second))
	hours := int64(dur.Hours())
	days := hours / 24
	hours = hours % 24
	mins := int64(dur.Minutes()) % 60
	msg := fmt.Sprintf("%d day(s) %d hour(s) %d minute(s) (%d second(s))\n", days, hours, mins, int64(dur.Seconds()))

	return checkers.NewChecker(checkSt, msg)
}
예제 #12
0
func checkReplication(args []string) *checkers.Checker {
	opts := replicationOpts{}
	psr := flags.NewParser(&opts, flags.Default)
	psr.Usage = "replication [OPTIONS]"
	_, err := psr.ParseArgs(args)
	if err != nil {
		os.Exit(1)
	}
	db := newMySQL(opts.mysqlSetting)
	err = db.Connect()
	if err != nil {
		return checkers.Unknown("couldn't connect DB")
	}
	defer db.Close()

	rows, res, err := db.Query("SHOW SLAVE STATUS")
	if err != nil {
		return checkers.Unknown("couldn't execute query")
	}

	if len(rows) == 0 {
		return checkers.Ok("MySQL is not slave")
	}

	idxIoThreadRunning := res.Map("Slave_IO_Running")
	idxSQLThreadRunning := res.Map("Slave_SQL_Running")
	idxSecondsBehindMaster := res.Map("Seconds_Behind_Master")
	ioThreadStatus := rows[0].Str(idxIoThreadRunning)
	sqlThreadStatus := rows[0].Str(idxSQLThreadRunning)
	secondsBehindMaster := rows[0].Int64(idxSecondsBehindMaster)

	if !(ioThreadStatus == "Yes" && sqlThreadStatus == "Yes") {
		return checkers.Critical("MySQL replication has been stopped")
	}

	checkSt := checkers.OK
	msg := fmt.Sprintf("MySQL replication behind master %d seconds", secondsBehindMaster)
	if secondsBehindMaster > opts.Crit {
		checkSt = checkers.CRITICAL
	} else if secondsBehindMaster > opts.Warn {
		checkSt = checkers.WARNING
	}
	return checkers.NewChecker(checkSt, msg)
}
예제 #13
0
func run(args []string) *checkers.Checker {
	opts, err := parseArgs(args)
	if err != nil {
		os.Exit(1)
	}

	err = opts.prepare()
	if err != nil {
		return checkers.Unknown(err.Error())
	}

	warnNum := int64(0)
	critNum := int64(0)
	errorOverall := ""

	for _, f := range opts.fileList {
		w, c, errLines, err := opts.searchLog(f)
		if err != nil {
			return checkers.Unknown(err.Error())
		}
		warnNum += w
		critNum += c
		if opts.ReturnContent {
			errorOverall += errLines
		}
	}

	checkSt := checkers.OK
	if warnNum > opts.WarnOver {
		checkSt = checkers.WARNING
	}
	if critNum > opts.CritOver {
		checkSt = checkers.CRITICAL
	}
	msg := fmt.Sprintf("%d warnings, %d criticals for pattern /%s/.", warnNum, critNum, opts.Pattern)
	if errorOverall != "" {
		msg += "\n" + errorOverall
	}
	return checkers.NewChecker(checkSt, msg)
}
예제 #14
0
func run(args []string) *checkers.Checker {
	opts, err := parseArgs(args)
	if err != nil {
		os.Exit(1)
	}

	client := &http.Client{Timeout: time.Duration(opts.Timeout) * time.Second}
	res, err := client.Get(createURL(opts))
	if err != nil {
		return checkers.Critical(err.Error())
	}

	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		return checkers.Unknown(fmt.Sprintf("failed: http status code %d", res.StatusCode))
	}

	resJ := jmxJolokiaResponse{}
	dec := json.NewDecoder(res.Body)
	if err := dec.Decode(&resJ); err != nil {
		return checkers.Critical(err.Error())
	}

	if resJ.Status != 200 {
		return checkers.Unknown(fmt.Sprintf("failed: response status %d", resJ.Status))
	}

	checkSt := checkers.OK
	msg := fmt.Sprintf("%s %s value %f", opts.MBean, opts.Attribute, resJ.Value)
	if resJ.Value > opts.Critical {
		checkSt = checkers.CRITICAL
		msg = fmt.Sprintf("%s %s value is over %f > %f", opts.MBean, opts.Attribute, resJ.Value, opts.Critical)
	} else if resJ.Value > opts.Warning {
		checkSt = checkers.WARNING
		msg = fmt.Sprintf("%s %s value is over %f > %f", opts.MBean, opts.Attribute, resJ.Value, opts.Warning)
	}

	return checkers.NewChecker(checkSt, msg)
}
예제 #15
0
func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		os.Exit(1)
	}

	wload, err := parseThreshold(opts.WarningThreshold)
	if err != nil {
		return checkers.Unknown(err.Error())
	}
	cload, err := parseThreshold(opts.CriticalThreshold)
	if err != nil {
		return checkers.Unknown(err.Error())
	}

	loadavgs, err := getloadavg()
	if err != nil {
		return checkers.Unknown(err.Error())
	}

	result := checkers.OK
	for i, load := range loadavgs {
		if opts.PerCPU {
			numCPU := runtime.NumCPU()
			load = load / float64(numCPU)
		}
		if load > cload[i] {
			result = checkers.CRITICAL
			break
		}
		if load > wload[i] {
			result = checkers.WARNING
		}
	}

	msg := fmt.Sprintf("load average: %.2f, %.2f, %.2f", loadavgs[0], loadavgs[1], loadavgs[2])
	return checkers.NewChecker(result, msg)
}
예제 #16
0
func checkReachable(args []string) *checkers.Checker {
	opts := redisSetting{}
	psr := flags.NewParser(&opts, flags.Default)
	psr.Usage = "reachable [OPTIONS]"
	_, err := psr.ParseArgs(args)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	c, info, err := connectRedisGetInfo(opts)
	if err != nil {
		return checkers.Unknown(err.Error())
	}
	defer c.Close()

	if _, ok := (*info)["redis_version"]; !ok {
		return checkers.Unknown("couldn't get redis_version")
	}

	return checkers.Ok(
		fmt.Sprintf("version: %s", (*info)["redis_version"]),
	)
}
예제 #17
0
func (opts *tcpOpts) run() *checkers.Checker {
	err := opts.prepare()
	if err != nil {
		return checkers.Unknown(err.Error())
	}
	// prevent changing output of some commands
	os.Setenv("LANG", "C")
	os.Setenv("LC_ALL", "C")

	address := fmt.Sprintf("%s:%d", opts.Hostname, opts.Port)
	start := time.Now()
	if opts.Delay > 0 {
		time.Sleep(time.Duration(opts.Delay) * time.Second)
	}
	var conn net.Conn
	if opts.UnixSock != "" {
		conn, err = dial("unix", opts.UnixSock, opts.SSL, opts.NoCheckCertificate)
	} else {
		conn, err = dial("tcp", address, opts.SSL, opts.NoCheckCertificate)
	}
	if err != nil {
		return checkers.Critical(err.Error())
	}
	defer conn.Close()

	if opts.Send != "" {
		err := write(conn, []byte(opts.Send), opts.Timeout)
		if err != nil {
			return checkers.Critical(err.Error())
		}
	}

	res := ""
	if opts.expectReg != nil {
		buf, err := slurp(conn, opts.MaxBytes, opts.Timeout)
		if err != nil {
			return checkers.Critical(err.Error())
		}
		res = string(buf)
		if !opts.expectReg.MatchString(res) {
			return checkers.Critical("Unexpected response from host/socket: " + res)
		}
	}

	if opts.Quit != "" {
		err := write(conn, []byte(opts.Quit), opts.Timeout)
		if err != nil {
			return checkers.Critical(err.Error())
		}
	}
	elapsed := time.Now().Sub(start)

	chkSt := checkers.OK
	if opts.Warning > 0 && elapsed > time.Duration(opts.Warning)*time.Second {
		chkSt = checkers.WARNING
	}
	if opts.Critical > 0 && elapsed > time.Duration(opts.Critical)*time.Second {
		chkSt = checkers.CRITICAL
	}
	msg := fmt.Sprintf("%.3f seconds response time on", float64(elapsed)/float64(time.Second))
	if opts.Hostname != "" {
		msg += " " + opts.Hostname
	}
	if opts.Port > 0 {
		msg += fmt.Sprintf(" port %d", opts.Port)
	}
	if res != "" {
		msg += fmt.Sprintf(" [%s]", strings.Trim(res, "\r\n"))
	}
	return checkers.NewChecker(chkSt, msg)
}