Add ethtool input plugin (#5865)
This commit is contained in:
parent
6cbaf890d9
commit
d9ddd95b3c
|
@ -1070,6 +1070,13 @@
|
||||||
pruneopts = ""
|
pruneopts = ""
|
||||||
revision = "e2704e165165ec55d062f5919b4b29494e9fa790"
|
revision = "e2704e165165ec55d062f5919b4b29494e9fa790"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:a18bd4e530f3f36fe91a5d1fd57d492f25287546e613f892d21c2b76b848517d"
|
||||||
|
name = "github.com/safchain/ethtool"
|
||||||
|
packages = ["."]
|
||||||
|
pruneopts = ""
|
||||||
|
revision = "42ed695e3de80b9d695f280295fd7994639f209d"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
digest = "1:7fc2f428767a2521abc63f1a663d981f61610524275d6c0ea645defadd4e916f"
|
digest = "1:7fc2f428767a2521abc63f1a663d981f61610524275d6c0ea645defadd4e916f"
|
||||||
|
@ -1781,6 +1788,7 @@
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp",
|
"github.com/prometheus/client_golang/prometheus/promhttp",
|
||||||
"github.com/prometheus/client_model/go",
|
"github.com/prometheus/client_model/go",
|
||||||
"github.com/prometheus/common/expfmt",
|
"github.com/prometheus/common/expfmt",
|
||||||
|
"github.com/safchain/ethtool",
|
||||||
"github.com/shirou/gopsutil/cpu",
|
"github.com/shirou/gopsutil/cpu",
|
||||||
"github.com/shirou/gopsutil/disk",
|
"github.com/shirou/gopsutil/disk",
|
||||||
"github.com/shirou/gopsutil/host",
|
"github.com/shirou/gopsutil/host",
|
||||||
|
|
|
@ -301,3 +301,7 @@
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "gopkg.in/ldap.v3"
|
name = "gopkg.in/ldap.v3"
|
||||||
version = "3.1.0"
|
version = "3.1.0"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/safchain/ethtool"
|
||||||
|
revision = "42ed695e3de80b9d695f280295fd7994639f209d"
|
||||||
|
|
|
@ -38,6 +38,7 @@ import (
|
||||||
_ "github.com/influxdata/telegraf/plugins/inputs/dovecot"
|
_ "github.com/influxdata/telegraf/plugins/inputs/dovecot"
|
||||||
_ "github.com/influxdata/telegraf/plugins/inputs/ecs"
|
_ "github.com/influxdata/telegraf/plugins/inputs/ecs"
|
||||||
_ "github.com/influxdata/telegraf/plugins/inputs/elasticsearch"
|
_ "github.com/influxdata/telegraf/plugins/inputs/elasticsearch"
|
||||||
|
_ "github.com/influxdata/telegraf/plugins/inputs/ethtool"
|
||||||
_ "github.com/influxdata/telegraf/plugins/inputs/exec"
|
_ "github.com/influxdata/telegraf/plugins/inputs/exec"
|
||||||
_ "github.com/influxdata/telegraf/plugins/inputs/fail2ban"
|
_ "github.com/influxdata/telegraf/plugins/inputs/fail2ban"
|
||||||
_ "github.com/influxdata/telegraf/plugins/inputs/fibaro"
|
_ "github.com/influxdata/telegraf/plugins/inputs/fibaro"
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Ethtool Input Plugin
|
||||||
|
|
||||||
|
The ethtool input plugin pulls ethernet device stats. Fields pulled will depend on the network device and driver
|
||||||
|
|
||||||
|
### Configuration:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# Returns ethtool statistics for given interfaces
|
||||||
|
[[inputs.ethtool]]
|
||||||
|
## List of interfaces to pull metrics for
|
||||||
|
# interface_include = ["eth0"]
|
||||||
|
|
||||||
|
## List of interfaces to ignore when pulling metrics.
|
||||||
|
# interface_exclude = ["eth1"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Interfaces can be included or ignored using
|
||||||
|
|
||||||
|
- `interface_include`
|
||||||
|
- `interface_exclude`
|
||||||
|
|
||||||
|
Note that loopback interfaces will be automatically ignored
|
||||||
|
|
||||||
|
### Metrics:
|
||||||
|
|
||||||
|
Metrics are dependant on the network device and driver
|
||||||
|
|
||||||
|
### Example Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
ethtool,driver=igb,host=test01,interface=mgmt0 tx_queue_1_packets=280782i,rx_queue_5_csum_err=0i,tx_queue_4_restart=0i,tx_multicast=7i,tx_queue_1_bytes=39674885i,rx_queue_2_alloc_failed=0i,tx_queue_5_packets=173970i,tx_single_coll_ok=0i,rx_queue_1_drops=0i,tx_queue_2_restart=0i,tx_aborted_errors=0i,rx_queue_6_csum_err=0i,tx_queue_5_restart=0i,tx_queue_4_bytes=64810835i,tx_abort_late_coll=0i,tx_queue_4_packets=109102i,os2bmc_tx_by_bmc=0i,tx_bytes=427527435i,tx_queue_7_packets=66665i,dropped_smbus=0i,rx_queue_0_csum_err=0i,tx_flow_control_xoff=0i,rx_packets=25926536i,rx_queue_7_csum_err=0i,rx_queue_3_bytes=84326060i,rx_multicast=83771i,rx_queue_4_alloc_failed=0i,rx_queue_3_drops=0i,rx_queue_3_csum_err=0i,rx_errors=0i,tx_errors=0i,tx_queue_6_packets=183236i,rx_broadcast=24378893i,rx_queue_7_packets=88680i,tx_dropped=0i,rx_frame_errors=0i,tx_queue_3_packets=161045i,tx_packets=1257017i,rx_queue_1_csum_err=0i,tx_window_errors=0i,tx_dma_out_of_sync=0i,rx_length_errors=0i,rx_queue_5_drops=0i,tx_timeout_count=0i,rx_queue_4_csum_err=0i,rx_flow_control_xon=0i,tx_heartbeat_errors=0i,tx_flow_control_xon=0i,collisions=0i,tx_queue_0_bytes=29465801i,rx_queue_6_drops=0i,rx_queue_0_alloc_failed=0i,tx_queue_1_restart=0i,rx_queue_0_drops=0i,tx_broadcast=9i,tx_carrier_errors=0i,tx_queue_7_bytes=13777515i,tx_queue_7_restart=0i,rx_queue_5_bytes=50732006i,rx_queue_7_bytes=35744457i,tx_deferred_ok=0i,tx_multi_coll_ok=0i,rx_crc_errors=0i,rx_fifo_errors=0i,rx_queue_6_alloc_failed=0i,tx_queue_2_packets=175206i,tx_queue_0_packets=107011i,rx_queue_4_bytes=201364548i,rx_queue_6_packets=372573i,os2bmc_rx_by_host=0i,multicast=83771i,rx_queue_4_drops=0i,rx_queue_5_packets=130535i,rx_queue_6_bytes=139488035i,tx_fifo_errors=0i,tx_queue_5_bytes=84899130i,rx_queue_0_packets=24529563i,rx_queue_3_alloc_failed=0i,rx_queue_7_drops=0i,tx_queue_6_bytes=96288614i,tx_queue_2_bytes=22132949i,tx_tcp_seg_failed=0i,rx_queue_1_bytes=246703840i,rx_queue_0_bytes=1506870738i,tx_queue_0_restart=0i,rx_queue_2_bytes=111344804i,tx_tcp_seg_good=0i,tx_queue_3_restart=0i,rx_no_buffer_count=0i,rx_smbus=0i,rx_queue_1_packets=273865i,rx_over_errors=0i,os2bmc_tx_by_host=0i,rx_queue_1_alloc_failed=0i,rx_queue_7_alloc_failed=0i,rx_short_length_errors=0i,tx_hwtstamp_timeouts=0i,tx_queue_6_restart=0i,rx_queue_2_packets=207136i,tx_queue_3_bytes=70391970i,rx_queue_3_packets=112007i,rx_queue_4_packets=212177i,tx_smbus=0i,rx_long_byte_count=2480280632i,rx_queue_2_csum_err=0i,rx_missed_errors=0i,rx_bytes=2480280632i,rx_queue_5_alloc_failed=0i,rx_queue_2_drops=0i,os2bmc_rx_by_bmc=0i,rx_align_errors=0i,rx_long_length_errors=0i,rx_hwtstamp_cleared=0i,rx_flow_control_xoff=0i 1564658080000000000
|
||||||
|
ethtool,driver=igb,host=test02,interface=mgmt0 rx_queue_2_bytes=111344804i,tx_queue_3_bytes=70439858i,multicast=83771i,rx_broadcast=24378975i,tx_queue_0_packets=107011i,rx_queue_6_alloc_failed=0i,rx_queue_6_drops=0i,rx_hwtstamp_cleared=0i,tx_window_errors=0i,tx_tcp_seg_good=0i,rx_queue_1_drops=0i,tx_queue_1_restart=0i,rx_queue_7_csum_err=0i,rx_no_buffer_count=0i,tx_queue_1_bytes=39675245i,tx_queue_5_bytes=84899130i,tx_broadcast=9i,rx_queue_1_csum_err=0i,tx_flow_control_xoff=0i,rx_queue_6_csum_err=0i,tx_timeout_count=0i,os2bmc_tx_by_bmc=0i,rx_queue_6_packets=372577i,rx_queue_0_alloc_failed=0i,tx_flow_control_xon=0i,rx_queue_2_drops=0i,tx_queue_2_packets=175206i,rx_queue_3_csum_err=0i,tx_abort_late_coll=0i,tx_queue_5_restart=0i,tx_dropped=0i,rx_queue_2_alloc_failed=0i,tx_multi_coll_ok=0i,rx_queue_1_packets=273865i,rx_flow_control_xon=0i,tx_single_coll_ok=0i,rx_length_errors=0i,rx_queue_7_bytes=35744457i,rx_queue_4_alloc_failed=0i,rx_queue_6_bytes=139488395i,rx_queue_2_csum_err=0i,rx_long_byte_count=2480288216i,rx_queue_1_alloc_failed=0i,tx_queue_0_restart=0i,rx_queue_0_csum_err=0i,tx_queue_2_bytes=22132949i,rx_queue_5_drops=0i,tx_dma_out_of_sync=0i,rx_queue_3_drops=0i,rx_queue_4_packets=212177i,tx_queue_6_restart=0i,rx_packets=25926650i,rx_queue_7_packets=88680i,rx_frame_errors=0i,rx_queue_3_bytes=84326060i,rx_short_length_errors=0i,tx_queue_7_bytes=13777515i,rx_queue_3_alloc_failed=0i,tx_queue_6_packets=183236i,rx_queue_0_drops=0i,rx_multicast=83771i,rx_queue_2_packets=207136i,rx_queue_5_csum_err=0i,rx_queue_5_packets=130535i,rx_queue_7_alloc_failed=0i,tx_smbus=0i,tx_queue_3_packets=161081i,rx_queue_7_drops=0i,tx_queue_2_restart=0i,tx_multicast=7i,tx_fifo_errors=0i,tx_queue_3_restart=0i,rx_long_length_errors=0i,tx_queue_6_bytes=96288614i,tx_queue_1_packets=280786i,tx_tcp_seg_failed=0i,rx_align_errors=0i,tx_errors=0i,rx_crc_errors=0i,rx_queue_0_packets=24529673i,rx_flow_control_xoff=0i,tx_queue_0_bytes=29465801i,rx_over_errors=0i,rx_queue_4_drops=0i,os2bmc_rx_by_bmc=0i,rx_smbus=0i,dropped_smbus=0i,tx_hwtstamp_timeouts=0i,rx_errors=0i,tx_queue_4_packets=109102i,tx_carrier_errors=0i,tx_queue_4_bytes=64810835i,tx_queue_4_restart=0i,rx_queue_4_csum_err=0i,tx_queue_7_packets=66665i,tx_aborted_errors=0i,rx_missed_errors=0i,tx_bytes=427575843i,collisions=0i,rx_queue_1_bytes=246703840i,rx_queue_5_bytes=50732006i,rx_bytes=2480288216i,os2bmc_rx_by_host=0i,rx_queue_5_alloc_failed=0i,rx_queue_3_packets=112007i,tx_deferred_ok=0i,os2bmc_tx_by_host=0i,tx_heartbeat_errors=0i,rx_queue_0_bytes=1506877506i,tx_queue_7_restart=0i,tx_packets=1257057i,rx_queue_4_bytes=201364548i,rx_fifo_errors=0i,tx_queue_5_packets=173970i 1564658090000000000
|
||||||
|
```
|
|
@ -0,0 +1,46 @@
|
||||||
|
package ethtool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Command interface {
|
||||||
|
Init() error
|
||||||
|
DriverName(intf string) (string, error)
|
||||||
|
Interfaces() ([]net.Interface, error)
|
||||||
|
Stats(intf string) (map[string]uint64, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Ethtool struct {
|
||||||
|
// This is the list of interface names to include
|
||||||
|
InterfaceInclude []string `toml:"interface_include"`
|
||||||
|
|
||||||
|
// This is the list of interface names to ignore
|
||||||
|
InterfaceExclude []string `toml:"interface_exclude"`
|
||||||
|
|
||||||
|
// the ethtool command
|
||||||
|
command Command
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
pluginName = "ethtool"
|
||||||
|
tagInterface = "interface"
|
||||||
|
tagDriverName = "driver"
|
||||||
|
|
||||||
|
sampleConfig = `
|
||||||
|
## List of interfaces to pull metrics for
|
||||||
|
# interface_include = ["eth0"]
|
||||||
|
|
||||||
|
## List of interfaces to ignore when pulling metrics.
|
||||||
|
# interface_exclude = ["eth1"]
|
||||||
|
`
|
||||||
|
)
|
||||||
|
|
||||||
|
func (e *Ethtool) SampleConfig() string {
|
||||||
|
return sampleConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// Description returns a one-sentence description on the Input
|
||||||
|
func (e *Ethtool) Description() string {
|
||||||
|
return "Returns ethtool statistics for given interfaces"
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package ethtool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/influxdata/telegraf"
|
||||||
|
"github.com/influxdata/telegraf/filter"
|
||||||
|
"github.com/influxdata/telegraf/plugins/inputs"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/safchain/ethtool"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CommandEthtool struct {
|
||||||
|
ethtool *ethtool.Ethtool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Ethtool) Gather(acc telegraf.Accumulator) error {
|
||||||
|
|
||||||
|
// Get the list of interfaces
|
||||||
|
interfaces, err := e.command.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
acc.AddError(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
interfaceFilter, err := filter.NewIncludeExcludeFilter(e.InterfaceInclude, e.InterfaceExclude)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// parallelize the ethtool call in event of many interfaces
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
for _, iface := range interfaces {
|
||||||
|
|
||||||
|
// Check this isn't a loop back and that its matched by the filter
|
||||||
|
if (iface.Flags&net.FlagLoopback == 0) && interfaceFilter.Match(iface.Name) {
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
go func(i net.Interface) {
|
||||||
|
e.gatherEthtoolStats(i, acc)
|
||||||
|
wg.Done()
|
||||||
|
}(iface)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Waiting for all the interfaces
|
||||||
|
wg.Wait()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialise the Command Tool
|
||||||
|
func (e *Ethtool) Init() error {
|
||||||
|
return e.command.Init()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gather the stats for the interface.
|
||||||
|
func (e *Ethtool) gatherEthtoolStats(iface net.Interface, acc telegraf.Accumulator) {
|
||||||
|
|
||||||
|
tags := make(map[string]string)
|
||||||
|
tags[tagInterface] = iface.Name
|
||||||
|
|
||||||
|
driverName, err := e.command.DriverName(iface.Name)
|
||||||
|
if err != nil {
|
||||||
|
driverErr := errors.Wrapf(err, "%s driver", iface.Name)
|
||||||
|
acc.AddError(driverErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tags[tagDriverName] = driverName
|
||||||
|
|
||||||
|
fields := make(map[string]interface{})
|
||||||
|
stats, err := e.command.Stats(iface.Name)
|
||||||
|
if err != nil {
|
||||||
|
statsErr := errors.Wrapf(err, "%s stats", iface.Name)
|
||||||
|
acc.AddError(statsErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range stats {
|
||||||
|
fields[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
acc.AddFields(pluginName, fields, tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCommandEthtool() *CommandEthtool {
|
||||||
|
return &CommandEthtool{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandEthtool) Init() error {
|
||||||
|
|
||||||
|
if c.ethtool != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
e, err := ethtool.NewEthtool()
|
||||||
|
if err == nil {
|
||||||
|
c.ethtool = e
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandEthtool) DriverName(intf string) (string, error) {
|
||||||
|
return c.ethtool.DriverName(intf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandEthtool) Stats(intf string) (map[string]uint64, error) {
|
||||||
|
return c.ethtool.Stats(intf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandEthtool) Interfaces() ([]net.Interface, error) {
|
||||||
|
|
||||||
|
// Get the list of interfaces
|
||||||
|
interfaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return interfaces, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
inputs.Add(pluginName, func() telegraf.Input {
|
||||||
|
return &Ethtool{
|
||||||
|
InterfaceInclude: []string{},
|
||||||
|
InterfaceExclude: []string{},
|
||||||
|
command: NewCommandEthtool(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
package ethtool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/influxdata/telegraf"
|
||||||
|
"github.com/influxdata/telegraf/plugins/inputs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (e *Ethtool) Gather(acc telegraf.Accumulator) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
inputs.Add(pluginName, func() telegraf.Input {
|
||||||
|
log.Print("W! [inputs.ethtool] Current platform is not supported")
|
||||||
|
return &Ethtool{}
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,379 @@
|
||||||
|
package ethtool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/influxdata/telegraf/testutil"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
var command *Ethtool
|
||||||
|
var interfaceMap map[string]*InterfaceMock
|
||||||
|
|
||||||
|
type InterfaceMock struct {
|
||||||
|
Name string
|
||||||
|
DriverName string
|
||||||
|
Stat map[string]uint64
|
||||||
|
LoopBack bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommandEthtoolMock struct {
|
||||||
|
InterfaceMap map[string]*InterfaceMock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandEthtoolMock) Init() error {
|
||||||
|
// Not required for test mock
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandEthtoolMock) DriverName(intf string) (driverName string, err error) {
|
||||||
|
i := c.InterfaceMap[intf]
|
||||||
|
if i != nil {
|
||||||
|
driverName = i.DriverName
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return driverName, errors.New("interface not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandEthtoolMock) Interfaces() ([]net.Interface, error) {
|
||||||
|
interfaceNames := make([]net.Interface, 0)
|
||||||
|
for k, v := range c.InterfaceMap {
|
||||||
|
|
||||||
|
// Whether to set the flag to loopback
|
||||||
|
flag := net.FlagUp
|
||||||
|
if v.LoopBack {
|
||||||
|
flag = net.FlagLoopback
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a dummy interface
|
||||||
|
iface := net.Interface{
|
||||||
|
Index: 0,
|
||||||
|
MTU: 1500,
|
||||||
|
Name: k,
|
||||||
|
HardwareAddr: nil,
|
||||||
|
Flags: flag,
|
||||||
|
}
|
||||||
|
interfaceNames = append(interfaceNames, iface)
|
||||||
|
}
|
||||||
|
return interfaceNames, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandEthtoolMock) Stats(intf string) (stat map[string]uint64, err error) {
|
||||||
|
i := c.InterfaceMap[intf]
|
||||||
|
if i != nil {
|
||||||
|
stat = i.Stat
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return stat, errors.New("interface not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func setup() {
|
||||||
|
|
||||||
|
interfaceMap = make(map[string]*InterfaceMock)
|
||||||
|
|
||||||
|
eth1Stat := map[string]uint64{
|
||||||
|
"port_rx_1024_to_15xx": 25167245,
|
||||||
|
"port_rx_128_to_255": 1573526387,
|
||||||
|
"port_rx_15xx_to_jumbo": 137819058,
|
||||||
|
"port_rx_256_to_511": 772038107,
|
||||||
|
"port_rx_512_to_1023": 78294457,
|
||||||
|
"port_rx_64": 8798065,
|
||||||
|
"port_rx_65_to_127": 450348015,
|
||||||
|
"port_rx_bad": 0,
|
||||||
|
"port_rx_bad_bytes": 0,
|
||||||
|
"port_rx_bad_gtjumbo": 0,
|
||||||
|
"port_rx_broadcast": 6428250,
|
||||||
|
"port_rx_bytes": 893460472634,
|
||||||
|
"port_rx_control": 0,
|
||||||
|
"port_rx_dp_di_dropped_packets": 2772680304,
|
||||||
|
"port_rx_dp_hlb_fetch": 0,
|
||||||
|
"port_rx_dp_hlb_wait": 0,
|
||||||
|
"port_rx_dp_q_disabled_packets": 0,
|
||||||
|
"port_rx_dp_streaming_packets": 0,
|
||||||
|
"port_rx_good": 3045991334,
|
||||||
|
"port_rx_good_bytes": 893460472927,
|
||||||
|
"port_rx_gtjumbo": 0,
|
||||||
|
"port_rx_lt64": 0,
|
||||||
|
"port_rx_multicast": 1639566045,
|
||||||
|
"port_rx_nodesc_drops": 0,
|
||||||
|
"port_rx_overflow": 0,
|
||||||
|
"port_rx_packets": 3045991334,
|
||||||
|
"port_rx_pause": 0,
|
||||||
|
"port_rx_pm_discard_bb_overflow": 0,
|
||||||
|
"port_rx_pm_discard_mapping": 0,
|
||||||
|
"port_rx_pm_discard_qbb": 0,
|
||||||
|
"port_rx_pm_discard_vfifo_full": 0,
|
||||||
|
"port_rx_pm_trunc_bb_overflow": 0,
|
||||||
|
"port_rx_pm_trunc_qbb": 0,
|
||||||
|
"port_rx_pm_trunc_vfifo_full": 0,
|
||||||
|
"port_rx_unicast": 1399997040,
|
||||||
|
"port_tx_1024_to_15xx": 236,
|
||||||
|
"port_tx_128_to_255": 275090219,
|
||||||
|
"port_tx_15xx_to_jumbo": 926,
|
||||||
|
"port_tx_256_to_511": 48567221,
|
||||||
|
"port_tx_512_to_1023": 5142016,
|
||||||
|
"port_tx_64": 113903973,
|
||||||
|
"port_tx_65_to_127": 161935699,
|
||||||
|
"port_tx_broadcast": 8,
|
||||||
|
"port_tx_bytes": 94357131016,
|
||||||
|
"port_tx_control": 0,
|
||||||
|
"port_tx_lt64": 0,
|
||||||
|
"port_tx_multicast": 325891647,
|
||||||
|
"port_tx_packets": 604640290,
|
||||||
|
"port_tx_pause": 0,
|
||||||
|
"port_tx_unicast": 278748635,
|
||||||
|
"ptp_bad_syncs": 1,
|
||||||
|
"ptp_fast_syncs": 1,
|
||||||
|
"ptp_filter_matches": 0,
|
||||||
|
"ptp_good_syncs": 136151,
|
||||||
|
"ptp_invalid_sync_windows": 0,
|
||||||
|
"ptp_no_time_syncs": 1,
|
||||||
|
"ptp_non_filter_matches": 0,
|
||||||
|
"ptp_oversize_sync_windows": 53,
|
||||||
|
"ptp_rx_no_timestamp": 0,
|
||||||
|
"ptp_rx_timestamp_packets": 0,
|
||||||
|
"ptp_sync_timeouts": 1,
|
||||||
|
"ptp_timestamp_packets": 0,
|
||||||
|
"ptp_tx_timestamp_packets": 0,
|
||||||
|
"ptp_undersize_sync_windows": 3,
|
||||||
|
"rx-0.rx_packets": 55659234,
|
||||||
|
"rx-1.rx_packets": 87880538,
|
||||||
|
"rx-2.rx_packets": 26746234,
|
||||||
|
"rx-3.rx_packets": 103026471,
|
||||||
|
"rx-4.rx_packets": 0,
|
||||||
|
"rx_eth_crc_err": 0,
|
||||||
|
"rx_frm_trunc": 0,
|
||||||
|
"rx_inner_ip_hdr_chksum_err": 0,
|
||||||
|
"rx_inner_tcp_udp_chksum_err": 0,
|
||||||
|
"rx_ip_hdr_chksum_err": 0,
|
||||||
|
"rx_mcast_mismatch": 0,
|
||||||
|
"rx_merge_events": 0,
|
||||||
|
"rx_merge_packets": 0,
|
||||||
|
"rx_nodesc_trunc": 0,
|
||||||
|
"rx_noskb_drops": 0,
|
||||||
|
"rx_outer_ip_hdr_chksum_err": 0,
|
||||||
|
"rx_outer_tcp_udp_chksum_err": 0,
|
||||||
|
"rx_reset": 0,
|
||||||
|
"rx_tcp_udp_chksum_err": 0,
|
||||||
|
"rx_tobe_disc": 0,
|
||||||
|
"tx-0.tx_packets": 85843565,
|
||||||
|
"tx-1.tx_packets": 108642725,
|
||||||
|
"tx-2.tx_packets": 202596078,
|
||||||
|
"tx-3.tx_packets": 207561010,
|
||||||
|
"tx-4.tx_packets": 0,
|
||||||
|
"tx_cb_packets": 4,
|
||||||
|
"tx_merge_events": 11025,
|
||||||
|
"tx_pio_packets": 531928114,
|
||||||
|
"tx_pushes": 604643378,
|
||||||
|
"tx_tso_bursts": 0,
|
||||||
|
"tx_tso_fallbacks": 0,
|
||||||
|
"tx_tso_long_headers": 0,
|
||||||
|
}
|
||||||
|
eth1 := &InterfaceMock{"eth1", "driver1", eth1Stat, false}
|
||||||
|
interfaceMap[eth1.Name] = eth1
|
||||||
|
|
||||||
|
eth2Stat := map[string]uint64{
|
||||||
|
"port_rx_1024_to_15xx": 11529312,
|
||||||
|
"port_rx_128_to_255": 1868952037,
|
||||||
|
"port_rx_15xx_to_jumbo": 130339387,
|
||||||
|
"port_rx_256_to_511": 843846270,
|
||||||
|
"port_rx_512_to_1023": 173194372,
|
||||||
|
"port_rx_64": 9190374,
|
||||||
|
"port_rx_65_to_127": 507806115,
|
||||||
|
"port_rx_bad": 0,
|
||||||
|
"port_rx_bad_bytes": 0,
|
||||||
|
"port_rx_bad_gtjumbo": 0,
|
||||||
|
"port_rx_broadcast": 6648019,
|
||||||
|
"port_rx_bytes": 1007358162202,
|
||||||
|
"port_rx_control": 0,
|
||||||
|
"port_rx_dp_di_dropped_packets": 3164124639,
|
||||||
|
"port_rx_dp_hlb_fetch": 0,
|
||||||
|
"port_rx_dp_hlb_wait": 0,
|
||||||
|
"port_rx_dp_q_disabled_packets": 0,
|
||||||
|
"port_rx_dp_streaming_packets": 0,
|
||||||
|
"port_rx_good": 3544857867,
|
||||||
|
"port_rx_good_bytes": 1007358162202,
|
||||||
|
"port_rx_gtjumbo": 0,
|
||||||
|
"port_rx_lt64": 0,
|
||||||
|
"port_rx_multicast": 2231999743,
|
||||||
|
"port_rx_nodesc_drops": 0,
|
||||||
|
"port_rx_overflow": 0,
|
||||||
|
"port_rx_packets": 3544857867,
|
||||||
|
"port_rx_pause": 0,
|
||||||
|
"port_rx_pm_discard_bb_overflow": 0,
|
||||||
|
"port_rx_pm_discard_mapping": 0,
|
||||||
|
"port_rx_pm_discard_qbb": 0,
|
||||||
|
"port_rx_pm_discard_vfifo_full": 0,
|
||||||
|
"port_rx_pm_trunc_bb_overflow": 0,
|
||||||
|
"port_rx_pm_trunc_qbb": 0,
|
||||||
|
"port_rx_pm_trunc_vfifo_full": 0,
|
||||||
|
"port_rx_unicast": 1306210105,
|
||||||
|
"port_tx_1024_to_15xx": 379,
|
||||||
|
"port_tx_128_to_255": 202767251,
|
||||||
|
"port_tx_15xx_to_jumbo": 558,
|
||||||
|
"port_tx_256_to_511": 31454719,
|
||||||
|
"port_tx_512_to_1023": 6865731,
|
||||||
|
"port_tx_64": 17268276,
|
||||||
|
"port_tx_65_to_127": 272816313,
|
||||||
|
"port_tx_broadcast": 6,
|
||||||
|
"port_tx_bytes": 78071946593,
|
||||||
|
"port_tx_control": 0,
|
||||||
|
"port_tx_lt64": 0,
|
||||||
|
"port_tx_multicast": 239510586,
|
||||||
|
"port_tx_packets": 531173227,
|
||||||
|
"port_tx_pause": 0,
|
||||||
|
"port_tx_unicast": 291662635,
|
||||||
|
"ptp_bad_syncs": 0,
|
||||||
|
"ptp_fast_syncs": 0,
|
||||||
|
"ptp_filter_matches": 0,
|
||||||
|
"ptp_good_syncs": 0,
|
||||||
|
"ptp_invalid_sync_windows": 0,
|
||||||
|
"ptp_no_time_syncs": 0,
|
||||||
|
"ptp_non_filter_matches": 0,
|
||||||
|
"ptp_oversize_sync_windows": 0,
|
||||||
|
"ptp_rx_no_timestamp": 0,
|
||||||
|
"ptp_rx_timestamp_packets": 0,
|
||||||
|
"ptp_sync_timeouts": 0,
|
||||||
|
"ptp_timestamp_packets": 0,
|
||||||
|
"ptp_tx_timestamp_packets": 0,
|
||||||
|
"ptp_undersize_sync_windows": 0,
|
||||||
|
"rx-0.rx_packets": 84587075,
|
||||||
|
"rx-1.rx_packets": 74029305,
|
||||||
|
"rx-2.rx_packets": 134586471,
|
||||||
|
"rx-3.rx_packets": 87531322,
|
||||||
|
"rx-4.rx_packets": 0,
|
||||||
|
"rx_eth_crc_err": 0,
|
||||||
|
"rx_frm_trunc": 0,
|
||||||
|
"rx_inner_ip_hdr_chksum_err": 0,
|
||||||
|
"rx_inner_tcp_udp_chksum_err": 0,
|
||||||
|
"rx_ip_hdr_chksum_err": 0,
|
||||||
|
"rx_mcast_mismatch": 0,
|
||||||
|
"rx_merge_events": 0,
|
||||||
|
"rx_merge_packets": 0,
|
||||||
|
"rx_nodesc_trunc": 0,
|
||||||
|
"rx_noskb_drops": 0,
|
||||||
|
"rx_outer_ip_hdr_chksum_err": 0,
|
||||||
|
"rx_outer_tcp_udp_chksum_err": 0,
|
||||||
|
"rx_reset": 0,
|
||||||
|
"rx_tcp_udp_chksum_err": 0,
|
||||||
|
"rx_tobe_disc": 0,
|
||||||
|
"tx-0.tx_packets": 232521451,
|
||||||
|
"tx-1.tx_packets": 97876137,
|
||||||
|
"tx-2.tx_packets": 106822111,
|
||||||
|
"tx-3.tx_packets": 93955050,
|
||||||
|
"tx-4.tx_packets": 0,
|
||||||
|
"tx_cb_packets": 1,
|
||||||
|
"tx_merge_events": 8402,
|
||||||
|
"tx_pio_packets": 481040054,
|
||||||
|
"tx_pushes": 531174491,
|
||||||
|
"tx_tso_bursts": 128,
|
||||||
|
"tx_tso_fallbacks": 0,
|
||||||
|
"tx_tso_long_headers": 0,
|
||||||
|
}
|
||||||
|
eth2 := &InterfaceMock{"eth2", "driver1", eth2Stat, false}
|
||||||
|
interfaceMap[eth2.Name] = eth2
|
||||||
|
|
||||||
|
// dummy loopback including dummy stat to ensure that the ignore feature is working
|
||||||
|
lo0Stat := map[string]uint64{
|
||||||
|
"dummy": 0,
|
||||||
|
}
|
||||||
|
lo0 := &InterfaceMock{"lo0", "", lo0Stat, true}
|
||||||
|
interfaceMap[lo0.Name] = lo0
|
||||||
|
|
||||||
|
c := &CommandEthtoolMock{interfaceMap}
|
||||||
|
command = &Ethtool{
|
||||||
|
InterfaceInclude: []string{},
|
||||||
|
InterfaceExclude: []string{},
|
||||||
|
command: c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toStringMapInterface(in map[string]uint64) map[string]interface{} {
|
||||||
|
var m = map[string]interface{}{}
|
||||||
|
for k, v := range in {
|
||||||
|
m[k] = v
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGather(t *testing.T) {
|
||||||
|
|
||||||
|
setup()
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
|
||||||
|
err := command.Gather(&acc)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, acc.Metrics, 2)
|
||||||
|
|
||||||
|
expectedFieldsEth1 := toStringMapInterface(interfaceMap["eth1"].Stat)
|
||||||
|
expectedTagsEth1 := map[string]string{
|
||||||
|
"interface": "eth1",
|
||||||
|
"driver": "driver1",
|
||||||
|
}
|
||||||
|
acc.AssertContainsTaggedFields(t, pluginName, expectedFieldsEth1, expectedTagsEth1)
|
||||||
|
expectedFieldsEth2 := toStringMapInterface(interfaceMap["eth2"].Stat)
|
||||||
|
expectedTagsEth2 := map[string]string{
|
||||||
|
"interface": "eth2",
|
||||||
|
"driver": "driver1",
|
||||||
|
}
|
||||||
|
acc.AssertContainsTaggedFields(t, pluginName, expectedFieldsEth2, expectedTagsEth2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGatherIncludeInterfaces(t *testing.T) {
|
||||||
|
|
||||||
|
setup()
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
|
||||||
|
command.InterfaceInclude = append(command.InterfaceInclude, "eth1")
|
||||||
|
|
||||||
|
err := command.Gather(&acc)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, acc.Metrics, 1)
|
||||||
|
|
||||||
|
// Should contain eth1
|
||||||
|
expectedFieldsEth1 := toStringMapInterface(interfaceMap["eth1"].Stat)
|
||||||
|
expectedTagsEth1 := map[string]string{
|
||||||
|
"interface": "eth1",
|
||||||
|
"driver": "driver1",
|
||||||
|
}
|
||||||
|
acc.AssertContainsTaggedFields(t, pluginName, expectedFieldsEth1, expectedTagsEth1)
|
||||||
|
|
||||||
|
// Should not contain eth2
|
||||||
|
expectedFieldsEth2 := toStringMapInterface(interfaceMap["eth2"].Stat)
|
||||||
|
expectedTagsEth2 := map[string]string{
|
||||||
|
"interface": "eth2",
|
||||||
|
"driver": "driver1",
|
||||||
|
}
|
||||||
|
acc.AssertDoesNotContainsTaggedFields(t, pluginName, expectedFieldsEth2, expectedTagsEth2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGatherIgnoreInterfaces(t *testing.T) {
|
||||||
|
|
||||||
|
setup()
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
|
||||||
|
command.InterfaceExclude = append(command.InterfaceExclude, "eth1")
|
||||||
|
|
||||||
|
err := command.Gather(&acc)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, acc.Metrics, 1)
|
||||||
|
|
||||||
|
// Should not contain eth1
|
||||||
|
expectedFieldsEth1 := toStringMapInterface(interfaceMap["eth1"].Stat)
|
||||||
|
expectedTagsEth1 := map[string]string{
|
||||||
|
"interface": "eth1",
|
||||||
|
"driver": "driver1",
|
||||||
|
}
|
||||||
|
acc.AssertDoesNotContainsTaggedFields(t, pluginName, expectedFieldsEth1, expectedTagsEth1)
|
||||||
|
|
||||||
|
// Should contain eth2
|
||||||
|
expectedFieldsEth2 := toStringMapInterface(interfaceMap["eth2"].Stat)
|
||||||
|
expectedTagsEth2 := map[string]string{
|
||||||
|
"interface": "eth2",
|
||||||
|
"driver": "driver1",
|
||||||
|
}
|
||||||
|
acc.AssertContainsTaggedFields(t, pluginName, expectedFieldsEth2, expectedTagsEth2)
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue