Пример #1
0
func extraHopGetCertificateByCount(c *gohop.Client, md *opentsdb.MultiDataPoint) error {
	//These are the metrics we are populating in this part of the collector
	metricNameCount := "extrahop.certificates"

	//Metadata for the above metrics
	metadata.AddMeta(metricNameCount, nil, "rate", metadata.Gauge, false)
	metadata.AddMeta(metricNameCount, nil, "unit", metadata.Count, false)
	metadata.AddMeta(metricNameCount, nil, "desc", "The number of times a given certificate was seen", false)

	ms := []gohop.MetricSpec{ //Build a metric spec to tell ExtraHop what we want to pull out.
		{Name: "cert_subject", KeyPair: gohop.KeyPair{Key1Regex: "", Key2Regex: "", OpenTSDBKey1: "", Key2OpenTSDBKey2: ""}, OpenTSDBMetric: metricNameCount},
	}
	mrk, err := c.KeyedMetricQuery(gohop.Cycle30Sec, "ssl_server_detail", "activity_group", -60000, 0, ms, []int64{int64(extraHopCertificateActivityGroup)})
	if err != nil {
		return err
	}

	//At this time we have a keyed metric response from ExtraHop. We need to find all the stats, then the values of the stats, and then
	//filter out to only the records we want.

	//This is our function that is going to be executed on each data point in the extrahop dataset
	appendCountPoints := func(c *gohop.Client, md *opentsdb.MultiDataPoint, a *gohop.MetricStatKeyed, b *[]gohop.MetricStatKeyedValue, d *gohop.MetricStatKeyedValue) {
		thisPoint := getSSLDataPointFromSet(metricNameCount, c.APIUrl.Host, a.Time, d)
		if thisPoint != nil {
			*md = append(*md, thisPoint)
		}
	}

	processGohopStat(&mrk, c, md, appendCountPoints) //This will loop through our datapoint structure and execute appendCountPoints on each final data piece

	return nil
}
Пример #2
0
// AddTS is the same as Add but lets you specify the timestamp
func AddTS(md *opentsdb.MultiDataPoint, name string, ts int64, value interface{}, t opentsdb.TagSet, rate metadata.RateType, unit metadata.Unit, desc string) {
	if b, ok := value.(bool); ok {
		if b {
			value = 1
		} else {
			value = 0
		}
	}
	tags := t.Copy()
	if host, present := tags["host"]; !present {
		tags["host"] = util.Hostname
	} else if host == "" {
		delete(tags, "host")
	}
	if rate != metadata.Unknown {
		metadata.AddMeta(name, nil, "rate", rate, false)
	}
	if unit != metadata.None {
		metadata.AddMeta(name, nil, "unit", unit, false)
	}
	if desc != "" {
		metadata.AddMeta(name, tags, "desc", desc, false)
	}

	tags = AddTags.Copy().Merge(tags)
	d := opentsdb.DataPoint{
		Metric:    name,
		Timestamp: ts,
		Value:     value,
		Tags:      tags,
	}
	*md = append(*md, &d)
}
Пример #3
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
}
Пример #4
0
// ExtraHop collection registration
func ExtraHop(host, apikey, filterby string, filterpercent int, customMetrics []string, certMatch string, certActivityGroup int) error {
	if host == "" || apikey == "" {
		return fmt.Errorf("Empty host or API key for ExtraHop.")
	}

	extraHopAdditionalMetrics = customMetrics
	extraHopFilterProtoBy = filterby
	switch filterby { //Set up options
	case "toppercent":
		extraHopL7Description = fmt.Sprintf("Only the top %d percent of traffic has its protocols logged, the remainder is tagged as as proto=otherprotos", extraHopTopProtoPerc)
		extraHopOtherProtoName = "otherprotos"
		if filterpercent > 0 && filterpercent < 100 {
			extraHopTopProtoPerc = filterpercent
		} else {
			return fmt.Errorf("Invalid ExtraHop FilterPercent value (%d). Number should be between 1 and 99.", filterpercent)
		}
	case "namedprotocols":
		extraHopL7Description = "Only named protocols are logged. Any unnamed protocol (A protocol name starting with tcp, udp or ssl) is tagged as proto=unnamed"
		extraHopOtherProtoName = "unnamed"
	//There is also case "none", but in that case the options we need to keep as default, so there's actually nothing to do here.
	default:
		return fmt.Errorf("Invalid ExtraHop FilterBy option (%s). Valid options are namedprotocols, toppercent or none.", filterby)

	}
	//Add the metadata for the L7 types, as now we have enough information to know what they're going to be
	for l7type, l7s := range l7types {
		xhMetricName := fmt.Sprintf("extrahop.l7.%s", l7type)
		metadata.AddMeta(xhMetricName, nil, "rate", l7s.Rate, false)
		metadata.AddMeta(xhMetricName, nil, "unit", l7s.Unit, false)
		metadata.AddMeta(xhMetricName, nil, "desc", fmt.Sprintf("%s %s", l7s.Description, extraHopL7Description), false)
	}
	u, err := url.Parse(host)
	if err != nil {
		return err
	}

	if certMatch != "" {
		compiledRegexp, err := regexp.Compile(certMatch)
		if err != nil {
			return err
		}
		extraHopCertificateMatch = compiledRegexp
		extraHopCertificateActivityGroup = certActivityGroup
	}
	collectors = append(collectors, &IntervalCollector{
		F: func() (opentsdb.MultiDataPoint, error) {
			return c_extrahop(host, apikey)
		},
		name:     fmt.Sprintf("extrahop-%s", u.Host),
		Interval: time.Second * time.Duration(extraHopIntervalSeconds),
	})
	return nil

}
Пример #5
0
// AddTS is the same as Add but lets you specify the timestamp
func AddTS(md *opentsdb.MultiDataPoint, name string, ts int64, value interface{}, t opentsdb.TagSet, rate metadata.RateType, unit metadata.Unit, desc string) {
	// Check if we really want that metric
	if skipMetric(name) {
		return
	}

	tags := t.Copy()
	if host, present := tags["host"]; !present {
		tags["host"] = util.Hostname
	} else if host == "" {
		delete(tags, "host")
	}
	// if tags are not cleanable, log a message and skip it
	if err := tags.Clean(); err != nil {
		line := ""
		//attempt to log where Add was called from
		if _, filename, l, ok := runtime.Caller(1); ok {
			if filepath.Base(filename) == "collectors.go" {
				_, filename, l, ok = runtime.Caller(2)
			}
			if ok {
				line = fmt.Sprintf("%s:%d", filepath.Base(filename), l)
			}
		}
		slog.Errorf("Invalid tagset discovered: %s. Skipping datapoint. Added from: %s", tags.String(), line)
		return
	}
	if rate != metadata.Unknown {
		metadata.AddMeta(name, nil, "rate", rate, false)
	}
	if unit != metadata.None {
		metadata.AddMeta(name, nil, "unit", unit, false)
	}
	if desc != "" {
		metadata.AddMeta(name, tags, "desc", desc, false)
	}
	tags = AddTags.Copy().Merge(tags)
	if b, ok := value.(bool); ok {
		if b {
			value = 1
		} else {
			value = 0
		}
	}
	d := opentsdb.DataPoint{
		Metric:    name,
		Timestamp: ts,
		Value:     value,
		Tags:      tags,
	}
	*md = append(*md, &d)
}
Пример #6
0
func c_omreport_ps() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	readOmreport(func(fields []string) {
		if len(fields) < 3 || fields[0] == "Index" {
			return
		}
		id := strings.Replace(fields[0], ":", "_", -1)
		ts := opentsdb.TagSet{"id": id}
		Add(&md, "hw.ps", severity(fields[1]), ts, metadata.Gauge, metadata.Ok, descDellHWPS)
		pm := &metadata.HWPowerSupply{}
		if len(fields) < 6 {
			return
		}
		if fields[4] != "" {
			pm.RatedInputWattage = fields[4]
		}
		if fields[5] != "" {
			pm.RatedOutputWattage = fields[5]
		}
		if j, err := json.Marshal(&pm); err == nil {
			metadata.AddMeta("", ts, "psMeta", string(j), true)
		} else {
			slog.Error(err)
		}
	}, "chassis", "pwrsupplies")
	return md, nil
}
Пример #7
0
func c_diskspace_windows() (opentsdb.MultiDataPoint, error) {
	var dst []Win32_LogicalDisk
	var q = wmi.CreateQuery(&dst, "WHERE DriveType = 3 AND FreeSpace <> null")
	err := queryWmi(q, &dst)
	if err != nil {
		return nil, err
	}
	var md opentsdb.MultiDataPoint
	for _, v := range dst {
		tags := opentsdb.TagSet{"disk": v.Name}
		space_used := v.Size - v.FreeSpace
		Add(&md, "win.disk.fs.space_free", v.FreeSpace, tags, metadata.Gauge, metadata.Bytes, osDiskFreeDesc)
		Add(&md, "win.disk.fs.space_total", v.Size, tags, metadata.Gauge, metadata.Bytes, osDiskTotalDesc)
		Add(&md, "win.disk.fs.space_used", space_used, tags, metadata.Gauge, metadata.Bytes, osDiskUsedDesc)
		Add(&md, osDiskFree, v.FreeSpace, tags, metadata.Gauge, metadata.Bytes, osDiskFreeDesc)
		Add(&md, osDiskTotal, v.Size, tags, metadata.Gauge, metadata.Bytes, osDiskTotalDesc)
		Add(&md, osDiskUsed, space_used, tags, metadata.Gauge, metadata.Bytes, osDiskUsedDesc)
		if v.Size != 0 {
			percent_free := float64(v.FreeSpace) / float64(v.Size) * 100
			Add(&md, "win.disk.fs.percent_free", percent_free, tags, metadata.Gauge, metadata.Pct, osDiskPctFreeDesc)
			Add(&md, osDiskPctFree, percent_free, tags, metadata.Gauge, metadata.Pct, osDiskPctFreeDesc)
		}
		if v.VolumeName != "" {
			metadata.AddMeta("", tags, "label", v.VolumeName, true)
		}
	}
	return md, nil
}
Пример #8
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
}
Пример #9
0
func c_meta_linux_ifaces() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	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
				metadata.AddMeta("", tags, "speed", v*MbitToBit, true)
			}
		}
		_ = util.ReadCommand(func(line string) error {
			if v := metaLinuxIfacesMaster(line); v != "" {
				metadata.AddMeta("", tags, "master", v, true)
				return doneErr
			}
			return nil
		}, "ip", "-o", "addr", "show", iface.Name)
	})
	return md, nil
}
Пример #10
0
func c_fortinet_meta(host, community string) (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	ts := opentsdb.TagSet{"host": host}
	serial, err := snmpOidString(host, community, fortinetBaseOID+fortinetSerial)
	if err != nil {
		return md, fmt.Errorf("failed to get serial for host %v: %v", host, err)
	}
	metadata.AddMeta("", ts, "serialNumber", serial, false)
	version, err := snmpOidString(host, community, fortinetBaseOID+fortinetVersion)
	if err != nil {
		return md, fmt.Errorf("failed to get serial for host %v: %v", host, err)
	}
	if version == "" {
		return md, fmt.Errorf("got empty os version string for host %v", host)
	}
	// Fortinet could come from the manufactor oid, but since this is a fortinet
	// only collector saving the extra poll call
	metadata.AddMeta("", ts, "versionCaption", fmt.Sprintf("Fortinet: %v", version), false)
	return md, nil
}
Пример #11
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
}
Пример #12
0
func c_cisco_desc(host, community string) (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	desc, err := getSNMPDesc(host, community)
	if err != nil {
		return md, err
	}
	if desc == "" {
		return md, fmt.Errorf("empty description string (used to get OS version) for cisco host %v", host)
	}
	metadata.AddMeta("", opentsdb.TagSet{"host": host}, "versionCaption", desc, false)
	return md, nil
}
Пример #13
0
func metaIfaces(f func(iface net.Interface, tags opentsdb.TagSet)) {
	ifaces, _ := net.Interfaces()
	for _, iface := range ifaces {
		if strings.HasPrefix(iface.Name, "lo") {
			continue
		}
		tags := opentsdb.TagSet{"iface": fmt.Sprint("Interface", iface.Index)}
		metadata.AddMeta("", tags, "name", iface.Name, true)
		if mac := iface.HardwareAddr.String(); mac != "" {
			metadata.AddMeta("", tags, "mac", iface.HardwareAddr.String(), true)
		}
		ads, _ := iface.Addrs()
		for i, ad := range ads {
			addr := strings.Split(ad.String(), "/")[0]
			metadata.AddMeta("", opentsdb.TagSet{"addr": fmt.Sprint("Addr", i)}.Merge(tags), "addr", addr, true)
		}
		if f != nil {
			f(iface, tags)
		}
	}
}
Пример #14
0
func putMetadata(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	d := json.NewDecoder(r.Body)
	var ms []metadata.Metasend
	if err := d.Decode(&ms); err != nil {
		w.WriteHeader(500)
		return
	}
	for _, m := range ms {
		metadata.AddMeta(m.Metric, m.Tags.Copy(), m.Name, m.Value, true)
	}
	w.WriteHeader(204)
}
Пример #15
0
// c_omreport_storage_pdisk is called from the controller func, since it needs the encapsulating id.
func c_omreport_storage_pdisk(id string, md *opentsdb.MultiDataPoint) {
	readOmreport(func(fields []string) {
		if len(fields) < 3 || fields[0] == "ID" {
			return
		}
		//Need to find out what the various ID formats might be
		id := strings.Replace(fields[0], ":", "_", -1)
		ts := opentsdb.TagSet{"id": id}
		Add(md, "hw.storage.pdisk", severity(fields[1]), ts, metadata.Gauge, metadata.Ok, descDellHWPDisk)
		if len(fields) < 32 {
			return
		}
		dm := &metadata.HWDiskMeta{}
		if fields[2] != "" {
			dm.Name = fields[2]
		}
		if fields[6] != "" {
			dm.Media = fields[6]
		}
		if fields[19] != "" {
			dm.Capacity = fields[19]
		}
		if fields[23] != "" {
			dm.VendorId = fields[23]
		}
		if fields[24] != "" {
			dm.ProductId = fields[24]
		}
		if fields[25] != "" {
			dm.Serial = fields[25]
		}
		if fields[26] != "" {
			dm.Part = fields[26]
		}
		if fields[27] != "" {
			dm.NegotatiedSpeed = fields[27]
		}
		if fields[28] != "" {
			dm.CapableSpeed = fields[28]
		}
		if fields[31] != "" {
			dm.SectorSize = fields[31]

		}
		if j, err := json.Marshal(&dm); err == nil {
			metadata.AddMeta("", ts, "physicalDiskMeta", string(j), true)
		} else {
			slog.Error(err)
		}
	}, "storage", "pdisk", "controller="+id)
}
Пример #16
0
func puppet_linux() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	// See if puppet has been disabled (i.e. `puppet agent --disable 'Reason'`)
	var disabled, noReason int
	if v, err := ioutil.ReadFile(puppetDisabled); err == nil {
		disabled = 1
		d := struct {
			Disabled string `json:"disabled_message"`
		}{}
		if err := json.Unmarshal(v, &d); err == nil && d.Disabled != "" {
			if d.Disabled == "reason not specified" {
				noReason = 1
			}
			metadata.AddMeta("", nil, "puppet.disabled_reason", d.Disabled, true)
		}
	}
	Add(&md, "puppet.disabled", disabled, nil, metadata.Gauge, metadata.Count, "")
	Add(&md, "puppet.disabled_no_reason", noReason, nil, metadata.Gauge, metadata.Count, "")
	// Gather stats from the run summary
	s, err := ioutil.ReadFile(puppetRunSummary)
	if err != nil {
		return nil, err
	}
	var m PRSummary
	if err = yaml.Unmarshal(s, &m); err != nil {
		return nil, err
	}
	last_run, err := strconv.ParseInt(m.Time["last_run"], 10, 64)
	//m.Version.Config appears to be the unix timestamp
	AddTS(&md, "puppet.run.resources", last_run, m.Resources.Changed, opentsdb.TagSet{"resource": "changed"}, metadata.Gauge, metadata.Count, descPuppetChanged)
	AddTS(&md, "puppet.run.resources", last_run, m.Resources.Failed, opentsdb.TagSet{"resource": "failed"}, metadata.Gauge, metadata.Count, descPuppetFailed)
	AddTS(&md, "puppet.run.resources", last_run, m.Resources.FailedToRestart, opentsdb.TagSet{"resource": "failed_to_restart"}, metadata.Gauge, metadata.Count, descPuppetFailedToRestart)
	AddTS(&md, "puppet.run.resources", last_run, m.Resources.OutOfSync, opentsdb.TagSet{"resource": "out_of_sync"}, metadata.Gauge, metadata.Count, descPuppetOutOfSync)
	AddTS(&md, "puppet.run.resources", last_run, m.Resources.Restarted, opentsdb.TagSet{"resource": "restarted"}, metadata.Gauge, metadata.Count, descPuppetRestarted)
	AddTS(&md, "puppet.run.resources", last_run, m.Resources.Scheduled, opentsdb.TagSet{"resource": "scheduled"}, metadata.Gauge, metadata.Count, descPuppetScheduled)
	AddTS(&md, "puppet.run.resources", last_run, m.Resources.Skipped, opentsdb.TagSet{"resource": "skipped"}, metadata.Gauge, metadata.Count, descPuppetSkipped)
	AddTS(&md, "puppet.run.resources_total", last_run, m.Resources.Total, nil, metadata.Gauge, metadata.Count, descPuppetTotalResources)
	AddTS(&md, "puppet.run.changes", last_run, m.Changes.Total, nil, metadata.Gauge, metadata.Count, descPuppetTotalChanges)
	for k, v := range m.Time {
		metric, err := strconv.ParseFloat(v, 64)
		if err != nil {
			if k == "total" {
				AddTS(&md, "puppet.run_duration_total", last_run, metric, nil, metadata.Gauge, metadata.Second, descPuppetTotalTime)
			} else {
				AddTS(&md, "puppet.run_duration", last_run, metric, opentsdb.TagSet{"time": k}, metadata.Gauge, metadata.Second, descPuppetModuleTime)
			}
		}
	}
	return md, nil
}
Пример #17
0
func c_snmp_ips(community, host string) (opentsdb.MultiDataPoint, error) {
	ifIPAdEntAddrRaw, err := snmp_subtree(host, community, ifIPAdEntAddr)
	if err != nil {
		return nil, err
	}
	ipAdEnts := make(map[string]*ipAdEntAddr)
	for id, value := range ifIPAdEntAddrRaw {
		// Split entry type id from ip address
		sp := strings.SplitN(id, ".", 2)
		if len(sp) != 2 {
			slog.Errorln("unexpected length of snmp resonse")
		}
		typeId := sp[0]
		address := sp[1]
		if _, ok := ipAdEnts[address]; !ok {
			ipAdEnts[address] = &ipAdEntAddr{}
		}
		switch typeId {
		case "1":
			if v, ok := value.([]byte); ok {
				ipAdEnts[address].IP = v
			}
		case "2":
			if v, ok := value.(int64); ok {
				ipAdEnts[address].InterfaceId = v
			}
		case "3":
			if v, ok := value.([]byte); ok {
				ipAdEnts[address].Mask = v
			}
		}
	}
	ipsByInt := make(map[int64][]net.IPNet)
	for _, ipNet := range ipAdEnts {
		ipsByInt[ipNet.InterfaceId] = append(ipsByInt[ipNet.InterfaceId], ipNet.IPNet)
	}
	for intId, ipNets := range ipsByInt {
		var ips []string
		for _, ipNet := range ipNets {
			ips = append(ips, ipNet.String())
		}
		sort.Strings(ips)
		j, err := json.Marshal(ips)
		if err != nil {
			slog.Errorf("error marshaling ips for host %v: %v", host, err)
		}
		metadata.AddMeta("", opentsdb.TagSet{"host": host, "iface": fmt.Sprintf("%v", intId)}, "addresses", string(j), false)
	}
	return nil, nil
}
Пример #18
0
func metaIfaces(f func(iface net.Interface, tags opentsdb.TagSet)) {
	ifaces, _ := net.Interfaces()
	for _, iface := range ifaces {
		if strings.HasPrefix(iface.Name, "lo") {
			continue
		}
		tags := opentsdb.TagSet{"iface": iface.Name}
		metadata.AddMeta("", tags, "name", iface.Name, true)
		if mac := strings.ToUpper(strings.Replace(iface.HardwareAddr.String(), ":", "", -1)); mac != "" {
			metadata.AddMeta("", tags, "mac", mac, true)
		}
		rawAds, _ := iface.Addrs()
		addrs := make([]string, len(rawAds))
		for i, rAd := range rawAds {
			addrs[i] = rAd.String()
		}
		sort.Strings(addrs)
		j, _ := json.Marshal(addrs)
		metadata.AddMeta("", tags, "addresses", string(j), true)
		if f != nil {
			f(iface, tags)
		}
	}
}
Пример #19
0
func c_omreport_memory() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	readOmreport(func(fields []string) {
		if len(fields) != 5 {
			return
		}
		if _, err := strconv.Atoi(fields[0]); err != nil {
			return
		}
		ts := opentsdb.TagSet{"name": replace(fields[2])}
		Add(&md, "hw.chassis.memory", severity(fields[1]), ts, metadata.Gauge, metadata.Ok, descDellHWMemory)
		metadata.AddMeta("", ts, "memory", clean(fields[4]), true)
	}, "chassis", "memory")
	return md, nil
}
Пример #20
0
func readOSRelease() bool {
	var found bool
	_ = readLine("/etc/os-release", func(s string) error {
		fields := strings.SplitN(s, "=", 2)
		if len(fields) != 2 {
			return nil
		}
		if fields[0] == "PRETTY_NAME" {
			metadata.AddMeta("", nil, "version", strings.Trim(fields[1], `"`), true)
			found = true
		}
		return nil
	})
	return found
}
Пример #21
0
func c_snmp_cdp(community, host string) (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	cdpEntries := make(map[string]*cdpCacheEntry)
	deviceIdRaw, err := snmp_subtree(host, community, cdpCacheDeviceId)
	if err != nil {
		return md, err
	}
	for k, v := range deviceIdRaw {
		ids := strings.Split(k, ".")
		if len(ids) != 2 {
			slog.Error("unexpected snmp cdpCacheEntry id")
			continue
		}
		cdpEntries[ids[0]] = &cdpCacheEntry{}
		cdpEntries[ids[0]].DeviceId = fmt.Sprintf("%s", v)
		cdpEntries[ids[0]].InterfaceId = ids[1]
	}
	devicePortRaw, err := snmp_subtree(host, community, cdpCacheDevicePort)
	for k, v := range devicePortRaw {
		ids := strings.Split(k, ".")
		if len(ids) != 2 {
			slog.Error("unexpected snmp cdpCacheEntry id")
			continue
		}
		if entry, ok := cdpEntries[ids[0]]; ok {
			entry.DevicePort = fmt.Sprintf("%s", v)
		}
	}
	byInterface := make(map[string][]*cdpCacheEntry)
	for _, entry := range cdpEntries {
		if _, ok := byInterface[entry.InterfaceId]; ok {
			byInterface[entry.InterfaceId] = append(byInterface[entry.InterfaceId], entry)
		} else {
			byInterface[entry.InterfaceId] = []*cdpCacheEntry{entry}
		}
	}
	for iface, entry := range byInterface {
		j, err := json.Marshal(entry)
		if err != nil {
			return md, err
		}
		metadata.AddMeta("", opentsdb.TagSet{"host": host, "iface": iface}, "cdpCacheEntries", string(j), false)
	}
	if err != nil {
		return md, nil
	}
	return md, nil
}
Пример #22
0
func readIssue() {
	_ = 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
		}
		metadata.AddMeta("", nil, "version", strings.Join(fields, " "), true)
		return nil
	}, "cat", "/etc/issue")
}
Пример #23
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
}
Пример #24
0
func c_omreport_storage_controller() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	readOmreport(func(fields []string) {
		if len(fields) < 3 || fields[0] == "ID" {
			return
		}
		c_omreport_storage_pdisk(fields[0], &md)
		id := strings.Replace(fields[0], ":", "_", -1)
		ts := opentsdb.TagSet{"id": id}
		Add(&md, "hw.storage.controller", severity(fields[1]), ts, metadata.Gauge, metadata.Ok, descDellHWStorageCtl)
		cm := &metadata.HWControllerMeta{}
		if len(fields) < 8 {
			return
		}
		if fields[2] != "" {
			cm.Name = fields[2]
		}
		if fields[3] != "" {
			cm.SlotId = fields[3]
		}
		if fields[4] != "" {
			cm.State = fields[4]
		}
		if fields[5] != "" {
			cm.FirmwareVersion = fields[5]
		}
		if fields[7] != "" {
			cm.DriverVersion = fields[7]
		}
		if j, err := json.Marshal(&cm); err == nil {
			metadata.AddMeta("", ts, "controllerMeta", string(j), true)
		} else {
			slog.Error(err)
		}
	}, "storage", "controller")
	return md, nil
}
Пример #25
0
func c_meta_windows_version() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	var dst []Win32_OperatingSystem
	q := wmi.CreateQuery(&dst, "")
	err := wmi.Query(q, &dst)
	if err != nil {
		slog.Error(err)
		return md, err
	}

	var dstComputer []Win32_ComputerSystem
	q = wmi.CreateQuery(&dstComputer, "")
	err = wmi.Query(q, &dstComputer)
	if err != nil {
		slog.Error(err)
		return md, err
	}

	var dstBIOS []Win32_BIOS
	q = wmi.CreateQuery(&dstBIOS, "")
	err = wmi.Query(q, &dstBIOS)
	if err != nil {
		slog.Error(err)
		return md, err
	}

	for _, v := range dst {
		metadata.AddMeta("", nil, "version", v.Version, true)
		metadata.AddMeta("", nil, "versionCaption", v.Caption, true)
	}

	for _, v := range dstComputer {
		metadata.AddMeta("", nil, "manufacturer", v.Manufacturer, true)
		metadata.AddMeta("", nil, "model", v.Model, true)
		metadata.AddMeta("", nil, "memoryTotal", v.TotalPhysicalMemory, true)
	}

	for _, v := range dstBIOS {
		metadata.AddMeta("", nil, "serialNumber", v.SerialNumber, true)
	}
	return md, nil
}
Пример #26
0
func c_snmp_ifaces(community, host string) (opentsdb.MultiDataPoint, error) {
	ifNamesRaw, err := snmp_subtree(host, community, ifName)
	if err != nil || len(ifNamesRaw) == 0 {
		ifNamesRaw, err = snmp_subtree(host, community, ifDescr)
		if err != nil {
			return nil, err
		}
	}
	ifAliasesRaw, err := snmp_subtree(host, community, ifAlias)
	if err != nil {
		return nil, err
	}
	ifTypesRaw, err := snmp_subtree(host, community, ifType)
	if err != nil {
		return nil, err
	}
	ifNames := make(map[interface{}]string, len(ifNamesRaw))
	ifAliases := make(map[interface{}]string, len(ifAliasesRaw))
	ifTypes := make(map[interface{}]int64, len(ifTypesRaw))
	for k, v := range ifNamesRaw {
		ifNames[k] = fmt.Sprintf("%s", v)
	}
	for k, v := range ifTypesRaw {
		val, ok := v.(int64)
		if !ok {
			return nil, fmt.Errorf("unexpected type from from MIB::ifType")
		}
		ifTypes[k] = val
	}
	for k, v := range ifAliasesRaw {
		// In case clean would come up empty, prevent the point from being removed
		// by setting our own empty case.
		ifAliases[k], _ = opentsdb.Clean(fmt.Sprintf("%s", v))
		if ifAliases[k] == "" {
			ifAliases[k] = "NA"
		}
	}
	var md opentsdb.MultiDataPoint
	add := func(sA snmpAdd) error {
		m, err := snmp_subtree(host, community, sA.oid)
		if err != nil {
			return err
		}
		var sum int64
		for k, v := range m {
			tags := opentsdb.TagSet{
				"host":  host,
				"iface": fmt.Sprintf("%s", k),
				"iname": ifNames[k],
			}
			if sA.dir != "" {
				tags["direction"] = sA.dir
			}
			if iVal, ok := v.(int64); ok && ifTypes[k] == 6 {
				sum += iVal
			}
			Add(&md, switchInterfaceMetric(sA.metric, ifNames[k], ifTypes[k]), v, tags, sA.rate, sA.unit, sA.desc)
			metadata.AddMeta("", tags, "alias", ifAliases[k], false)
		}
		if sA.metric == osNetBytes {
			tags := opentsdb.TagSet{"host": host, "direction": sA.dir}
			Add(&md, osNetBytes+".total", sum, tags, metadata.Counter, metadata.Bytes, "The total number of bytes transfered through the network device.")
		}
		return nil
	}
	oids := []snmpAdd{
		{ifHCInBroadcastPkts, osNetBroadcast, "in", metadata.Counter, metadata.Packet, osNetBroadcastDesc},
		{ifHCInMulticastPkts, osNetMulticast, "in", metadata.Counter, metadata.Packet, osNetMulticastDesc},
		{ifHCInUcastPkts, osNetUnicast, "in", metadata.Counter, metadata.Packet, osNetUnicastDesc},
		{ifHCOutBroadcastPkts, osNetBroadcast, "out", metadata.Counter, metadata.Packet, osNetBroadcastDesc},
		{ifHCOutMulticastPkts, osNetMulticast, "out", metadata.Counter, metadata.Packet, osNetMulticastDesc},
		{ifHCOutOctets, osNetBytes, "out", metadata.Counter, metadata.Bytes, osNetBytesDesc},
		{ifHCOutUcastPkts, osNetUnicast, "out", metadata.Counter, metadata.Packet, osNetUnicastDesc},
		{ifHCinOctets, osNetBytes, "in", metadata.Counter, metadata.Bytes, osNetBytesDesc},
		{ifInDiscards, osNetDropped, "in", metadata.Counter, metadata.Packet, osNetDroppedDesc},
		{ifInErrors, osNetErrors, "in", metadata.Counter, metadata.Error, osNetErrorsDesc},
		{ifOutDiscards, osNetDropped, "out", metadata.Counter, metadata.Packet, osNetDroppedDesc},
		{ifOutErrors, osNetErrors, "out", metadata.Counter, metadata.Error, osNetErrorsDesc},
		{ifInPauseFrames, osNetPauseFrames, "in", metadata.Counter, metadata.Frame, osNetPauseFrameDesc},
		{ifOutPauseFrames, osNetPauseFrames, "out", metadata.Counter, metadata.Frame, osNetPauseFrameDesc},
		{ifMTU, osNetMTU, "", metadata.Gauge, metadata.Bytes, osNetMTUDesc},
		{ifHighSpeed, osNetifspeed, "", metadata.Gauge, metadata.Megabit, osNetIfspeedDesc},
		{ifAdminStatus, osNetAdminStatus, "", metadata.Gauge, metadata.StatusCode, osNetAdminStatusDesc},
		{ifOperStatus, osNetOperStatus, "", metadata.Gauge, metadata.StatusCode, osNetOperStatusDesc},
	}
	for _, sA := range oids {
		if err := add(sA); err != nil {
			return nil, err
		}
	}
	return md, nil
}
Пример #27
0
func (c *ProgramCollector) runProgram(dpchan chan<- *opentsdb.DataPoint) (progError error) {
	cmd := exec.Command(c.Path)
	setupExternalCommand(cmd)
	pr, pw := io.Pipe()
	s := bufio.NewScanner(pr)
	cmd.Stdout = pw
	er, ew := io.Pipe()
	cmd.Stderr = ew
	if err := cmd.Start(); err != nil {
		return err
	}
	go func() {
		progError = cmd.Wait()
		pw.Close()
		ew.Close()
	}()
	go func() {
		es := bufio.NewScanner(er)
		for es.Scan() {
			line := strings.TrimSpace(es.Text())
			slog.Error(line)
		}
	}()
	for s.Scan() {
		var errs []error
		t := strings.TrimSpace(s.Text())
		if len(t) == 0 {
			continue
		}
		if dp, err := parseTcollectorValue(t); err == nil {
			dpchan <- dp
			continue
		} else {
			errs = append(errs, fmt.Errorf("tcollector: %v", err))
		}
		var dp opentsdb.DataPoint
		if err := json.Unmarshal([]byte(t), &dp); err != nil {
			errs = append(errs, fmt.Errorf("opentsdb.DataPoint: %v", err))
		} else if dp.Valid() {
			if dp.Tags == nil {
				dp.Tags = opentsdb.TagSet{}
			}
			setExternalTags(dp.Tags)
			c.ApplyTags(dp.Tags)
			dpchan <- &dp
			continue
		} else {
			errs = append(errs, fmt.Errorf("opentsdb.DataPoint: invalid data"))
		}
		var m metadata.Metasend
		if err := json.Unmarshal([]byte(t), &m); err != nil {
			errs = append(errs, fmt.Errorf("metadata.Metasend: %v", err))
		} else {
			if m.Tags == nil {
				m.Tags = opentsdb.TagSet{}
			}
			setExternalTags(m.Tags)
			if m.Value == "" || m.Name == "" || (m.Metric == "" && len(m.Tags) == 0) {
				errs = append(errs, fmt.Errorf("metadata.Metasend: invalid data"))
			} else {
				metadata.AddMeta(m.Metric, m.Tags, m.Name, m.Value, false)
				continue
			}
		}
		slog.Errorf("%s: unparseable line: %s", c.Path, t)
		for _, e := range errs {
			slog.Error(e)
		}
	}
	if err := s.Err(); err != nil {
		return err
	}
	return
}
Пример #28
0
func c_snmp_bridge(community, host string) (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	vlanRaw, err := snmp_subtree(host, community, vtpVlanState)
	if err != nil {
		return md, err
	}
	vlans := []string{}
	for vlan, state := range vlanRaw {
		Add(&md, "cisco.net.vlan_state", state, opentsdb.TagSet{"host": host, "vlan": vlan}, metadata.Gauge, metadata.StatusCode, "")
		vlans = append(vlans, vlan)
	}
	ifMacs := make(map[string][]string)
	for _, vlan := range vlans {
		// community string indexing: http://www.cisco.com/c/en/us/support/docs/ip/simple-network-management-protocol-snmp/40367-camsnmp40367.html
		macRaw, err := snmp_subtree(host, community+"@"+vlan, dot1dTpFdbAddress)
		if err != nil {
			slog.Infoln(err)
			// continue since it might just be the one vlan
			continue
		}
		remoteMacAddresses := make(map[string]string)
		for k, v := range macRaw {
			if ba, ok := v.([]byte); ok {
				remoteMacAddresses[k] = strings.ToUpper(hex.EncodeToString(ba))
			}
		}
		toPort := make(map[string]string)
		toPortRaw, err := snmp_subtree(host, community+"@"+vlan, dot1dTpFdbPort)
		if err != nil {
			slog.Infoln(err)
		}
		for k, v := range toPortRaw {
			toPort[k] = fmt.Sprintf("%v", v)
		}
		portToIfIndex := make(map[string]string)
		portToIfIndexRaw, err := snmp_subtree(host, community+"@"+vlan, dot1dBasePortIfIndex)
		for k, v := range portToIfIndexRaw {
			portToIfIndex[k] = fmt.Sprintf("%v", v)
		}
		if err != nil {
			slog.Infoln(err)
		}
		for port, mac := range remoteMacAddresses {
			if port, ok := toPort[port]; ok {
				if ifIndex, ok := portToIfIndex[port]; ok {
					if _, ok := ifMacs[ifIndex]; ok {
						ifMacs[ifIndex] = append(ifMacs[ifIndex], mac)
					} else {
						ifMacs[ifIndex] = []string{mac}
					}
				}
			}
		}
	}
	for iface, macs := range ifMacs {
		j, err := json.Marshal(macs)
		if err != nil {
			return md, nil
		}
		metadata.AddMeta("", opentsdb.TagSet{"host": host, "iface": iface}, "remoteMacs", string(j), false)
	}
	return md, nil
}
Пример #29
0
func c_snmp_ifaces(community, host string) (opentsdb.MultiDataPoint, error) {
	n, err := snmp_subtree(host, community, ifName)
	if err != nil || len(n) == 0 {
		n, err = snmp_subtree(host, community, ifDescr)
		if err != nil {
			return nil, err
		}
	}
	a, err := snmp_subtree(host, community, ifAlias)
	if err != nil {
		return nil, err
	}
	names := make(map[interface{}]string, len(n))
	aliases := make(map[interface{}]string, len(a))
	for k, v := range n {
		names[k] = fmt.Sprintf("%s", v)
	}
	for k, v := range a {
		// In case clean would come up empty, prevent the point from being removed
		// by setting our own empty case.
		aliases[k], _ = opentsdb.Clean(fmt.Sprintf("%s", v))
		if aliases[k] == "" {
			aliases[k] = "NA"
		}
	}
	var md opentsdb.MultiDataPoint
	add := func(oid, metric, dir string) error {
		m, err := snmp_subtree(host, community, oid)
		if err != nil {
			return err
		}
		for k, v := range m {
			tags := opentsdb.TagSet{
				"host":      host,
				"direction": dir,
				"iface":     fmt.Sprintf("%d", k),
				"iname":     names[k],
			}
			Add(&md, switch_bond(metric, names[k]), v, tags, metadata.Unknown, metadata.None, "")
			metadata.AddMeta("", tags, "alias", aliases[k], false)
		}
		return nil
	}
	oids := []snmpAdd{
		{ifHCInBroadcastPkts, osNetBroadcast, "in"},
		{ifHCInMulticastPkts, osNetMulticast, "in"},
		{ifHCInUcastPkts, osNetUnicast, "in"},
		{ifHCOutBroadcastPkts, osNetBroadcast, "out"},
		{ifHCOutMulticastPkts, osNetMulticast, "out"},
		{ifHCOutOctets, osNetBytes, "out"},
		{ifHCOutUcastPkts, osNetUnicast, "out"},
		{ifHCinOctets, osNetBytes, "in"},
		{ifInDiscards, osNetDropped, "in"},
		{ifInErrors, osNetErrors, "in"},
		{ifOutDiscards, osNetDropped, "out"},
		{ifOutErrors, osNetErrors, "out"},
		{ifInPauseFrames, osNetPauseFrames, "in"},
		{ifOutPauseFrames, osNetPauseFrames, "out"},
	}
	for _, o := range oids {
		if err := add(o.oid, o.metric, o.dir); err != nil {
			return nil, err
		}
	}
	return md, nil
}
Пример #30
0
func c_meta_windows_ifaces() (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	var dstConfigs []Win32_NetworkAdapterConfiguration
	q := wmi.CreateQuery(&dstConfigs, "WHERE MACAddress != null")
	err := wmi.Query(q, &dstConfigs)
	if err != nil {
		slog.Error(err)
		return md, err
	}

	mNicConfigs := make(map[uint32]*Win32_NetworkAdapterConfiguration)
	for i, nic := range dstConfigs {
		mNicConfigs[nic.InterfaceIndex] = &dstConfigs[i]
	}

	mNicTeamIDtoSpeed := make(map[string]uint64)
	mNicTeamIDtoMaster := make(map[string]string)
	var dstTeamMembers []MSFT_NetLbfoTeamMember
	q = wmi.CreateQuery(&dstTeamMembers, "")
	err = wmi.QueryNamespace(q, &dstTeamMembers, "root\\StandardCimv2")
	if err == nil {
		for _, teamMember := range dstTeamMembers {
			mNicTeamIDtoSpeed[teamMember.InstanceID] = teamMember.ReceiveLinkSpeed
			mNicTeamIDtoMaster[teamMember.InstanceID] = teamMember.Team
		}
	}

	var dstAdapters []Win32_NetworkAdapter
	q = wmi.CreateQuery(&dstAdapters, "WHERE PhysicalAdapter=True and MACAddress <> null and NetConnectionStatus = 2") //Only adapters with MAC addresses and status="Connected"
	err = wmi.Query(q, &dstAdapters)
	if err != nil {
		slog.Error(err)
		return md, err
	}

	mNicIndextoIPs := make(map[int]string)
	ifaces, _ := net.Interfaces()
	for _, iface := range ifaces {
		if iface.Flags&(net.FlagLoopback|net.FlagPointToPoint) != 0 {
			continue
		}
		rawAds, _ := iface.Addrs()
		addrs := make([]string, len(rawAds))
		for i, rAd := range rawAds {
			addrs[i] = rAd.String()
		}
		sort.Strings(addrs)
		j, _ := json.Marshal(addrs)
		mNicIndextoIPs[iface.Index] = string(j)
	}

	for _, v := range dstAdapters {
		tag := opentsdb.TagSet{"iface": fmt.Sprint("Interface", v.InterfaceIndex)}
		metadata.AddMeta("", tag, "description", v.Description, true)
		metadata.AddMeta("", tag, "name", v.NetConnectionID, true)
		metadata.AddMeta("", tag, "mac", strings.Replace(v.MACAddress, ":", "", -1), true)
		if v.Speed != nil && *v.Speed != 0 {
			metadata.AddMeta("", tag, "speed", v.Speed, true)
		} else {
			nicSpeed := mNicTeamIDtoSpeed[v.GUID]
			metadata.AddMeta("", tag, "speed", nicSpeed, true)
		}

		nicMaster := mNicTeamIDtoMaster[v.GUID]
		if nicMaster != "" {
			metadata.AddMeta("", tag, "master", nicMaster, true)
		}

		nicIPs := mNicIndextoIPs[int(v.InterfaceIndex)]
		if nicIPs == "" {
			nicIPs = "[]"
		}
		metadata.AddMeta("", tag, "addresses", nicIPs, true)
	}
	return md, nil
}