From 8f241a7a162c1c2e05775c70e3e07e9b22867b22 Mon Sep 17 00:00:00 2001 From: Phil Preston Date: Tue, 5 Jun 2018 01:58:20 +0100 Subject: [PATCH] Add counter fields to pf input (#4216) --- plugins/inputs/pf/README.md | 15 ++++++++++ plugins/inputs/pf/pf.go | 58 +++++++++++++++++++++++++++++------- plugins/inputs/pf/pf_test.go | 46 +++++++++++++++++++++++----- 3 files changed, 101 insertions(+), 18 deletions(-) diff --git a/plugins/inputs/pf/README.md b/plugins/inputs/pf/README.md index ed058671b..2e70de5b7 100644 --- a/plugins/inputs/pf/README.md +++ b/plugins/inputs/pf/README.md @@ -31,6 +31,21 @@ telegraf ALL=(root) NOPASSWD: /sbin/pfctl -s info - searches (integer, count) - inserts (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: diff --git a/plugins/inputs/pf/pf.go b/plugins/inputs/pf/pf.go index 9712ee8a6..04b5f9d21 100644 --- a/plugins/inputs/pf/pf.go +++ b/plugins/inputs/pf/pf.go @@ -67,7 +67,7 @@ func errMissingData(tag string) error { type pfctlOutputStanza struct { HeaderRE *regexp.Regexp - ParseFunc func([]string, telegraf.Accumulator) error + ParseFunc func([]string, map[string]interface{}) error Found bool } @@ -76,11 +76,16 @@ var pfctlOutputStanzas = []*pfctlOutputStanza{ HeaderRE: regexp.MustCompile("^State Table"), ParseFunc: parseStateTable, }, + &pfctlOutputStanza{ + HeaderRE: regexp.MustCompile("^Counters"), + ParseFunc: parseCounterTable, + }, } var anyTableHeaderRE = regexp.MustCompile("^[A-Z]") func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error { + fields := make(map[string]interface{}) scanner := bufio.NewScanner(strings.NewReader(pfoutput)) for scanner.Scan() { line := scanner.Text() @@ -91,10 +96,14 @@ func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error line = scanner.Text() for !anyTableHeaderRE.MatchString(line) { stanzaLines = append(stanzaLines, line) - scanner.Scan() - line = scanner.Text() + more := scanner.Scan() + if more { + line = scanner.Text() + } else { + break + } } - if perr := s.ParseFunc(stanzaLines, acc); perr != nil { + if perr := s.ParseFunc(stanzaLines, fields); perr != nil { return perr } s.Found = true @@ -106,6 +115,8 @@ func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error return errParseHeader } } + + acc.AddFields(measurement, fields, make(map[string]string)) return nil } @@ -124,11 +135,40 @@ var StateTable = []*Entry{ 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 { - entries := stateTableRE.FindStringSubmatch(v) + entries := regex.FindStringSubmatch(v) if entries != nil { - for _, f := range StateTable { + for _, f := range entryTable { if f.PfctlTitle == entries[1] { var err error 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 StateTable { + for _, v := range entryTable { if v.Value == -1 { return errMissingData(v.PfctlTitle) } fields[v.Field] = v.Value } - acc.AddFields(measurement, fields, make(map[string]string)) return nil } diff --git a/plugins/inputs/pf/pf_test.go b/plugins/inputs/pf/pf_test.go index 233e72592..0b90d949a 100644 --- a/plugins/inputs/pf/pf_test.go +++ b/plugins/inputs/pf/pf_test.go @@ -152,10 +152,25 @@ Counters measurements: []measurementResult{ measurementResult{ fields: map[string]interface{}{ - "entries": int64(2), - "searches": int64(11325), - "inserts": int64(5), - "removals": int64(3)}, + "entries": int64(2), + "searches": int64(11325), + "inserts": int64(5), + "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{}, }, }, @@ -197,10 +212,25 @@ Counters measurements: []measurementResult{ measurementResult{ fields: map[string]interface{}{ - "entries": int64(649), - "searches": int64(18421725761), - "inserts": int64(156762508), - "removals": int64(156761859)}, + "entries": int64(649), + "searches": int64(18421725761), + "inserts": int64(156762508), + "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{}, }, },