Skip to content

Commit

Permalink
1.Change the caller level from warn to debug when delete the qdisc
Browse files Browse the repository at this point in the history
2.Implement a dynamic temporary cache that tracks network interfaces that do not support the ethtool operation.
3.Add new test cases for the new changings
  • Loading branch information
xiaozhiche320 committed Aug 29, 2024
1 parent c472403 commit 5f43e70
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 138 deletions.
69 changes: 0 additions & 69 deletions deploy/prometheus/values.yaml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package linuxutil

import (
"errors"
"strings"

"github.com/pkg/errors"

lru "github.com/hashicorp/golang-lru/v2"

Expand All @@ -10,21 +12,21 @@ import (
)

type CachedEthtool struct {
ethHandle EthtoolInterface
unsupported *lru.Cache[string, any]
EthtoolInterface
unsupported *lru.Cache[string, struct{}]
l *log.ZapLogger
}

func NewCachedEthtool(ethHandle EthtoolInterface, opts *EthtoolOpts) *CachedEthtool {
cache, err := lru.New[string, any](int(opts.limit))
cache, err := lru.New[string, struct{}](int(opts.limit))
if err != nil {
log.Logger().Error("failed to create LRU cache: ", zap.Error(err))
}
//not sure if I should do the same way to process the handle

return &CachedEthtool{
ethHandle: ethHandle,
unsupported: cache,
l: log.Logger().Named(string("EthtoolReader")),
EthtoolInterface: ethHandle,
unsupported: cache,
l: log.Logger().Named(string("EthtoolReader")),
}
}

Expand All @@ -36,15 +38,13 @@ func (ce *CachedEthtool) Stats(intf string) (map[string]uint64, error) {
return nil, errskip
}

ifaceStats, err := ce.ethHandle.Stats(intf)

ifaceStats, err := ce.EthtoolInterface.Stats(intf)
if err != nil {
ce.unsupported.Add(intf, nil)
return nil, err
if strings.Contains(err.Error(), "operation not supported") {
ce.unsupported.Add(intf, struct{}{})
return nil, errors.Wrap(err, "interface not supported while retrieving stats")
}
return nil, errors.Wrap(err, "failed to retrieve interface stats")
}
return ifaceStats, nil
}

func (ce *CachedEthtool) Close() {
ce.ethHandle.Close()
}
21 changes: 4 additions & 17 deletions pkg/plugin/linuxutil/ethtool_stats_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ type EthtoolReader struct {
opts *EthtoolOpts
data *EthtoolStats
ethHandle EthtoolInterface
// unsupported map[string]struct{}
}

func NewEthtoolReader(opts *EthtoolOpts, ethHandle EthtoolInterface) *EthtoolReader {
Expand All @@ -33,12 +32,10 @@ func NewEthtoolReader(opts *EthtoolOpts, ethHandle EthtoolInterface) *EthtoolRea
// Construct a cached ethtool handle
CachedEthHandle := NewCachedEthtool(ethHandle, opts)
return &EthtoolReader{
l: log.Logger().Named(string("EthtoolReader")),
opts: opts,
data: &EthtoolStats{},
// ethHandle: ethHandle,
l: log.Logger().Named(string("EthtoolReader")),
opts: opts,
data: &EthtoolStats{},
ethHandle: CachedEthHandle,
// unsupported: make(map[string]struct{}),
}
}

Expand All @@ -54,8 +51,6 @@ func (er *EthtoolReader) readAndUpdate() error {
}

