Пример #1
0
func metaLinuxVersion() {
	_ = util.ReadCommand(func(line string) error {
		AddMeta("", nil, "uname", line, true)
		return nil
	}, "uname", "-a")
	_ = util.ReadCommand(func(line string) error {
		fields := strings.Fields(line)
		hasNum := false
		for i := 0; i < len(fields); {
			if strings.HasPrefix(fields[i], `\`) {
				fields = append(fields[:i], fields[i+1:]...)
			} else {
				if v, _ := strconv.ParseFloat(fields[i], 32); v > 0 {
					hasNum = true
				}
				i++
			}
		}
		if !hasNum {
			return nil
		}
		AddMeta("", nil, "version", strings.Join(fields, " "), true)
		return nil
	}, "cat", "/etc/issue")
}
Пример #2
0
func c_meta_darwin_version() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	util.ReadCommand(func(line string) error {
		metadata.AddMeta("", nil, "uname", line, true)
		return nil
	}, "uname", "-a")
	var name, vers, build string
	util.ReadCommand(func(line string) error {
		sp := strings.SplitN(line, ":", 2)
		if len(sp) != 2 {
			return nil
		}
		v := strings.TrimSpace(sp[1])
		switch sp[0] {
		case "ProductName":
			name = v
		case "ProductVersion":
			vers = v
		case "BuildVersion":
			build = v
		}
		return nil
	}, "sw_vers")
	if name != "" && vers != "" && build != "" {
		metadata.AddMeta("", nil, "version", fmt.Sprintf("%s.%s", vers, build), true)
		metadata.AddMeta("", nil, "versionCaption", fmt.Sprintf("%s %s", name, vers), true)
	}
	return md, nil
}
Пример #3
0
func metaDarwinVersion() {
	util.ReadCommand(func(line string) error {
		AddMeta("", nil, "uname", line, true)
		return nil
	}, "uname", "-a")
	var name, vers, build string
	util.ReadCommand(func(line string) error {
		sp := strings.SplitN(line, ":", 2)
		if len(sp) != 2 {
			return nil
		}
		v := strings.TrimSpace(sp[1])
		switch sp[0] {
		case "ProductName":
			name = v
		case "ProductVersion":
			vers = v
		case "BuildVersion":
			build = v
		}
		return nil
	}, "sw_vers")
	if name != "" && vers != "" && build != "" {
		AddMeta("", nil, "version", fmt.Sprintf("%s.%s", vers, build), true)
		AddMeta("", nil, "versionCaption", fmt.Sprintf("%s %s", name, vers), true)
	}
}
Пример #4
0
func c_dfstat_blocks_linux() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	err := util.ReadCommand(func(line string) error {
		fields := strings.Fields(line)
		// TODO: support mount points with spaces in them. They mess up the field order
		// currently due to df's columnar output.
		if len(fields) != 6 || !IsDigit(fields[2]) {
			return nil
		}
		fs := fields[0]
		mount := fields[5]
		tags := opentsdb.TagSet{"mount": mount}
		os_tags := opentsdb.TagSet{"disk": mount}
		metric := "linux.disk.fs."
		ometric := "os.disk.fs."
		if removable_fs(fs) {
			metric += "rem."
			ometric += "rem."
		}
		Add(&md, metric+"space_total", fields[1], tags, metadata.Gauge, metadata.Bytes, osDiskTotalDesc)
		Add(&md, metric+"space_used", fields[2], tags, metadata.Gauge, metadata.Bytes, osDiskUsedDesc)
		Add(&md, metric+"space_free", fields[3], tags, metadata.Gauge, metadata.Bytes, osDiskFreeDesc)
		Add(&md, ometric+"space_total", fields[1], os_tags, metadata.Gauge, metadata.Bytes, osDiskTotalDesc)
		Add(&md, ometric+"space_used", fields[2], os_tags, metadata.Gauge, metadata.Bytes, osDiskUsedDesc)
		Add(&md, ometric+"space_free", fields[3], os_tags, metadata.Gauge, metadata.Bytes, osDiskFreeDesc)
		st, _ := strconv.ParseFloat(fields[1], 64)
		sf, _ := strconv.ParseFloat(fields[3], 64)
		if st != 0 {
			Add(&md, osDiskPctFree, sf/st*100, os_tags, metadata.Gauge, metadata.Pct, osDiskPctFreeDesc)
		}
		return nil
	}, "df", "-lP", "--block-size", "1")
	return md, err
}
Пример #5
0
func parseRailURL() string {
	var config string
	var url string
	util.ReadCommand(func(line string) error {
		fields := strings.Fields(line)
		if len(fields) == 0 || !strings.Contains(fields[0], "rg-listener") {
			return nil
		}
		for i, s := range fields {
			if s == "-config" && len(fields) > i {
				config = fields[i+1]
			}
		}
		return nil
	}, "ps", "-e", "-o", "args")
	if config == "" {
		return config
	}
	readLine(config, func(s string) error {
		if m := rgListenRE.FindStringSubmatch(s); len(m) > 0 {
			url = "http://" + m[1]
		}
		return nil
	})
	return url
}
Пример #6
0
func c_dfstat_inodes_linux() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	err := util.ReadCommand(func(line string) error {
		fields := strings.Fields(line)
		if len(fields) != 7 || !IsDigit(fields[2]) {
			return nil
		}
		// /dev/mapper/vg0-usr ext4 851968 468711 383257 56% /usr
		fs := fields[0]
		fsType := fields[1]
		inodesTotal := fields[2]
		inodesUsed := fields[3]
		inodesFree := fields[4]
		mount := fields[6]
		if isPseudoFS(fsType) {
			return nil
		}
		tags := opentsdb.TagSet{"mount": mount}
		metric := "linux.disk.fs."
		if removable_fs(fs) {
			metric += "rem."
		}
		Add(&md, metric+"inodes_total", inodesTotal, tags, metadata.Gauge, metadata.Count, "")
		Add(&md, metric+"inodes_used", inodesUsed, tags, metadata.Gauge, metadata.Count, "")
		Add(&md, metric+"inodes_free", inodesFree, tags, metadata.Gauge, metadata.Count, "")
		return nil
	}, "df", "-liPT")
	return md, err
}
Пример #7
0
func redisInit() {
	update := func() {
		var instances []opentsdb.TagSet
		oldRedis := false
		add := func(port string) {
			ri := make(opentsdb.TagSet)
			ri["port"] = port
			instances = append(instances, ri)
		}
		util.ReadCommand(func(line string) error {
			sp := strings.Fields(line)
			if len(sp) != 3 || !strings.HasSuffix(sp[1], "redis-server") {
				return nil
			}
			if !strings.Contains(sp[2], ":") {
				oldRedis = true
				return nil
			}
			port := strings.Split(sp[2], ":")[1]
			if port != "0" {
				add(port)
			}
			return nil
		}, "ps", "-e", "-o", "pid,args")
		if oldRedis {
			util.ReadCommand(func(line string) error {
				if !strings.Contains(line, "redis-server") {
					return nil
				}
				sp := strings.Fields(line)
				if len(sp) < 7 || !strings.Contains(sp[3], ":") {
					return nil
				}
				port := strings.Split(sp[3], ":")[1]
				add(port)
				return nil
			}, "netstat", "-tnlp")
		}
		redisInstances = instances
	}
	update()
	go func() {
		for range time.Tick(time.Minute * 5) {
			update()
		}
	}()
}
Пример #8
0
func c_vmstat_darwin() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	var free float64
	util.ReadCommand(func(line string) error {
		if line == "" || strings.HasPrefix(line, "Object cache") || strings.HasPrefix(line, "Mach Virtual") {
			return nil
		}
		fields := strings.Split(line, ":")
		if len(fields) < 2 {
			return nil
		}
		value, err := strconv.ParseFloat(strings.TrimSpace(fields[1]), 64)
		if err != nil {
			return nil
		}
		if strings.HasPrefix(fields[0], "Pages") {
			name := strings.TrimSpace(fields[0])
			name = strings.Replace(name, "Pages ", "", -1)
			name = strings.Replace(name, " ", "", -1)
			Add(&md, "darwin.mem.vm.4kpages."+name, value, nil, metadata.Unknown, metadata.None, "")
			if name == "free" {
				free = value * 4096
				Add(&md, osMemFree, free, nil, metadata.Gauge, metadata.Bytes, osMemFreeDesc)
			}
		} else if fields[0] == "Pageins" {
			Add(&md, "darwin.mem.vm.pageins", value, nil, metadata.Counter, metadata.None, "")
		} else if fields[0] == "Pageouts" {
			Add(&md, "darwin.mem.vm.pageouts", value, nil, metadata.Counter, metadata.None, "")
		}
		return nil
	}, "vm_stat")
	util.ReadCommand(func(line string) error {
		total, _ := strconv.ParseFloat(line, 64)
		if total == 0 {
			return nil
		}
		Add(&md, osMemTotal, total, nil, metadata.Gauge, metadata.Bytes, osMemTotalDesc)
		if free == 0 {
			return nil
		}
		Add(&md, osMemUsed, total-free, nil, metadata.Gauge, metadata.Bytes, osMemUsedDesc)
		Add(&md, osMemPctFree, free/total, nil, metadata.Gauge, metadata.Pct, osMemPctFreeDesc)
		return nil
	}, "sysctl", "-n", "hw.memsize")
	return md, nil
}
Пример #9
0
func c_meta_linux_version() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	_ = util.ReadCommand(func(line string) error {
		metadata.AddMeta("", nil, "uname", line, true)
		return nil
	}, "uname", "-a")
	if !readOSRelease() {
		readIssue()
	}
	return md, nil
}
Пример #10
0
func readOmreport(f func([]string), args ...string) {
	args = append(args, "-fmt", "ssv")
	_ = util.ReadCommand(func(line string) error {
		sp := strings.Split(line, ";")
		for i, s := range sp {
			sp[i] = clean(s)
		}
		f(sp)
		return nil
	}, "omreport", args...)
}
Пример #11
0
func c_netbackup_frequency() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	var class, schedule string
	var clients []string
	if err := util.ReadCommand(func(line string) error {
		if strings.HasPrefix(line, "Policy Name:") {
			clients = nil
			f := strings.Fields(line)
			if len(f) == 3 {
				class = f[2]
				return nil
			}
			return fmt.Errorf("error parsing policy: %v", line)
		}
		if strings.HasPrefix(line, "Client/HW/OS/Pri/DMI/CIT:") {
			f := strings.Fields(line)
			if len(f) == 9 {
				clients = append(clients, f[1])
				return nil
			}
			return fmt.Errorf("error parsing client")
		}
		if strings.HasPrefix(line, "Schedule:") {
			f := strings.Fields(line)
			if len(f) > 1 {
				schedule = f[1]
				return nil
			}
			return fmt.Errorf("error parsing client: %v", line)
		}
		if strings.HasPrefix(strings.TrimSpace(line), "Frequency:") {
			f := strings.Fields(line)
			if len(f) == 5 {
				freq := strings.TrimLeft(f[3], "(")
				for _, client := range clients {
					tags := opentsdb.TagSet{"class": class, "client": client, "schedule": schedule}
					Add(&md, "netbackup.backup.frequency", freq, tags, metadata.Gauge, metadata.Second, "")
				}
				return nil
			}
			return fmt.Errorf("error parsing frequency: %v", line)
		}
		return nil
	}, "bppllist", "-L", "-allpolicies"); err == util.ErrPath {
		return nil, nil
	} else if err != nil {
		return nil, err
	}
	return md, nil
}
Пример #12
0
func collectMetadataOmreport() {
	_ = util.ReadCommand(func(line string) error {
		fields := strings.Split(line, ";")
		if len(fields) != 2 {
			return nil
		}
		switch fields[0] {
		case "Chassis Service Tag":
			AddMeta("", nil, "serialNumber", fields[1], true)
		case "Chassis Model":
			AddMeta("", nil, "model", fields[1], true)
		}
		return nil
	}, "omreport", "chassis", "info", "-fmt", "ssv")
}
Пример #13
0
func metaLinuxSerial() {
	_ = util.ReadCommand(func(line string) error {
		fields := strings.SplitN(line, ":", 2)
		if len(fields) != 2 {
			return nil
		}
		switch fields[0] {
		case "\tSerial Number":
			AddMeta("", nil, "serialNumber", strings.TrimSpace(fields[1]), true)
		case "\tProduct Name":
			AddMeta("", nil, "model", strings.TrimSpace(fields[1]), true)
		}
		return nil
	}, "dmidecode", "-t", "system")
}
Пример #14
0
func c_iostat_darwin() (opentsdb.MultiDataPoint, error) {
	var categories []string
	var md opentsdb.MultiDataPoint
	ln := 0
	i := 0
	util.ReadCommand(func(line string) error {
		ln++
		if ln == 1 {
			categories = strings.Fields(line)
		}
		if ln < 4 {
			return nil
		}
		values := strings.Fields(line)
		for _, cat := range categories {
			if i+3 > len(values) {
				break
			} else if strings.HasPrefix(cat, "disk") {
				Add(&md, "darwin.disk.kilobytes_transfer", values[i], opentsdb.TagSet{"disk": cat}, metadata.Unknown, metadata.None, "")
				i++
				Add(&md, "darwin.disk.transactions", values[i], opentsdb.TagSet{"disk": cat}, metadata.Unknown, metadata.None, "")
				i++
				Add(&md, "darwin.disk.megabytes", values[i], opentsdb.TagSet{"disk": cat}, metadata.Unknown, metadata.None, "")
				i++
			} else if cat == "cpu" {
				Add(&md, "darwin.cpu.user", values[i], nil, metadata.Gauge, metadata.Pct, descDarwinCPUUser)
				i++
				Add(&md, "darwin.cpu.sys", values[i], nil, metadata.Gauge, metadata.Pct, descDarwinCPUSys)
				i++
				Add(&md, "darwin.cpu.idle", values[i], nil, metadata.Gauge, metadata.Pct, descDarwinCPUIdle)
				i++
			} else if cat == "load" {
				Add(&md, "darwin.loadavg_1_min", values[i], nil, metadata.Unknown, metadata.None, "")
				i++
				Add(&md, "darwin.loadavg_5_min", values[i], nil, metadata.Unknown, metadata.None, "")
				i++
				Add(&md, "darwin.loadavg_15_min", values[i], nil, metadata.Unknown, metadata.None, "")
				i++
			}
		}
		return nil
	}, "iostat", "-c2", "-w1")
	if ln < 4 {
		return nil, fmt.Errorf("bad return value")
	}
	return md, nil
}
Пример #15
0
func c_meta_linux_serial() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	_ = util.ReadCommand(func(line string) error {
		fields := strings.SplitN(line, ":", 2)
		if len(fields) != 2 {
			return nil
		}
		switch fields[0] {
		case "\tSerial Number":
			metadata.AddMeta("", nil, "serialNumber", strings.TrimSpace(fields[1]), true)
		case "\tProduct Name":
			metadata.AddMeta("", nil, "model", strings.TrimSpace(fields[1]), true)
		}
		return nil
	}, "dmidecode", "-t", "system")
	return md, nil
}
Пример #16
0
func metaLinuxIfaces() {
	metaIfaces(func(iface net.Interface, tags opentsdb.TagSet) {
		if speed, err := ioutil.ReadFile("/sys/class/net/" + iface.Name + "/speed"); err == nil {
			v, _ := strconv.Atoi(strings.TrimSpace(string(speed)))
			if v > 0 {
				const MbitToBit = 1e6
				AddMeta("", tags, "speed", v*MbitToBit, true)
			}
		}
		_ = util.ReadCommand(func(line string) error {
			if v := metaLinuxIfacesMaster(line); v != "" {
				AddMeta("", tags, "master", v, true)
				return doneErr
			}
			return nil
		}, "ip", "-o", "addr", "show", iface.Name)
	})
}
Пример #17
0
func c_ntp_peers_unix() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	const metric = "ntp."
	_ = util.ReadCommand(func(line string) error {
		fields := strings.Fields(line)
		if len(fields) != len(ntpNtpqPeerFields) || fields[0] == "remote" {
			return nil
		}
		r := []rune(line)
		if len(r) < 2 {
			return fmt.Errorf("unexpected length of line")
		}
		fl := string(r[0])
		rest := string(r[1:])
		fields = strings.Fields(rest)
		if len(fields) != len(ntpNtpqPeerFields) {
			return fmt.Errorf("unexpected length of fields")
		}
		remote := fields[0]
		tags := opentsdb.TagSet{"remote": remote, "refid": fields[1]}
		var current_source int
		if fl == "*" {
			current_source = 1
		}
		Add(&md, metric+"current_source", current_source, tags, metadata.Gauge, metadata.Bool, "")
		Add(&md, metric+"stratum", fields[2], tags, metadata.Gauge, "Stratum", "")
		when, err := ntpUnPretty(fields[4])
		if err != nil {
			return err
		}
		Add(&md, metric+"when", when, tags, metadata.Gauge, metadata.Second, "")
		poll, err := ntpUnPretty(fields[5])
		if err != nil {
			return err
		}
		Add(&md, metric+"poll", poll, tags, metadata.Gauge, metadata.Second, "")
		Add(&md, metric+"reach", fields[6], tags, metadata.Gauge, "Code", "")
		Add(&md, metric+"delay", fields[7], tags, metadata.Gauge, metadata.MilliSecond, "")
		Add(&md, metric+"offset", fields[8], tags, metadata.Gauge, metadata.MilliSecond, "")
		Add(&md, metric+"jitter", fields[9], tags, metadata.Gauge, metadata.MilliSecond, "")
		return nil
	}, "ntpq", "-pn")
	return md, nil
}
Пример #18
0
func c_netbackup_jobs() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	latest := make(map[string]nbJob)
	if err := util.ReadCommand(func(line string) error {
		if len(line) < 32 {
			return nil
		}
		var r nbJob
		reader := csv.NewReader(strings.NewReader(line))
		if err := nbUnmarhsall(reader, &r); err != nil {
			return err
		}
		if !(r.Jobtype == 0 || r.Jobtype == 6) {
			return nil
		}
		if r.State != 3 && r.State != 5 {
			return nil
		}
		key := r.Class + r.Schedule + r.Client
		if existing, ok := latest[key]; !ok {
			latest[key] = r
		} else if r.Started.After(existing.Started) {
			latest[key] = r
		}
		return nil
	}, "bpdbjobs", "-report", "-all_columns"); err == util.ErrPath {
		return nil, nil
	} else if err != nil {
		return nil, err
	}
	now := time.Now()
	for _, r := range latest {
		tags := opentsdb.TagSet{"class": r.Class, "client": r.Client, "schedule": r.Schedule}
		Add(&md, "netbackup.backup.status", r.Status, tags, metadata.Gauge, metadata.StatusCode, "")
		Add(&md, "netbackup.backup.duration", r.Elapsed, tags, metadata.Gauge, metadata.Second, "")
		Add(&md, "netbackup.backup.attempt_age", now.Sub(r.Ended).Seconds(), tags, metadata.Gauge, metadata.Second, "")
		Add(&md, "netbackup.backup.duration", r.Elapsed, tags, metadata.Gauge, metadata.Second, "")
		Add(&md, "netbackup.backup.no_files", r.Files, tags, metadata.Gauge, metadata.Count, "")
		Add(&md, "netbackup.backup.kbytes", r.Kbytes, tags, metadata.Gauge, metadata.KBytes, "")
	}
	return md, nil
}
Пример #19
0
func c_dfstat_blocks_linux() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	err := util.ReadCommand(func(line string) error {
		fields := strings.Fields(line)
		// TODO: support mount points with spaces in them. They mess up the field order
		// currently due to df's columnar output.
		if len(fields) != 7 || !IsDigit(fields[2]) {
			return nil
		}
		// /dev/mapper/vg0-usr ext4 13384816 9996920 2815784 79% /usr
		fs := fields[0]
		fsType := fields[1]
		spaceTotal := fields[2]
		spaceUsed := fields[3]
		spaceFree := fields[4]
		mount := fields[6]
		if isPseudoFS(fsType) {
			return nil
		}
		tags := opentsdb.TagSet{"mount": mount}
		os_tags := opentsdb.TagSet{"disk": mount}
		metric := "linux.disk.fs."
		ometric := "os.disk.fs."
		if removable_fs(fs) {
			metric += "rem."
			ometric += "rem."
		}
		Add(&md, metric+"space_total", spaceTotal, tags, metadata.Gauge, metadata.Bytes, osDiskTotalDesc)
		Add(&md, metric+"space_used", spaceUsed, tags, metadata.Gauge, metadata.Bytes, osDiskUsedDesc)
		Add(&md, metric+"space_free", spaceFree, tags, metadata.Gauge, metadata.Bytes, osDiskFreeDesc)
		Add(&md, ometric+"space_total", spaceTotal, os_tags, metadata.Gauge, metadata.Bytes, osDiskTotalDesc)
		Add(&md, ometric+"space_used", spaceUsed, os_tags, metadata.Gauge, metadata.Bytes, osDiskUsedDesc)
		Add(&md, ometric+"space_free", spaceFree, os_tags, metadata.Gauge, metadata.Bytes, osDiskFreeDesc)
		st, _ := strconv.ParseFloat(spaceTotal, 64)
		sf, _ := strconv.ParseFloat(spaceFree, 64)
		if st != 0 {
			Add(&md, osDiskPctFree, sf/st*100, os_tags, metadata.Gauge, metadata.Pct, osDiskPctFreeDesc)
		}
		return nil
	}, "df", "-lPT", "--block-size", "1")
	return md, err
}
Пример #20
0
func c_dfstat_inodes_linux() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	err := util.ReadCommand(func(line string) error {
		fields := strings.Fields(line)
		if len(fields) != 6 || !IsDigit(fields[2]) {
			return nil
		}
		mount := fields[5]
		fs := fields[0]
		tags := opentsdb.TagSet{"mount": mount}
		metric := "linux.disk.fs."
		if removable_fs(fs) {
			metric += "rem."
		}
		Add(&md, metric+"inodes_total", fields[1], tags, metadata.Gauge, metadata.Count, "")
		Add(&md, metric+"inodes_used", fields[2], tags, metadata.Gauge, metadata.Count, "")
		Add(&md, metric+"inodes_free", fields[3], tags, metadata.Gauge, metadata.Count, "")
		return nil
	}, "df", "-liP")
	return md, err
}
Пример #21
0
func c_ipcount_linux() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	v4c := 0
	v6c := 0
	err := util.ReadCommand(func(line string) error {
		tl := strings.TrimSpace(line)
		if strings.HasPrefix(tl, "inet ") {
			v4c++
		}
		if strings.HasPrefix(tl, "inet6 ") {
			v6c++
		}
		return nil
	}, "ip", "addr", "list")
	if err != nil {
		return md, err
	}
	Add(&md, "linux.net.ip_count", v4c, opentsdb.TagSet{"version": "4"}, metadata.Gauge, "IP_Addresses", "")
	Add(&md, "linux.net.ip_count", v6c, opentsdb.TagSet{"version": "6"}, metadata.Gauge, "IP_Addresses", "")
	return md, nil
}
Пример #22
0
func c_memcached_stats() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	const metric = "memcached."
	util.ReadCommand(func(line string) error {
		f := strings.Fields(line)
		if len(f) != 2 {
			return nil
		}
		v, err := strconv.ParseFloat(f[1], 64)
		if err != nil {
			return nil
		}
		if m, ok := memcachedMeta[f[0]]; ok {
			name := f[0]
			if m.Metric != "" {
				name = m.Metric
			}
			Add(&md, metric+name, v, m.TagSet, m.RateType, m.Unit, m.Desc)
		}
		return nil
	}, "memcached-tool", "127.0.0.1:11211", "stats")
	return md, nil
}
Пример #23
0
func c_nodestats_cfstats_linux() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	var keyspace, table string
	util.ReadCommand(func(line string) error {
		fields := strings.Split(strings.TrimSpace(line), ": ")
		if len(fields) != 2 {
			return nil
		}
		if fields[0] == "Keyspace" {
			keyspace = fields[1]
			table = ""
			return nil
		}
		if fields[0] == "Table" {
			table = fields[1]
			return nil
		}
		metric := strings.Replace(fields[0], " ", "_", -1)
		metric = strings.Replace(metric, "(", "", -1)
		metric = strings.Replace(metric, ")", "", -1)
		metric = strings.Replace(metric, ",", "", -1)
		metric = strings.ToLower(metric)
		values := strings.Fields(fields[1])
		if values[0] == "NaN" {
			return nil
		}
		value := values[0]
		if table == "" {
			Add(&md, "cassandra.tables."+metric, value, opentsdb.TagSet{"keyspace": keyspace}, metadata.Unknown, metadata.None, "")
		} else {
			Add(&md, "cassandra.tables."+metric, value, opentsdb.TagSet{"keyspace": keyspace, "table": table}, metadata.Unknown, metadata.None, "")
		}
		return nil
	}, "nodetool", "cfstats")
	return md, nil
}
Пример #24
0
func c_dfstat_darwin() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	util.ReadCommand(func(line string) error {
		fields := strings.Fields(line)
		if line == "" || len(fields) < 9 || !IsDigit(fields[2]) {
			return nil
		}
		mount := fields[8]
		if strings.HasPrefix(mount, "/Volumes/Time Machine Backups") {
			return nil
		}
		f5, _ := strconv.Atoi(fields[5])
		f6, _ := strconv.Atoi(fields[6])
		tags := opentsdb.TagSet{"mount": mount}
		Add(&md, "darwin.disk.fs.total", fields[1], tags, metadata.Unknown, metadata.None, "")
		Add(&md, "darwin.disk.fs.used", fields[2], tags, metadata.Unknown, metadata.None, "")
		Add(&md, "darwin.disk.fs.free", fields[3], tags, metadata.Unknown, metadata.None, "")
		Add(&md, "darwin.disk.fs.inodes.total", f5+f6, tags, metadata.Unknown, metadata.None, "")
		Add(&md, "darwin.disk.fs.inodes.used", fields[5], tags, metadata.Unknown, metadata.None, "")
		Add(&md, "darwin.disk.fs.inodes.free", fields[6], tags, metadata.Unknown, metadata.None, "")
		return nil
	}, "df", "-lki")
	return md, nil
}
Пример #25
0
func c_sntp_windows() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	const metric = "sntp."
	var (
		stratum string
		delay   float64
		when    float64
		source  string
		poll    float64
	)
	if err := util.ReadCommand(func(line string) error {
		f := strings.SplitN(line, ":", 2)
		if len(f) != 2 {
			return nil
		}
		f[1] = strings.TrimSpace(f[1])
		switch f[0] {
		case "Stratum":
			sf := strings.Fields(f[1])
			if len(sf) < 1 {
				return fmt.Errorf("Unexpected value for stratum")
			}
			stratum = sf[0]
		case "Root Delay":
			d, err := time.ParseDuration(f[1])
			if err != nil {
				return err
			}
			delay = d.Seconds()
		case "Last Successful Sync Time":
			if f[1] == "unspecified" {
				break
			}
			t, err := time.Parse("1/2/2006 3:04:05 PM", f[1])
			if err != nil {
				return err
			}
			when = time.Since(t).Seconds()
		case "Source":
			source = strings.TrimSpace(f[1])
		case "Poll Interval":
			sf := strings.Fields(f[1])
			if len(sf) != 2 {
				return fmt.Errorf("Unexpected value for Poll Interval")
			}
			s := strings.Trim(sf[1], "()")
			d, err := time.ParseDuration(strings.TrimSpace(s))
			if err != nil {
				return err
			}
			poll = d.Seconds()
		}
		return nil
	}, "w32tm", "/query", "/status"); err != nil {
		return nil, nil
	}
	tags := opentsdb.TagSet{"remote": source}
	Add(&md, metric+"stratum", stratum, tags, metadata.Gauge, "Stratum", "")
	Add(&md, metric+"delay", delay, tags, metadata.Gauge, metadata.Second, "")
	Add(&md, metric+"when", when, tags, metadata.Gauge, metadata.Second, "")
	Add(&md, metric+"poll", poll, tags, metadata.Gauge, metadata.Second, "")
	_ = util.ReadCommand(func(line string) error {
		f := strings.SplitN(line, ",", 2)
		if len(f) != 2 {
			return nil
		}
		d, err := time.ParseDuration(strings.TrimSpace(f[1]))
		if err != nil {
			return nil
		}
		Add(&md, metric+"offset", d.Seconds(), tags, metadata.Gauge, metadata.Second, "")
		return nil
	}, "w32tm", "/stripchart", fmt.Sprintf("/computer:%v", source), "/samples:1", "/dataonly")
	return md, nil
}
Пример #26
0
func c_nodestats_cfstats_linux() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	var keyspace, table string
	util.ReadCommand(func(line string) error {
		fields := strings.Split(strings.TrimSpace(line), ": ")
		if len(fields) != 2 {
			return nil
		}
		if fields[0] == "Keyspace" {
			keyspace = fields[1]
			table = ""
			return nil
		}
		if fields[0] == "Table" {
			table = fields[1]
			return nil
		}

		tagset := make(opentsdb.TagSet)
		metricset := make(MetricSet)

		if table != "" {
			tagset["table"] = table
		}
		if keyspace != "" {
			tagset["keyspace"] = keyspace
		}

		metric := strings.Replace(fields[0], " ", "_", -1)
		metric = strings.Replace(metric, "(", "", -1)
		metric = strings.Replace(metric, ")", "", -1)
		metric = strings.Replace(metric, ",", "", -1)
		metric = strings.ToLower(metric)

		/*  This is to handle lines like "SSTables in each level: [31/4, 0, 0, 0, 0, 0, 0, 0]"
		sstables_in_each_level format (BNF):
		     <count>         ::= <integer>
		     <max_threshold> ::= <integer>
		     <exceeded>      ::= <count> "/" <max_threshold>
		     <level_item>    ::= <count>|<exceeded>
		     <list_item>     ::= <level_item> "," " " | <level_item>
		     <list>          ::= <list_item> | <list_item> <list>
		     <per_level>     ::= "[" <list> "]"
		*/
		if metric == "sstables_in_each_level" {
			fields[1] = strings.Replace(fields[1], "[", "", -1)
			fields[1] = strings.Replace(fields[1], "]", "", -1)
			per_level := strings.Split(fields[1], ", ")
			for index, count := range per_level {
				metricset["cassandra.tables.sstables_in_level_"+strconv.Itoa(index)] = strings.Split(count, "/")[0]
			}
			submitMetrics(&md, metricset, tagset)
			return nil
		}

		// every other value is simpler, and we only want the first word
		values := strings.Fields(fields[1])
		if _, err := strconv.ParseFloat(values[0], 64); err != nil || values[0] == "NaN" {
			return nil
		}

		metricset["cassandra.tables."+metric] = values[0]

		submitMetrics(&md, metricset, tagset)
		return nil
	}, "nodetool", "cfstats")
	return md, nil
}