This commit is contained in:
Daniel Czerwonk 2017-11-29 20:03:52 +01:00
parent 577c149b22
commit f66fc00242
5 changed files with 205 additions and 32 deletions

View File

@ -11,7 +11,7 @@ import (
"github.com/prometheus/common/log"
)
const version string = "0.8.3"
const version string = "0.9.0"
var (
showVersion = flag.Bool("version", false, "Print version information.")

View File

@ -17,12 +17,14 @@ var (
protocolRegex *regexp.Regexp
routeRegex *regexp.Regexp
uptimeRegex *regexp.Regexp
routeChangeRegex *regexp.Regexp
)
func init() {
protocolRegex, _ = regexp.Compile("^(?:1002\\-)?([^\\s]+)\\s+(BGP|OSPF)\\s+([^\\s]+)\\s+([^\\s]+)\\s+([^\\s]+)(?:\\s+(.*?))?$")
routeRegex, _ = regexp.Compile("^\\s+Routes:\\s+(\\d+) imported, (?:(\\d+) filtered, )?(\\d+) exported(?:, (\\d+) preferred)?")
uptimeRegex, _ = regexp.Compile("^(?:((\\d+):(\\d{2}):(\\d{2}))|\\d+)$")
protocolRegex = regexp.MustCompile("^(?:1002\\-)?([^\\s]+)\\s+(BGP|OSPF)\\s+([^\\s]+)\\s+([^\\s]+)\\s+([^\\s]+)(?:\\s+(.*?))?$")
routeRegex = regexp.MustCompile("^\\s+Routes:\\s+(\\d+) imported, (?:(\\d+) filtered, )?(\\d+) exported(?:, (\\d+) preferred)?")
uptimeRegex = regexp.MustCompile("^(?:((\\d+):(\\d{2}):(\\d{2}))|\\d+)$")
routeChangeRegex = regexp.MustCompile("(Import|Export) (updates|withdraws):\\s+(\\d+|---)\\s+(\\d+|---)\\s+(\\d+|---)\\s+(\\d+|---)\\s+(\\d+|---)\\s*")
}
func parseOutput(data []byte, ipVersion int) []*protocol.Protocol {
@ -41,6 +43,7 @@ func parseOutput(data []byte, ipVersion int) []*protocol.Protocol {
if current != nil {
parseLineForRoutes(line, current)
parseLineForRouteChanges(line, current)
}
if line == "" {
@ -59,9 +62,11 @@ func parseLineForProtocol(line string, ipVersion int) (*protocol.Protocol, bool)
}
proto := parseProto(match[2])
up := parseState(match[4])
ut := parseUptime(match[5])
p := &protocol.Protocol{Proto: proto, Name: match[1], IpVersion: ipVersion, Up: up, Uptime: ut, Attributes: make(map[string]float64)}
p := protocol.NewProtocol(match[1], proto, ipVersion, ut)
p.Up = parseState(match[4])
fillAttributes(p, match)
return p, true
@ -81,17 +86,19 @@ func parseProto(val string) int {
func parseLineForRoutes(line string, p *protocol.Protocol) {
match := routeRegex.FindStringSubmatch(line)
if match != nil {
p.Imported, _ = strconv.ParseInt(match[1], 10, 64)
p.Exported, _ = strconv.ParseInt(match[3], 10, 64)
if match == nil {
return
}
if len(match[2]) > 0 {
p.Filtered, _ = strconv.ParseInt(match[2], 10, 64)
}
p.Imported, _ = strconv.ParseInt(match[1], 10, 64)
p.Exported, _ = strconv.ParseInt(match[3], 10, 64)
if len(match[4]) > 0 {
p.Preferred, _ = strconv.ParseInt(match[4], 10, 64)
}
if len(match[2]) > 0 {
p.Filtered, _ = strconv.ParseInt(match[2], 10, 64)
}
if len(match[4]) > 0 {
p.Preferred, _ = strconv.ParseInt(match[4], 10, 64)
}
}
@ -105,7 +112,6 @@ func parseState(state string) int {
func parseUptime(value string) int {
match := uptimeRegex.FindStringSubmatch(value)
if match == nil {
return 0
}
@ -141,6 +147,44 @@ func parseUptimeForTimestamp(timestamp string) int {
return int(d.Seconds())
}
func parseLineForRouteChanges(line string, p *protocol.Protocol) {
match := routeChangeRegex.FindStringSubmatch(line)
if match == nil {
return
}
c := getRouteChangeCount(match, p)
c.Received = parseRouteChangeValue(match[3])
c.Rejected = parseRouteChangeValue(match[4])
c.Filtered = parseRouteChangeValue(match[5])
c.Ignored = parseRouteChangeValue(match[6])
c.Accepted = parseRouteChangeValue(match[7])
}
func getRouteChangeCount(values []string, p *protocol.Protocol) *protocol.RouteChangeCount {
if values[1] == "Import" {
if values[2] == "updates" {
return &p.ImportUpdates
}
return &p.ImportWithdraws
} else {
if values[2] == "updates" {
return &p.ExportUpdates
}
return &p.ExportWithdraws
}
}
func parseRouteChangeValue(value string) int64 {
if value == "---" {
return 0
}
return parseInt(value)
}
func parseInt(value string) int64 {
i, err := strconv.ParseInt(value, 10, 64)

View File

@ -70,6 +70,39 @@ func Test2BgpSessions(t *testing.T) {
assert.IntEqual("protocols", 2, len(p), t)
}
func TestUpdateAndWithdrawCounts(t *testing.T) {
data := "foo BGP master up 00:01:00 Established\ntest\n" +
" Routes: 12 imported, 1 filtered, 34 exported, 100 preferred\n" +
" Route change stats: received rejected filtered ignored accepted\n" +
" Import updates: 1 2 3 4 5\n" +
" Import withdraws: 6 7 8 9 10\n" +
" Export updates: 11 12 13 14 15\n" +
" Export withdraws: 16 17 18 19 ---"
p := parseOutput([]byte(data), 4)
x := p[0]
assert.Int64Equal("import updates received", 1, x.ImportUpdates.Received, t)
assert.Int64Equal("import updates rejected", 2, x.ImportUpdates.Rejected, t)
assert.Int64Equal("import updates filtered", 3, x.ImportUpdates.Filtered, t)
assert.Int64Equal("import updates ignored", 4, x.ImportUpdates.Ignored, t)
assert.Int64Equal("import updates accepted", 5, x.ImportUpdates.Accepted, t)
assert.Int64Equal("import withdraws received", 6, x.ImportWithdraws.Received, t)
assert.Int64Equal("import withdraws rejected", 7, x.ImportWithdraws.Rejected, t)
assert.Int64Equal("import withdraws filtered", 8, x.ImportWithdraws.Filtered, t)
assert.Int64Equal("import withdraws ignored", 9, x.ImportWithdraws.Ignored, t)
assert.Int64Equal("import withdraws accepted", 10, x.ImportWithdraws.Accepted, t)
assert.Int64Equal("export updates received", 11, x.ExportUpdates.Received, t)
assert.Int64Equal("export updates rejected", 12, x.ExportUpdates.Rejected, t)
assert.Int64Equal("export updates filtered", 13, x.ExportUpdates.Filtered, t)
assert.Int64Equal("export updates ignored", 14, x.ExportUpdates.Ignored, t)
assert.Int64Equal("export updates accepted", 15, x.ExportUpdates.Accepted, t)
assert.Int64Equal("export withdraws received", 16, x.ExportWithdraws.Received, t)
assert.Int64Equal("export withdraws rejected", 17, x.ExportWithdraws.Rejected, t)
assert.Int64Equal("export withdraws filtered", 18, x.ExportWithdraws.Filtered, t)
assert.Int64Equal("export withdraws ignored", 19, x.ExportWithdraws.Ignored, t)
assert.Int64Equal("export withdraws accepted", 0, x.ExportWithdraws.Accepted, t)
}
func TestOspfOldTimeFormat(t *testing.T) {
data := "ospf1 OSPF master up 1481973060 Running\ntest\nbar\n Routes: 12 imported, 34 exported, 100 preferred\nxxx"
p := parseOutput([]byte(data), 4)

View File

@ -3,12 +3,32 @@ package protocol
import "github.com/prometheus/client_golang/prometheus"
type GenericProtocolMetricExporter struct {
upDesc *prometheus.Desc
importCountDesc *prometheus.Desc
exportCountDesc *prometheus.Desc
filterCountDesc *prometheus.Desc
preferredCountDesc *prometheus.Desc
uptimeDesc *prometheus.Desc
upDesc *prometheus.Desc
importCountDesc *prometheus.Desc
exportCountDesc *prometheus.Desc
filterCountDesc *prometheus.Desc
preferredCountDesc *prometheus.Desc
uptimeDesc *prometheus.Desc
updatesImportReceiveCountDesc *prometheus.Desc
updatesImportRejectCountDesc *prometheus.Desc
updatesImportFilterCountDesc *prometheus.Desc
updatesImportIgnoreCountDesc *prometheus.Desc
updatesImportAcceptCountDesc *prometheus.Desc
withdrawsImportReceiveCountDesc *prometheus.Desc
withdrawsImportRejectCountDesc *prometheus.Desc
withdrawsImportFilterCountDesc *prometheus.Desc
withdrawsImportIgnoreCountDesc *prometheus.Desc
withdrawsImportAcceptCountDesc *prometheus.Desc
updatesExportReceiveCountDesc *prometheus.Desc
updatesExportRejectCountDesc *prometheus.Desc
updatesExportFilterCountDesc *prometheus.Desc
updatesExportIgnoreCountDesc *prometheus.Desc
updatesExportAcceptCountDesc *prometheus.Desc
withdrawsExportReceiveCountDesc *prometheus.Desc
withdrawsExportRejectCountDesc *prometheus.Desc
withdrawsExportFilterCountDesc *prometheus.Desc
withdrawsExportIgnoreCountDesc *prometheus.Desc
withdrawsExportAcceptCountDesc *prometheus.Desc
}
func NewGenericProtocolMetricExporter(prefix string) *GenericProtocolMetricExporter {
@ -26,6 +46,26 @@ func (m *GenericProtocolMetricExporter) initDesc(prefix string) {
m.filterCountDesc = prometheus.NewDesc(prefix+"_prefix_count_filter", "Number of filtered routes", labels, nil)
m.preferredCountDesc = prometheus.NewDesc(prefix+"_prefix_count_preferred", "Number of preferred routes", labels, nil)
m.uptimeDesc = prometheus.NewDesc(prefix+"_uptime", "Uptime of the protocol in seconds", labels, nil)
m.updatesImportIgnoreCountDesc = prometheus.NewDesc(prefix+"_changes_update_import_ignore_count", "Number of incoming updates beeing ignored", labels, nil)
m.updatesImportAcceptCountDesc = prometheus.NewDesc(prefix+"_changes_update_import_accept_count", "Number of incoming updates beeing accepted", labels, nil)
m.updatesImportFilterCountDesc = prometheus.NewDesc(prefix+"_changes_update_import_filter_count", "Number of incoming updates beeing filtered", labels, nil)
m.updatesImportRejectCountDesc = prometheus.NewDesc(prefix+"_changes_update_import_reject_count", "Number of incoming updates beeing rejected", labels, nil)
m.updatesImportReceiveCountDesc = prometheus.NewDesc(prefix+"_changes_update_import_receive_count", "Number of received updates", labels, nil)
m.withdrawsImportIgnoreCountDesc = prometheus.NewDesc(prefix+"_changes_withdraw_import_ignore_count", "Number of incoming withdraws beeing ignored", labels, nil)
m.withdrawsImportAcceptCountDesc = prometheus.NewDesc(prefix+"_changes_withdraw_import_accept_count", "Number of incoming withdraws beeing accepted", labels, nil)
m.withdrawsImportFilterCountDesc = prometheus.NewDesc(prefix+"_changes_withdraw_import_filter_count", "Number of incoming withdraws beeing filtered", labels, nil)
m.withdrawsImportRejectCountDesc = prometheus.NewDesc(prefix+"_changes_withdraw_import_reject_count", "Number of incoming withdraws beeing rejected", labels, nil)
m.withdrawsImportReceiveCountDesc = prometheus.NewDesc(prefix+"_changes_withdraw_import_receive_count", "Number of received withdraws", labels, nil)
m.updatesExportIgnoreCountDesc = prometheus.NewDesc(prefix+"_changes_update_export_ignore_count", "Number of outgoing updates beeing ignored", labels, nil)
m.updatesExportAcceptCountDesc = prometheus.NewDesc(prefix+"_changes_update_export_accept_count", "Number of outgoing updates beeing accepted", labels, nil)
m.updatesExportFilterCountDesc = prometheus.NewDesc(prefix+"_changes_update_export_filter_count", "Number of outgoing updates beeing filtered", labels, nil)
m.updatesExportRejectCountDesc = prometheus.NewDesc(prefix+"_changes_update_export_reject_count", "Number of outgoing updates beeing rejected", labels, nil)
m.updatesExportReceiveCountDesc = prometheus.NewDesc(prefix+"_changes_update_export_receive_count", "Number of sent updates", labels, nil)
m.withdrawsExportIgnoreCountDesc = prometheus.NewDesc(prefix+"_changes_withdraw_export_ignore_count", "Number of outgoing withdraws beeing ignored", labels, nil)
m.withdrawsExportAcceptCountDesc = prometheus.NewDesc(prefix+"_changes_withdraw_export_accept_count", "Number of outgoing withdraws beeing accepted", labels, nil)
m.withdrawsExportFilterCountDesc = prometheus.NewDesc(prefix+"_changes_withdraw_export_filter_count", "Number of outgoing withdraws beeing filtered", labels, nil)
m.withdrawsExportRejectCountDesc = prometheus.NewDesc(prefix+"_changes_withdraw_export_reject_count", "Number of outgoing withdraws beeing rejected", labels, nil)
m.withdrawsExportReceiveCountDesc = prometheus.NewDesc(prefix+"_changes_withdraw_export_receive_count", "Number of outgoing withdraws", labels, nil)
}
func (m *GenericProtocolMetricExporter) Describe(ch chan<- *prometheus.Desc) {
@ -35,6 +75,26 @@ func (m *GenericProtocolMetricExporter) Describe(ch chan<- *prometheus.Desc) {
ch <- m.filterCountDesc
ch <- m.preferredCountDesc
ch <- m.uptimeDesc
ch <- m.updatesImportReceiveCountDesc
ch <- m.updatesImportRejectCountDesc
ch <- m.updatesImportFilterCountDesc
ch <- m.updatesImportIgnoreCountDesc
ch <- m.updatesImportAcceptCountDesc
ch <- m.updatesExportReceiveCountDesc
ch <- m.updatesExportRejectCountDesc
ch <- m.updatesExportFilterCountDesc
ch <- m.updatesExportIgnoreCountDesc
ch <- m.updatesExportAcceptCountDesc
ch <- m.withdrawsImportIgnoreCountDesc
ch <- m.withdrawsImportAcceptCountDesc
ch <- m.withdrawsImportFilterCountDesc
ch <- m.withdrawsImportRejectCountDesc
ch <- m.withdrawsImportReceiveCountDesc
ch <- m.withdrawsExportIgnoreCountDesc
ch <- m.withdrawsExportAcceptCountDesc
ch <- m.withdrawsExportFilterCountDesc
ch <- m.withdrawsExportRejectCountDesc
ch <- m.withdrawsExportReceiveCountDesc
}
func (m *GenericProtocolMetricExporter) Export(protocol *Protocol, ch chan<- prometheus.Metric) {
@ -44,4 +104,24 @@ func (m *GenericProtocolMetricExporter) Export(protocol *Protocol, ch chan<- pro
ch <- prometheus.MustNewConstMetric(m.filterCountDesc, prometheus.GaugeValue, float64(protocol.Filtered), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.preferredCountDesc, prometheus.GaugeValue, float64(protocol.Preferred), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.uptimeDesc, prometheus.GaugeValue, float64(protocol.Uptime), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.updatesImportReceiveCountDesc, prometheus.GaugeValue, float64(protocol.ImportUpdates.Received), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.updatesImportRejectCountDesc, prometheus.GaugeValue, float64(protocol.ImportUpdates.Rejected), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.updatesImportFilterCountDesc, prometheus.GaugeValue, float64(protocol.ImportUpdates.Filtered), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.updatesImportAcceptCountDesc, prometheus.GaugeValue, float64(protocol.ImportUpdates.Accepted), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.updatesImportIgnoreCountDesc, prometheus.GaugeValue, float64(protocol.ImportUpdates.Ignored), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.updatesExportReceiveCountDesc, prometheus.GaugeValue, float64(protocol.ExportUpdates.Received), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.updatesExportRejectCountDesc, prometheus.GaugeValue, float64(protocol.ExportUpdates.Rejected), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.updatesExportFilterCountDesc, prometheus.GaugeValue, float64(protocol.ExportUpdates.Filtered), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.updatesExportAcceptCountDesc, prometheus.GaugeValue, float64(protocol.ExportUpdates.Accepted), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.updatesExportIgnoreCountDesc, prometheus.GaugeValue, float64(protocol.ExportUpdates.Ignored), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.withdrawsImportReceiveCountDesc, prometheus.GaugeValue, float64(protocol.ImportWithdraws.Received), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.withdrawsImportRejectCountDesc, prometheus.GaugeValue, float64(protocol.ImportWithdraws.Rejected), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.withdrawsImportFilterCountDesc, prometheus.GaugeValue, float64(protocol.ImportWithdraws.Filtered), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.withdrawsImportAcceptCountDesc, prometheus.GaugeValue, float64(protocol.ImportWithdraws.Accepted), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.withdrawsImportIgnoreCountDesc, prometheus.GaugeValue, float64(protocol.ImportWithdraws.Ignored), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.withdrawsExportReceiveCountDesc, prometheus.GaugeValue, float64(protocol.ExportWithdraws.Received), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.withdrawsExportRejectCountDesc, prometheus.GaugeValue, float64(protocol.ExportWithdraws.Rejected), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.withdrawsExportFilterCountDesc, prometheus.GaugeValue, float64(protocol.ExportWithdraws.Filtered), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.withdrawsExportAcceptCountDesc, prometheus.GaugeValue, float64(protocol.ExportWithdraws.Accepted), protocol.Name)
ch <- prometheus.MustNewConstMetric(m.withdrawsExportIgnoreCountDesc, prometheus.GaugeValue, float64(protocol.ExportWithdraws.Ignored), protocol.Name)
}

View File

@ -7,14 +7,30 @@ const (
)
type Protocol struct {
Name string
IpVersion int
Proto int
Up int
Imported int64
Exported int64
Filtered int64
Preferred int64
Uptime int
Attributes map[string]float64
Name string
IpVersion int
Proto int
Up int
Imported int64
Exported int64
Filtered int64
Preferred int64
Uptime int
Attributes map[string]float64
ImportUpdates RouteChangeCount
ImportWithdraws RouteChangeCount
ExportUpdates RouteChangeCount
ExportWithdraws RouteChangeCount
}
type RouteChangeCount struct {
Received int64
Rejected int64
Filtered int64
Ignored int64
Accepted int64
}
func NewProtocol(name string, proto, ipVersion, uptime int) *Protocol {
return &Protocol{Name: name, Proto: proto, IpVersion: ipVersion, Uptime: uptime, Attributes: make(map[string]float64)}
}