func (er *EthtoolReader) readInterfaceStats() error {
// ethtool section

ifaces, err := net.Interfaces()
if err != nil {
er.l.Error("Error while getting all interfaces: %v\n", zap.Error(err))
Expand All @@ -76,23 +71,15 @@ func (er *EthtoolReader) readInterfaceStats() error {

// Retrieve tx from eth0
ifaceStats, err := er.ethHandle.Stats(i.Name)

if err != nil {
if errors.Is(err, errskip) {
er.l.Info("Skipping unsupported interface", zap.String("ifacename", i.Name))
er.l.Debug("Skipping unsupported interface", zap.String("ifacename", i.Name))
} else {
er.l.Error("Error while getting ethtool:", zap.String("ifacename", i.Name), zap.Error(err))
}
continue
}

// switch {
// case errors.Is(err, errskip):
// er.l.Debug("Skipping unsupported interface", zap.String("ifacename", i.Name))
// case err != nil:
// er.l.Error("Error while getting ethtool stats", zap.String("ifacename", i.Name), zap.Error(err))
// case ifaceStats != nil:

er.data.stats[i.Name] = make(map[string]uint64)
tempMap := er.processStats(ifaceStats)
er.data.stats[i.Name] = tempMap
Expand Down
60 changes: 26 additions & 34 deletions pkg/plugin/linuxutil/ethtool_stats_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package linuxutil

import (
"errors"
"fmt"
"testing"

lru "github.com/hashicorp/golang-lru/v2"
Expand All @@ -18,7 +17,11 @@ var (
MockGaugeVec *metrics.MockIGaugeVec
MockCounterVec *metrics.MockICounterVec
)
var errInterfaceNotSupported = errors.New("interface not supported")

var (
errInterfaceNotSupported = errors.New("operation not supported")
errOther = errors.New("other error")
)

func TestNewEthtool(t *testing.T) {
log.SetupZapLogger(log.GetDefaultLogOpts())
Expand All @@ -32,7 +35,6 @@ func TestNewEthtool(t *testing.T) {
defer ctrl.Finish()

ethHandle := NewMockEthtoolInterface(ctrl)
// cachedEthHandle := NewCachedEthtool(ethHandle, opts)
ethReader := NewEthtoolReader(opts, ethHandle)
assert.NotNil(t, ethReader)
}
Expand All @@ -50,11 +52,11 @@ func TestNewEthtoolWithNil(t *testing.T) {
assert.NotNil(t, ethReader)
}

// var globalCache *lru.Cache[string, struct{}]

func TestReadInterfaceStats(t *testing.T) {

globalCache, _ := lru.New[string, any](10)
globalCache, err := lru.New[string, struct{}](10)
if err != nil {
t.Fatal("failed to create LRU cache: ", err)
}

log.SetupZapLogger(log.GetDefaultLogOpts())
l := log.Logger().Named("ethtool test").Sugar()
Expand Down Expand Up @@ -83,6 +85,18 @@ func TestReadInterfaceStats(t *testing.T) {
},
wantErr: false,
},
{
name: "test other error not added to cache",
opts: &EthtoolOpts{
errOrDropKeysOnly: false,
addZeroVal: false,
limit: 10,
},
statsReturn: nil,
statErr: errOther,
result: nil,
wantErr: true,
},
{
name: "test unsported interface",
opts: &EthtoolOpts{
Expand Down Expand Up @@ -117,14 +131,11 @@ func TestReadInterfaceStats(t *testing.T) {
defer ctrl.Finish()

ethHandle := NewMockEthtoolInterface(ctrl)
//add

cachedEthHandle := NewCachedEthtool(ethHandle, tt.opts)
// 在每次测试开始时,将全局缓存传递给临时缓存对象
cachedEthHandle.unsupported = globalCache
//done
ethReader := NewEthtoolReader(tt.opts, cachedEthHandle)

// ethReader.unsupported = globalUnsupportedCache
ethReader := NewEthtoolReader(tt.opts, cachedEthHandle)

assert.NotNil(t, ethReader)

Expand All @@ -148,33 +159,14 @@ func TestReadInterfaceStats(t *testing.T) {
ethReader.updateMetrics()
}

// if tt.statErr != nil && errors.Is(tt.statErr, errInterfaceNotSupported) {
// assert.NotEqual(t, nil, ethReader.unsupported, "unsupported map should not be nil")
// assert.NotEmpty(t, ethReader.unsupported, "unsupported map should contain interfaces")
// }

// globalUnsupportedCache = ethReader.unsupported
// fmt.Println("Current unsupported cache: ", ethReader.unsupported, "Global unsupported cache: ", globalUnsupportedCache)

// 检查缓存是否正确处理不支持的接口
fmt.Println("aa---------------------", cachedEthHandle.unsupported.Len())
for _, key := range cachedEthHandle.unsupported.Keys() {
fmt.Println("key: ", key)
}
if tt.statErr != nil && errors.Is(tt.statErr, errInterfaceNotSupported) {
assert.NotNil(t, cachedEthHandle.unsupported, "cache should not be nil")
assert.NotEqual(t, 0, cachedEthHandle.unsupported.Len(), "cache should contain interface")
// l.Infof("Current unsupported cache: ", cachedEthHandle.unsupported, "Global unsupported cache: ", globalCache)
// cachedIntf, found := cachedEthHandle.unsupported.Get(tt.name)
// assert.True(t, found, "interface should be in unsupported cache")
// assert.Equal(t, struct{}{}, cachedIntf, "interface should be marked as unsupported")
// for key := range cachedEthHandle.unsupported.Keys() {
// l.Infof("key: ", key)
// }
} else if tt.statErr != nil && !errors.Is(tt.statErr, errInterfaceNotSupported) {
assert.Equal(t, 0, cachedEthHandle.unsupported.Len(), "cache should not add interface for other errors")
}
globalCache = cachedEthHandle.unsupported
l.Infof("Current unsupported cache: ", cachedEthHandle.unsupported, "Global unsupported cache: ", globalCache)

globalCache = cachedEthHandle.unsupported
}
}

Expand Down
4 changes: 3 additions & 1 deletion pkg/plugin/linuxutil/linuxutil_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"go.uber.org/zap"
)

const defaultLimit = 2000

// New creates a linuxutil plugin.
func New(cfg *kcfg.Config) api.Plugin {
return &linuxUtil{
Expand Down Expand Up @@ -87,7 +89,7 @@ func (lu *linuxUtil) run(ctx context.Context) error {
ethtoolOpts := &EthtoolOpts{
errOrDropKeysOnly: false,
addZeroVal: false,
limit: 2000,
limit: defaultLimit,
}

ethHandle, err := ethtool.NewEthtool()
Expand Down
2 changes: 1 addition & 1 deletion pkg/plugin/linuxutil/types_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ type EthtoolOpts struct {
// when true will include all keys with value 0
addZeroVal bool

//Configurable limit for unsupported interfaces cache
// Configurable limit for unsupported interfaces cache
limit uint
}

Expand Down

0 comments on commit 5f43e70

Please sign in to comment.