Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/scollector: Monitoring teams interfaces #1280

Merged
merged 1 commit into from
Aug 28, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 165 additions & 0 deletions cmd/scollector/collectors/ifstat_linux.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package collectors

import (
"encoding/json"
"io/ioutil"
"path/filepath"
"regexp"
"strings"
"time"

"bosun.org/metadata"
"bosun.org/opentsdb"
Expand All @@ -12,6 +16,8 @@ import (
func init() {
collectors = append(collectors, &IntervalCollector{F: c_ifstat_linux})
collectors = append(collectors, &IntervalCollector{F: c_ipcount_linux})
collectors = append(collectors, &IntervalCollector{F: c_if_team_linux})
collectors = append(collectors, &IntervalCollector{F: c_if_bond_linux})
}

var netFields = []struct {
Expand Down Expand Up @@ -106,3 +112,162 @@ func c_ifstat_linux() (opentsdb.MultiDataPoint, error) {
})
return md, err
}

const (
linuxNetBondSlaveIsUpDesc = "The status of the bonded or teamed interface."
linuxNetBondSlaveCount = "The number of slaves on the bonded or teamed interface."
)

func c_if_bond_linux() (opentsdb.MultiDataPoint, error) {
var md opentsdb.MultiDataPoint
const bondingPath = "/proc/net/bonding"
bondDevices, err := ioutil.ReadDir(bondingPath)
if err != nil {
return md, nil
}
for _, fi := range bondDevices {
var iface string
var slaveCount int
if err := readLine(filepath.Join(bondingPath, fi.Name()), func(s string) error {
f := strings.SplitN(s, ":", 2)
if len(f) != 2 {
return nil
}
f[0] = strings.TrimSpace(f[0])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we assign names to these fields instead of referencing f[0] and f[1] everywhere below?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree on the checking error , but don't really feel like changing logic names etc on something that already works, this was just moved out of the proc_linux collector, but code is the same.

f[1] = strings.TrimSpace(f[1])
if f[0] == "Slave Interface" {
iface = f[1]
slaveCount++
}
// TODO: This will probably need to be updated for other types of bonding beside LACP, but I have no examples available to work with at the moment
if f[0] == "MII Status" && iface != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else if may make more sense here.

var status int
if f[1] == "up" {
status = 1
}
Add(&md, "linux.net.bond.slave.is_up", status, opentsdb.TagSet{"slave": iface, "bond": fi.Name()}, metadata.Gauge, metadata.Bool, linuxNetBondSlaveIsUpDesc)
}
return nil
}); err != nil {
return md, err
}
Add(&md, "linux.net.bond.slave.count", slaveCount, opentsdb.TagSet{"bond": fi.Name()}, metadata.Gauge, metadata.Count, linuxNetBondSlaveCount)
}
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
for portName, port := range ts.TeamPorts {
slaveCount++
Add(&md, "linux.net.bond.slave.is_up", port.Link.Up, opentsdb.TagSet{"slave": portName, "bond": name}, metadata.Gauge, metadata.Bool, linuxNetBondSlaveIsUpDesc)
}
Add(&md, "linux.net.bond.slave.count", slaveCount, opentsdb.TagSet{"bond": name}, metadata.Gauge, metadata.Count, linuxNetBondSlaveCount)
}
}
return md, nil
}

type TeamState struct {
TeamPorts map[string]TeamPort `json:"ports"`
Runner struct {
Active bool `json:"active"`
FastRate bool `json:"fast_rate"`
SelectPolicy string `json:"select_policy"`
SysPrio float64 `json:"sys_prio"`
} `json:"runner"`
Setup struct {
Daemonized bool `json:"daemonized"`
DbusEnabled bool `json:"dbus_enabled"`
DebugLevel float64 `json:"debug_level"`
KernelTeamModeName string `json:"kernel_team_mode_name"`
Pid float64 `json:"pid"`
PidFile string `json:"pid_file"`
RunnerName string `json:"runner_name"`
ZmqEnabled bool `json:"zmq_enabled"`
} `json:"setup"`
TeamDevice struct {
Ifinfo struct {
DevAddr string `json:"dev_addr"`
DevAddrLen float64 `json:"dev_addr_len"`
Ifindex float64 `json:"ifindex"`
Ifname string `json:"ifname"`
} `json:"ifinfo"`
} `json:"team_device"`
}

