fix(inputs.conntrack): Resolve segfault when setting collect field (#12603)
This commit is contained in:
parent
0f2db7abb8
commit
0ea50fa3b5
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/influxdata/telegraf"
|
"github.com/influxdata/telegraf"
|
||||||
|
"github.com/influxdata/telegraf/internal/choice"
|
||||||
"github.com/influxdata/telegraf/plugins/inputs"
|
"github.com/influxdata/telegraf/plugins/inputs"
|
||||||
"github.com/influxdata/telegraf/plugins/inputs/system"
|
"github.com/influxdata/telegraf/plugins/inputs/system"
|
||||||
)
|
)
|
||||||
|
|
@ -57,9 +58,17 @@ func (*Conntrack) SampleConfig() string {
|
||||||
return sampleConfig
|
return sampleConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conntrack) Gather(acc telegraf.Accumulator) error {
|
func (c *Conntrack) Init() error {
|
||||||
c.setDefaults()
|
c.setDefaults()
|
||||||
|
|
||||||
|
if err := choice.CheckSlice(c.Collect, []string{"all", "percpu"}); err != nil {
|
||||||
|
return fmt.Errorf("config option 'collect': %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conntrack) Gather(acc telegraf.Accumulator) error {
|
||||||
var metricKey string
|
var metricKey string
|
||||||
fields := make(map[string]interface{})
|
fields := make(map[string]interface{})
|
||||||
|
|
||||||
|
|
@ -93,19 +102,8 @@ func (c *Conntrack) Gather(acc telegraf.Accumulator) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var all bool
|
for _, metric := range c.Collect {
|
||||||
var perCPU bool
|
perCPU := metric == "percpu"
|
||||||
|
|
||||||
for _, collect := range c.Collect {
|
|
||||||
if collect == "all" {
|
|
||||||
all = true
|
|
||||||
}
|
|
||||||
if collect == "percpu" {
|
|
||||||
perCPU = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if all || perCPU {
|
|
||||||
stats, err := c.ps.NetConntrack(perCPU)
|
stats, err := c.ps.NetConntrack(perCPU)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
acc.AddError(fmt.Errorf("failed to retrieve conntrack statistics: %v", err))
|
acc.AddError(fmt.Errorf("failed to retrieve conntrack statistics: %v", err))
|
||||||
|
|
@ -115,8 +113,8 @@ func (c *Conntrack) Gather(acc telegraf.Accumulator) error {
|
||||||
acc.AddError(fmt.Errorf("conntrack input failed to collect stats"))
|
acc.AddError(fmt.Errorf("conntrack input failed to collect stats"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpuTag := "all"
|
||||||
for i, sts := range stats {
|
for i, sts := range stats {
|
||||||
cpuTag := "all"
|
|
||||||
if perCPU {
|
if perCPU {
|
||||||
cpuTag = fmt.Sprintf("cpu%d", i)
|
cpuTag = fmt.Sprintf("cpu%d", i)
|
||||||
}
|
}
|
||||||
|
|
@ -157,5 +155,9 @@ func (c *Conntrack) Gather(acc telegraf.Accumulator) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add(inputName, func() telegraf.Input { return &Conntrack{} })
|
inputs.Add(inputName, func() telegraf.Input {
|
||||||
|
return &Conntrack{
|
||||||
|
ps: system.NewSystemPS(),
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ func TestNoFilesFound(t *testing.T) {
|
||||||
dfltFiles = []string{"baz.txt"}
|
dfltFiles = []string{"baz.txt"}
|
||||||
dfltDirs = []string{"./foo/bar"}
|
dfltDirs = []string{"./foo/bar"}
|
||||||
c := &Conntrack{}
|
c := &Conntrack{}
|
||||||
|
require.NoError(t, c.Init())
|
||||||
acc := &testutil.Accumulator{}
|
acc := &testutil.Accumulator{}
|
||||||
err := c.Gather(acc)
|
err := c.Gather(acc)
|
||||||
|
|
||||||
|
|
@ -51,6 +52,7 @@ func TestDefaultsUsed(t *testing.T) {
|
||||||
count := 1234321
|
count := 1234321
|
||||||
require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(strconv.Itoa(count)), 0660))
|
require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(strconv.Itoa(count)), 0660))
|
||||||
c := &Conntrack{}
|
c := &Conntrack{}
|
||||||
|
require.NoError(t, c.Init())
|
||||||
acc := &testutil.Accumulator{}
|
acc := &testutil.Accumulator{}
|
||||||
|
|
||||||
require.NoError(t, c.Gather(acc))
|
require.NoError(t, c.Gather(acc))
|
||||||
|
|
@ -81,6 +83,7 @@ func TestConfigsUsed(t *testing.T) {
|
||||||
require.NoError(t, os.WriteFile(cntFile.Name(), []byte(strconv.Itoa(count)), 0660))
|
require.NoError(t, os.WriteFile(cntFile.Name(), []byte(strconv.Itoa(count)), 0660))
|
||||||
require.NoError(t, os.WriteFile(maxFile.Name(), []byte(strconv.Itoa(max)), 0660))
|
require.NoError(t, os.WriteFile(maxFile.Name(), []byte(strconv.Itoa(max)), 0660))
|
||||||
c := &Conntrack{}
|
c := &Conntrack{}
|
||||||
|
require.NoError(t, c.Init())
|
||||||
acc := &testutil.Accumulator{}
|
acc := &testutil.Accumulator{}
|
||||||
|
|
||||||
require.NoError(t, c.Gather(acc))
|
require.NoError(t, c.Gather(acc))
|
||||||
|
|
@ -123,9 +126,10 @@ func TestCollectStats(t *testing.T) {
|
||||||
|
|
||||||
mps.On("NetConntrack", false).Return([]net.ConntrackStat{sts}, nil)
|
mps.On("NetConntrack", false).Return([]net.ConntrackStat{sts}, nil)
|
||||||
cs := &Conntrack{
|
cs := &Conntrack{
|
||||||
ps: &mps,
|
ps: &mps,
|
||||||
|
Collect: []string{"all"},
|
||||||
}
|
}
|
||||||
cs.Collect = []string{"all"}
|
require.NoError(t, cs.Init())
|
||||||
|
|
||||||
err := cs.Gather(&acc)
|
err := cs.Gather(&acc)
|
||||||
if err != nil && strings.Contains(err.Error(), "Is the conntrack kernel module loaded?") {
|
if err != nil && strings.Contains(err.Error(), "Is the conntrack kernel module loaded?") {
|
||||||
|
|
@ -211,10 +215,35 @@ func TestCollectStatsPerCpu(t *testing.T) {
|
||||||
|
|
||||||
mps.On("NetConntrack", true).Return(sts, nil)
|
mps.On("NetConntrack", true).Return(sts, nil)
|
||||||
|
|
||||||
cs := &Conntrack{
|
allSts := []net.ConntrackStat{
|
||||||
ps: &mps,
|
{
|
||||||
|
Entries: 129,
|
||||||
|
Searched: 20,
|
||||||
|
Found: 2,
|
||||||
|
New: 10,
|
||||||
|
Invalid: 86,
|
||||||
|
Ignore: 26,
|
||||||
|
Delete: 6,
|
||||||
|
DeleteList: 10,
|
||||||
|
Insert: 18,
|
||||||
|
InsertFailed: 40,
|
||||||
|
Drop: 98,
|
||||||
|
EarlyDrop: 17,
|
||||||
|
IcmpError: 42,
|
||||||
|
ExpectNew: 24,
|
||||||
|
ExpectCreate: 88,
|
||||||
|
ExpectDelete: 106,
|
||||||
|
SearchRestart: 62,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
cs.Collect = []string{"all", "percpu"}
|
|
||||||
|
mps.On("NetConntrack", false).Return(allSts, nil)
|
||||||
|
|
||||||
|
cs := &Conntrack{
|
||||||
|
ps: &mps,
|
||||||
|
Collect: []string{"all", "percpu"},
|
||||||
|
}
|
||||||
|
require.NoError(t, cs.Init())
|
||||||
|
|
||||||
err := cs.Gather(&acc)
|
err := cs.Gather(&acc)
|
||||||
if err != nil && strings.Contains(err.Error(), "Is the conntrack kernel module loaded?") {
|
if err != nil && strings.Contains(err.Error(), "Is the conntrack kernel module loaded?") {
|
||||||
|
|
@ -243,13 +272,76 @@ func TestCollectStatsPerCpu(t *testing.T) {
|
||||||
"search_restart": uint32(31),
|
"search_restart": uint32(31),
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.AssertContainsFields(t, inputName, expectedFields)
|
|
||||||
acc.AssertContainsTaggedFields(t, inputName, expectedFields,
|
acc.AssertContainsTaggedFields(t, inputName, expectedFields,
|
||||||
map[string]string{
|
map[string]string{
|
||||||
"cpu": "cpu0",
|
"cpu": "cpu0",
|
||||||
})
|
})
|
||||||
|
|
||||||
//TODO: check cpu1 fields
|
//cpu1
|
||||||
|
expectedFields1 := map[string]interface{}{
|
||||||
|
"entries": uint32(79),
|
||||||
|
"searched": uint32(10),
|
||||||
|
"found": uint32(1),
|
||||||
|
"new": uint32(5),
|
||||||
|
"invalid": uint32(43),
|
||||||
|
"ignore": uint32(13),
|
||||||
|
"delete": uint32(3),
|
||||||
|
"delete_list": uint32(5),
|
||||||
|
"insert": uint32(9),
|
||||||
|
"insert_failed": uint32(10),
|
||||||
|
"drop": uint32(49),
|
||||||
|
"early_drop": uint32(7),
|
||||||
|
"icmp_error": uint32(21),
|
||||||
|
"expect_new": uint32(12),
|
||||||
|
"expect_create": uint32(44),
|
||||||
|
"expect_delete": uint32(53),
|
||||||
|
"search_restart": uint32(31),
|
||||||
|
}
|
||||||
|
|
||||||
require.Equal(t, 36, acc.NFields())
|
acc.AssertContainsTaggedFields(t, inputName, expectedFields1,
|
||||||
|
map[string]string{
|
||||||
|
"cpu": "cpu1",
|
||||||
|
})
|
||||||
|
|
||||||
|
allFields := map[string]interface{}{
|
||||||
|
"entries": uint32(129),
|
||||||
|
"searched": uint32(20),
|
||||||
|
"found": uint32(2),
|
||||||
|
"new": uint32(10),
|
||||||
|
"invalid": uint32(86),
|
||||||
|
"ignore": uint32(26),
|
||||||
|
"delete": uint32(6),
|
||||||
|
"delete_list": uint32(10),
|
||||||
|
"insert": uint32(18),
|
||||||
|
"insert_failed": uint32(40),
|
||||||
|
"drop": uint32(98),
|
||||||
|
"early_drop": uint32(17),
|
||||||
|
"icmp_error": uint32(42),
|
||||||
|
"expect_new": uint32(24),
|
||||||
|
"expect_create": uint32(88),
|
||||||
|
"expect_delete": uint32(106),
|
||||||
|
"search_restart": uint32(62),
|
||||||
|
}
|
||||||
|
|
||||||
|
acc.AssertContainsTaggedFields(t, inputName, allFields,
|
||||||
|
map[string]string{
|
||||||
|
"cpu": "all",
|
||||||
|
})
|
||||||
|
|
||||||
|
require.Equal(t, 53, acc.NFields())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCollectPsSystemInit(t *testing.T) {
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
cs := &Conntrack{
|
||||||
|
ps: system.NewSystemPS(),
|
||||||
|
Collect: []string{"all"},
|
||||||
|
}
|
||||||
|
require.NoError(t, cs.Init())
|
||||||
|
err := cs.Gather(&acc)
|
||||||
|
if err != nil && strings.Contains(err.Error(), "Is the conntrack kernel module loaded?") {
|
||||||
|
t.Skip("Conntrack kernel module not loaded.")
|
||||||
|
}
|
||||||
|
//make sure Conntrack.ps gets initialized without mocking
|
||||||
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue