예제 #1
0
파일: dsc_windows.go 프로젝트: mathpl/bosun
func c_dsc_status() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	if _, err := os.Stat(dscpath + "MetaConfig.mof"); os.IsNotExist(err) {
		return md, nil
	}
	var dst MSFT_DSCConfigurationStatus
	dscstatusmof, err := util.Command(time.Minute, nil, "wmic",
		`/namespace:\\ROOT\Microsoft\Windows\DesiredStateConfiguration`, "class",
		"MSFT_DSCLocalConfigurationManager", "call", "GetConfigurationStatus")
	if err != nil {
		return nil, err
	}
	dscstatusbuffer := new(bytes.Buffer)
	_, err = dscstatusbuffer.ReadFrom(dscstatusmof)
	if err != nil {
		return nil, err
	}
	err = mof.Unmarshal(dscstatusbuffer.Bytes(), &dst)
	if err != nil {
		return nil, err
	}
	if dst.ReturnValue != 0 {
		return nil, fmt.Errorf("GetConfigurationStatus ReturnValue %v", dst.ReturnValue)
	}
	for _, v := range dst.MSFT_DSCConfigurationStatus {
		Add(&md, dscLCM+"auto_reboot", v.MetaConfiguration.RebootNodeIfNeeded, nil, metadata.Gauge, metadata.Bool, descWinDSCAutoReboot)
		Add(&md, dscLCM+"frequency_config", v.MetaConfiguration.ConfigurationModeFrequencyMins, nil, metadata.Gauge, metadata.Count, descWinDSCFreqConfig)
		Add(&md, dscLCM+"frequency_refresh", v.MetaConfiguration.RefreshFrequencyMins, nil, metadata.Gauge, metadata.Count, descWinDSCFreqRefresh)
		Add(&md, dscLCM+"refresh_mode", dscModeToStatusCode(v.Mode), nil, metadata.Gauge, metadata.StatusCode, descWinDSCMode)
		Add(&md, dscLCM+"state", dscStateToStatusCode(v.MetaConfiguration.LCMState), nil, metadata.Gauge, metadata.StatusCode, descWinDSCState)
		Add(&md, dscStatus+"reboot_requested", v.RebootRequested, nil, metadata.Gauge, metadata.Bool, descWinDSCRebootRequested)
		Add(&md, dscStatus+"resources_total", v.NumberOfResources, nil, metadata.Gauge, metadata.Count, descWinDSCNumberOfResources)
		Add(&md, dscStatus+"run_age", dscStartDateToAge(v.StartDate), nil, metadata.Gauge, metadata.Second, descWinDSCAge)
		Add(&md, dscStatus+"run_duration", v.DurationInSeconds, nil, metadata.Gauge, metadata.Second, descWinDSCDurationInSeconds)
		Add(&md, dscStatus+"run_success", v.Status == "Success", nil, metadata.Gauge, metadata.Bool, descWinDSCStatus)
		Add(&md, dscStatus+"run_type", dscTypeToStatusCode(v.Type), nil, metadata.Gauge, metadata.Count, descWinDSCType)
		configurations := make(map[string]dscResourceCount)
		for _, r := range v.ResourcesInDesiredState {
			c := configurations[r.ConfigurationName]
			c.Success++
			c.Duration += r.DurationInSeconds
			configurations[r.ConfigurationName] = c
		}
		for _, r := range v.ResourcesNotInDesiredState {
			c := configurations[r.ConfigurationName]
			c.Failed++
			c.Duration += r.DurationInSeconds
			configurations[r.ConfigurationName] = c
		}
		for key, value := range configurations {
			Add(&md, dscStatus+"resources", value.Success, opentsdb.TagSet{"state": "Success", "configuration": key}, metadata.Gauge, metadata.Count, descWinDSCResourceState)
			Add(&md, dscStatus+"resources", value.Failed, opentsdb.TagSet{"state": "Failed", "configuration": key}, metadata.Gauge, metadata.Count, descWinDSCResourceState)
			Add(&md, dscStatus+"config_duration", value.Duration, opentsdb.TagSet{"configuration": key}, metadata.Gauge, metadata.Second, descWinDSCConfigSeconds)
		}
	}
	return md, nil
}
예제 #2
0
func examineMdadmVolume(volumeName string) (volumeDetail, error) {
	// command to get mdadm status
	tmout := 2 * time.Second
	// We don't use --test because it has failed us in the past.
	// Maybe we should use it sometime in the future
	output, err := util.Command(tmout, nil, "mdadm", "--detail", volumeName)
	if err != nil {
		return volumeDetail{}, err
	}
	detail := parseExamineMdadm(output)
	return detail, err
}
예제 #3
0
파일: exim_linux.go 프로젝트: eswdd/bosun
func c_exim_mailq() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	mailq, err := util.Command(time.Minute, nil, "/usr/bin/mailq")
	if err != nil {
		return nil, err
	}
	util.ReadCommandTimeout(time.Minute, func(line string) error {
		f := strings.Fields(line)
		if len(f) == 5 && f[4] == "TOTAL" {
			Add(&md, "exim.mailq_count", f[0], nil, metadata.Gauge, metadata.EMail, "The number of emails in exim's mail queue.")
			var multi int64 = 1
			size, err := strconv.ParseInt(f[1], 10, 64)
			if err != nil && len(f[1]) > 3 {
				unit := f[1][len(f[1])-2:]
				switch unit {
				case "KB":
					multi = 1024
				case "MB":
					multi = 1024 * 1024
				default:
					return fmt.Errorf("error parsing size unit of exim's mail queue")
				}
				size, err = strconv.ParseInt(f[1][:len(f[1])-2], 10, 64)
				if err != nil {
					return fmt.Errorf("error parsing exim size field")
				}
			}
			Add(&md, "exim.mailq_size", size*multi, nil, metadata.Gauge, metadata.Bytes, descEximMailQSize)
			oldest, err := opentsdb.ParseDuration(f[2])
			if err != nil {
				return err
			}
			Add(&md, "exim.mailq_oldest", oldest.Seconds(), nil, metadata.Gauge, metadata.Second, descEximMailQOldest)
			newest, err := opentsdb.ParseDuration(f[3])
			if err != nil {
				return err
			}
			Add(&md, "exim.mailq_newest", newest.Seconds(), nil, metadata.Gauge, metadata.Second, descEximMailQNewest)
		}
		return nil
	}, mailq, eximExiqsumm)
	return md, nil
}
예제 #4
0
func c_if_team_linux() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	getState := func(iname string) (TeamState, error) {
		var ts TeamState
		reader, err := util.Command(time.Second*5, nil, "teamdctl", iname, "state", "dump")
		if err != nil {
			return ts, err
		}
		err = json.NewDecoder(reader).Decode(&ts)
		if err != nil {
			return ts, err
		}
		return ts, nil
	}
	teamdFiles, err := ioutil.ReadDir("/var/run/teamd")
	if err != nil {
		return md, nil
	}
	for _, f := range teamdFiles {
		name := f.Name()
		if strings.HasSuffix(name, ".pid") {
			name = strings.TrimSuffix(name, ".pid")
			ts, err := getState(name)
			if err != nil {
				return md, err
			}
			var slaveCount int
			var speed int64
			for portName, port := range ts.TeamPorts {
				slaveCount++
				speed += int64(port.Link.Speed)
				metadata.AddMeta("", opentsdb.TagSet{"iface": portName}, "master", name, true)
				Add(&md, "linux.net.bond.slave.is_up", port.Link.Up, opentsdb.TagSet{"slave": portName, "bond": name}, metadata.Gauge, metadata.Bool, linuxNetBondSlaveIsUpDesc)
			}
			Add(&md, "os.net.bond.ifspeed", speed, opentsdb.TagSet{"bond": name}, metadata.Gauge, metadata.Megabit, osNetIfSpeedDesc)
			Add(&md, "linux.net.bond.slave.count", slaveCount, opentsdb.TagSet{"bond": name}, metadata.Gauge, metadata.Count, linuxNetBondSlaveCount)
		}
	}
	return md, nil
}
예제 #5
0
func c_varnish_unix() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	const metric = "varnish."

	r, err := util.Command(5*time.Second, nil, "varnishstat", "-j")
	if err != nil {
		return nil, err
	}

	var stats varnishStats
	if err := json.NewDecoder(r).Decode(&stats); err != nil {
		return nil, err
	}

	for name, raw := range stats {
		if name == "timestamp" {
			continue
		}

		var v varnishStat
		if err := json.Unmarshal(raw, &v); err != nil {
			slog.Errorln("varnish parser error:", name, err)
			continue
		}

		ts := opentsdb.TagSet{}

		// special case for backend stats. extract backend name, host and port, put
		// them in tags and remove them in name.
		// the format is like "name(host,,port)" for the "ident" field of "VBE" type
		if v.Type == "VBE" {
			subtype := v.SubType

			name = strings.Replace(name, "."+subtype, "", -1)

			idx := strings.Index(subtype, "(")
			if idx < 0 || len(subtype)-idx < 4 {
				// output format changed, ignore
				continue
			}

			ss := strings.Split(subtype[idx+1:len(subtype)-1], ",")
			if len(ss) != 3 {
				// output format changed, ignore
				continue
			}

			ts.Merge(opentsdb.TagSet{"backend": subtype[:idx]})
			ts.Merge(opentsdb.TagSet{"endpoint": ss[0] + "_" + ss[2]})
		}

		rate := metadata.RateType(metadata.Gauge)
		if flag := v.Flag; flag == "a" || flag == "c" {
			rate = metadata.Counter
		}

		unit := metadata.Unit(metadata.Count)
		if v.Format == "B" {
			unit = metadata.Bytes
		}

		Add(&md, metric+strings.ToLower(name), v.Value, ts, rate, unit, v.Desc)
	}
	return md, nil
}