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 }
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 }
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 }
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 }
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 }