Add counter fields to pf input (#4216)

This commit is contained in:
Phil Preston 2018-06-05 01:58:20 +01:00 committed by Daniel Nelson
parent be8b87000c
commit 9eab3572ff
No known key found for this signature in database
GPG Key ID: CAAD59C9444F6155
3 changed files with 101 additions and 18 deletions

View File

@ -31,6 +31,21 @@ telegraf ALL=(root) NOPASSWD: /sbin/pfctl -s info
- searches (integer, count) - searches (integer, count)
- inserts (integer, count) - inserts (integer, count)
- removals (integer, count) - removals (integer, count)
- match (integer, count)
- bad-offset (integer, count)
- fragment (integer, count)
- short (integer, count)
- normalize (integer, count)
- memory (integer, count)
- bad-timestamp (integer, count)
- congestion (integer, count)
- ip-option (integer, count)
- proto-cksum (integer, count)
- state-mismatch (integer, count)
- state-insert (integer, count)
- state-limit (integer, count)
- src-limit (integer, count)
- synproxy (integer, count)
### Example Output: ### Example Output:

View File

@ -67,7 +67,7 @@ func errMissingData(tag string) error {
type pfctlOutputStanza struct { type pfctlOutputStanza struct {
HeaderRE *regexp.Regexp HeaderRE *regexp.Regexp
ParseFunc func([]string, telegraf.Accumulator) error ParseFunc func([]string, map[string]interface{}) error
Found bool Found bool
} }
@ -76,11 +76,16 @@ var pfctlOutputStanzas = []*pfctlOutputStanza{
HeaderRE: regexp.MustCompile("^State Table"), HeaderRE: regexp.MustCompile("^State Table"),
ParseFunc: parseStateTable, ParseFunc: parseStateTable,
}, },
&pfctlOutputStanza{
HeaderRE: regexp.MustCompile("^Counters"),
ParseFunc: parseCounterTable,
},
} }
var anyTableHeaderRE = regexp.MustCompile("^[A-Z]") var anyTableHeaderRE = regexp.MustCompile("^[A-Z]")
func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error { func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error {
fields := make(map[string]interface{})
scanner := bufio.NewScanner(strings.NewReader(pfoutput)) scanner := bufio.NewScanner(strings.NewReader(pfoutput))
for scanner.Scan() { for scanner.Scan() {
line := scanner.Text() line := scanner.Text()
@ -91,10 +96,14 @@ func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error
line = scanner.Text() line = scanner.Text()
for !anyTableHeaderRE.MatchString(line) { for !anyTableHeaderRE.MatchString(line) {
stanzaLines = append(stanzaLines, line) stanzaLines = append(stanzaLines, line)
scanner.Scan() more := scanner.Scan()
if more {
line = scanner.Text() line = scanner.Text()
} else {
break
} }
if perr := s.ParseFunc(stanzaLines, acc); perr != nil { }
if perr := s.ParseFunc(stanzaLines, fields); perr != nil {
return perr return perr
} }
s.Found = true s.Found = true
@ -106,6 +115,8 @@ func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error
return errParseHeader return errParseHeader
} }
} }
acc.AddFields(measurement, fields, make(map[string]string))
return nil return nil
} }
@ -124,11 +135,40 @@ var StateTable = []*Entry{
var stateTableRE = regexp.MustCompile(`^ (.*?)\s+(\d+)`) var stateTableRE = regexp.MustCompile(`^ (.*?)\s+(\d+)`)
func parseStateTable(lines []string, acc telegraf.Accumulator) error { func parseStateTable(lines []string, fields map[string]interface{}) error {
return storeFieldValues(lines, stateTableRE, fields, StateTable)
}
var CounterTable = []*Entry{
&Entry{"match", "match", -1},
&Entry{"bad-offset", "bad-offset", -1},
&Entry{"fragment", "fragment", -1},
&Entry{"short", "short", -1},
&Entry{"normalize", "normalize", -1},
&Entry{"memory", "memory", -1},
&Entry{"bad-timestamp", "bad-timestamp", -1},
&Entry{"congestion", "congestion", -1},
&Entry{"ip-option", "ip-option", -1},
&Entry{"proto-cksum", "proto-cksum", -1},
&Entry{"state-mismatch", "state-mismatch", -1},
&Entry{"state-insert", "state-insert", -1},
&Entry{"state-limit", "state-limit", -1},
&Entry{"src-limit", "src-limit", -1},
&Entry{"synproxy", "synproxy", -1},
}
var counterTableRE = regexp.MustCompile(`^ (.*?)\s+(\d+)`)
func parseCounterTable(lines []string, fields map[string]interface{}) error {
return storeFieldValues(lines, counterTableRE, fields, CounterTable)
}
func storeFieldValues(lines []string, regex *regexp.Regexp, fields map[string]interface{}, entryTable []*Entry) error {
for _, v := range lines { for _, v := range lines {
entries := stateTableRE.FindStringSubmatch(v) entries := regex.FindStringSubmatch(v)
if entries != nil { if entries != nil {
for _, f := range StateTable { for _, f := range entryTable {
if f.PfctlTitle == entries[1] { if f.PfctlTitle == entries[1] {
var err error var err error
if f.Value, err = strconv.ParseInt(entries[2], 10, 64); err != nil { if f.Value, err = strconv.ParseInt(entries[2], 10, 64); err != nil {
@ -139,15 +179,13 @@ func parseStateTable(lines []string, acc telegraf.Accumulator) error {
} }
} }
fields := make(map[string]interface{}) for _, v := range entryTable {
for _, v := range StateTable {
if v.Value == -1 { if v.Value == -1 {
return errMissingData(v.PfctlTitle) return errMissingData(v.PfctlTitle)
} }
fields[v.Field] = v.Value fields[v.Field] = v.Value
} }
acc.AddFields(measurement, fields, make(map[string]string))
return nil return nil
} }

View File

@ -155,7 +155,22 @@ Counters
"entries": int64(2), "entries": int64(2),
"searches": int64(11325), "searches": int64(11325),
"inserts": int64(5), "inserts": int64(5),
"removals": int64(3)}, "removals": int64(3),
"match": int64(11226),
"bad-offset": int64(0),
"fragment": int64(0),
"short": int64(0),
"normalize": int64(0),
"memory": int64(0),
"bad-timestamp": int64(0),
"congestion": int64(0),
"ip-option": int64(0),
"proto-cksum": int64(0),
"state-mismatch": int64(0),
"state-insert": int64(0),
"state-limit": int64(0),
"src-limit": int64(0),
"synproxy": int64(0)},
tags: map[string]string{}, tags: map[string]string{},
}, },
}, },
@ -200,7 +215,22 @@ Counters
"entries": int64(649), "entries": int64(649),
"searches": int64(18421725761), "searches": int64(18421725761),
"inserts": int64(156762508), "inserts": int64(156762508),
"removals": int64(156761859)}, "removals": int64(156761859),
"match": int64(473002784),
"bad-offset": int64(0),
"fragment": int64(2729),
"short": int64(107),
"normalize": int64(1685),
"memory": int64(101),
"bad-timestamp": int64(0),
"congestion": int64(0),
"ip-option": int64(152301),
"proto-cksum": int64(108),
"state-mismatch": int64(24393),
"state-insert": int64(92),
"state-limit": int64(0),
"src-limit": int64(0),
"synproxy": int64(0)},
tags: map[string]string{}, tags: map[string]string{},
}, },
}, },