type TeamPort struct {
Ifinfo struct {
DevAddr string `json:"dev_addr"`
DevAddrLen float64 `json:"dev_addr_len"`
Ifindex float64 `json:"ifindex"`
Ifname string `json:"ifname"`
}
Link struct {
Duplex string `json:"duplex"`
Speed float64 `json:"speed"`
Up bool `json:"up"`
} `json:"link"`
LinkWatches struct {
List struct {
LinkWatch0 struct {
DelayDown float64 `json:"delay_down"`
DelayUp float64 `json:"delay_up"`
Name string `json:"name"`
Up bool `json:"up"`
} `json:"link_watch_0"`
} `json:"list"`
Up bool `json:"up"`
} `json:"link_watches"`
Runner struct {
ActorLacpduInfo struct {
Key float64 `json:"key"`
Port float64 `json:"port"`
PortPriority float64 `json:"port_priority"`
State float64 `json:"state"`
System string `json:"system"`
SystemPriority float64 `json:"system_priority"`
} `json:"actor_lacpdu_info"`
Aggregator struct {
ID float64 `json:"id"`
Selected bool `json:"selected"`
} `json:"aggregator"`
Key float64 `json:"key"`
PartnerLacpduInfo struct {
Key float64 `json:"key"`
Port float64 `json:"port"`
PortPriority float64 `json:"port_priority"`
State float64 `json:"state"`
System string `json:"system"`
SystemPriority float64 `json:"system_priority"`
} `json:"partner_lacpdu_info"`
Prio float64 `json:"prio"`
Selected bool `json:"selected"`
State string `json:"state"`
} `json:"runner"`
}
32 changes: 0 additions & 32 deletions cmd/scollector/collectors/procstats_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package collectors

import (
"fmt"
"io/ioutil"
"regexp"
"strconv"
"strings"
Expand Down Expand Up @@ -347,37 +346,6 @@ func c_procstats_linux() (opentsdb.MultiDataPoint, error) {
}); err != nil {
Error = err
}
const bondingPath = "/proc/net/bonding"
bondDevices, _ := ioutil.ReadDir(bondingPath)
for _, fi := range bondDevices {
var iface string
var slave_count int
if err := readLine(bondingPath+"/"+fi.Name(), func(s string) error {
f := strings.SplitN(s, ":", 2)
if len(f) != 2 {
return nil
}
f[0] = strings.TrimSpace(f[0])
f[1] = strings.TrimSpace(f[1])
if f[0] == "Slave Interface" {
iface = f[1]
slave_count++
}
// TODO: This will probably need to be updated for other types of bonding beside LACP, but I have no examples available to work with at the moment
if f[0] == "MII Status" && iface != "" {
var status int
if f[1] == "up" {
status = 1
}
Add(&md, "linux.net.bond.slave.is_up", status, opentsdb.TagSet{"slave": iface, "bond": fi.Name()}, metadata.Gauge, metadata.Bool, "The status of a bond interface.")
}
return nil
}); err != nil {
Error = err
}
Add(&md, "linux.net.bond.slave.count", slave_count, opentsdb.TagSet{"bond": fi.Name()}, metadata.Gauge, metadata.Bool, "The number of slaves on the bonded interface.")
}
// TODO: Bonding monitoring for CentOS 7 using /var/run/teamd/* and teamdctl <team0> state
if err := readLine("/proc/sys/fs/file-nr", func(s string) error {
f := strings.Fields(s)
if len(f) != 3 {
Expand Down