Skip to content

Commit

Permalink
Merge pull request #128 from AKYD/add_multi_re_support_routingengine
Browse files Browse the repository at this point in the history
Add multi routing engine support to the "routing_engine" module
  • Loading branch information
czerwonk authored Apr 20, 2021
2 parents 66d7bb3 + 2c81e2d commit ecf3a52
Show file tree
Hide file tree
Showing 3 changed files with 381 additions and 29 deletions.
139 changes: 115 additions & 24 deletions routingengine/collector.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package routingengine

import (
"encoding/xml"
"strings"

"github.com/czerwonk/junos_exporter/collector"
"github.com/czerwonk/junos_exporter/rpc"
"github.com/prometheus/client_golang/prometheus"
Expand All @@ -9,36 +12,59 @@ import (
const prefix string = "junos_route_engine_"

var (
temperature *prometheus.Desc
memoryUtilization *prometheus.Desc
cpuTemperature *prometheus.Desc
cpuUser *prometheus.Desc
cpuBackground *prometheus.Desc
cpuSystem *prometheus.Desc
cpuInterrupt *prometheus.Desc
cpuIdle *prometheus.Desc
loadAverageOne *prometheus.Desc
loadAverageFive *prometheus.Desc
loadAverageFifteen *prometheus.Desc
reStatus *prometheus.Desc
uptime *prometheus.Desc
temperature *prometheus.Desc
memoryUtilization *prometheus.Desc
memoryBufferUtilization *prometheus.Desc
cpuTemperature *prometheus.Desc
cpuUser *prometheus.Desc
cpuBackground *prometheus.Desc
cpuSystem *prometheus.Desc
cpuInterrupt *prometheus.Desc
cpuIdle *prometheus.Desc
loadAverageOne *prometheus.Desc
loadAverageFive *prometheus.Desc
loadAverageFifteen *prometheus.Desc
reStatus *prometheus.Desc
uptime *prometheus.Desc
memorySystemTotal *prometheus.Desc
memorySystemTotalUsed *prometheus.Desc
memorySystemTotalUtil *prometheus.Desc
memoryControlPlane *prometheus.Desc
memoryControlPlaneUsed *prometheus.Desc
memoryControlPlaneUtil *prometheus.Desc
memoryDataPlane *prometheus.Desc
memoryDataPlaneUsed *prometheus.Desc
memoryDataPlaneUtil *prometheus.Desc
mastershipState *prometheus.Desc
mastershipPriority *prometheus.Desc
)

func init() {
l := []string{"target", "slot"}
l := []string{"target", "re_name", "slot"}
temperature = prometheus.NewDesc(prefix+"temp", "Temperature of the air flowing past the Routing Engine (in degrees C)", l, nil)
memoryUtilization = prometheus.NewDesc(prefix+"memory_utilization", "Percentage of Routing Engine memory being used", l, nil)
memoryUtilization = prometheus.NewDesc(prefix+"memory_utilization_percent", "Percent of Routing Engine memory being used", l, nil)
cpuTemperature = prometheus.NewDesc(prefix+"cpu_temp", "Temperature of the CPU (in degrees C)", l, nil)
cpuUser = prometheus.NewDesc(prefix+"cpu_user_percent", "Percentage of CPU time being used by user processes", l, nil)
cpuBackground = prometheus.NewDesc(prefix+"cpu_background_percent", "Percentage of CPU time being used by background processes", l, nil)
cpuSystem = prometheus.NewDesc(prefix+"cpu_system_percent", "Percentage of CPU time being used by kernel processes", l, nil)
cpuInterrupt = prometheus.NewDesc(prefix+"cpu_interrupt_percent", "Percentage of CPU time being used by interrupts", l, nil)
cpuIdle = prometheus.NewDesc(prefix+"cpu_idle_percent", "Percentage of CPU time that is idle", l, nil)
cpuUser = prometheus.NewDesc(prefix+"cpu_user_percent", "Percent of CPU time being used by user processes", l, nil)
cpuBackground = prometheus.NewDesc(prefix+"cpu_background_percent", "Percent of CPU time being used by background processes", l, nil)
cpuSystem = prometheus.NewDesc(prefix+"cpu_system_percent", "Percent of CPU time being used by kernel processes", l, nil)
cpuInterrupt = prometheus.NewDesc(prefix+"cpu_interrupt_percent", "Percent of CPU time being used by interrupts", l, nil)
cpuIdle = prometheus.NewDesc(prefix+"cpu_idle_percent", "Percent of CPU time that is idle", l, nil)
loadAverageOne = prometheus.NewDesc(prefix+"load_average_one", "Routing Engine load averages for the last 1 minute", l, nil)
loadAverageFive = prometheus.NewDesc(prefix+"load_average_five", "Routing Engine load averages for the last 5 minutes", l, nil)
loadAverageFifteen = prometheus.NewDesc(prefix+"load_average_fifteen", "Routing Engine load averages for the last 15 minutes", l, nil)
uptime = prometheus.NewDesc(prefix+"uptime_seconds", "Seconds since boot", l, nil)
reStatus = prometheus.NewDesc(prefix+"status", "Status of routing-engine (1 OK, 2 Testing, 3 Failed, 4 Absent, 5 Present)", l, nil)

memorySystemTotal = prometheus.NewDesc(prefix+"memory_system_total_bytes", "Total System memory", l, nil)
memorySystemTotalUsed = prometheus.NewDesc(prefix+"memory_system_total_used_bytes", "System memory utilized", l, nil)
memoryControlPlane = prometheus.NewDesc(prefix+"memory_control_plane_bytes", "Total Control Plane memory", l, nil)
memoryControlPlaneUsed = prometheus.NewDesc(prefix+"memory_control_plane_used_bytes", "Control Plane utilized", l, nil)
memoryDataPlane = prometheus.NewDesc(prefix+"memory_data_plane_bytes", "Total Data Plane memory", l, nil)
memoryDataPlaneUsed = prometheus.NewDesc(prefix+"memory_data_plane_used_bytes", "Data Plane memory utilized", l, nil)

l = []string{"target", "re_name", "slot", "mastership"}
mastershipState = prometheus.NewDesc(prefix+"mastership_state", "Mastership state", l, nil)
mastershipPriority = prometheus.NewDesc(prefix+"mastership_priority", "Mastership priority", l, nil)
}

type routingEngineCollector struct {
Expand Down Expand Up @@ -69,24 +95,40 @@ func (*routingEngineCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- loadAverageFifteen
ch <- reStatus
ch <- uptime
ch <- memorySystemTotal
ch <- memorySystemTotalUsed
ch <- memoryControlPlane
ch <- memoryControlPlaneUsed
ch <- memoryDataPlane
ch <- memoryDataPlaneUsed
ch <- mastershipState
ch <- mastershipPriority
}

// Collect collects metrics from JunOS
func (c *routingEngineCollector) Collect(client *rpc.Client, ch chan<- prometheus.Metric, labelValues []string) error {
var x = RoutingEngineRpc{}
err := client.RunCommandAndParse("show chassis routing-engine", &x)
var x = RpcReply{}
err := client.RunCommandAndParseWithParser("show chassis routing-engine", func(b []byte) error {
return parseXML(b, &x)
})
if err != nil {
return err
}

for _, re := range x.Information.RouteEngine {
c.collectForSlot(re, ch, labelValues)
for _, re := range x.MultiRoutingEngineResults.RoutingEngine {
labelValues := append(labelValues, re.Name)
for _, re_ := range re.RouteEngineInformation.RouteEngines {
c.collectForSlot(re_, ch, labelValues)
}
}

return nil
}

func (c *routingEngineCollector) collectForSlot(re RouteEngine, ch chan<- prometheus.Metric, labelValues []string) error {
if re.Slot == "" {
re.Slot = "N/A"
}
l := append(labelValues, re.Slot)

ch <- prometheus.MustNewConstMetric(temperature, prometheus.GaugeValue, re.Temperature.Value, l...)
Expand All @@ -111,5 +153,54 @@ func (c *routingEngineCollector) collectForSlot(re RouteEngine, ch chan<- promet
}
ch <- prometheus.MustNewConstMetric(reStatus, prometheus.GaugeValue, float64(statusValues[re.Status]), l...)

if re.MemorySystemTotal > 0 {
ch <- prometheus.MustNewConstMetric(memorySystemTotal, prometheus.GaugeValue, float64(re.MemorySystemTotal)*1024*1024, l...)
}
if re.MemorySystemTotalUsed > 0 {
ch <- prometheus.MustNewConstMetric(memorySystemTotalUsed, prometheus.GaugeValue, float64(re.MemorySystemTotalUsed)*1024*1024, l...)
}
if re.MemoryControlPlane > 0 {
ch <- prometheus.MustNewConstMetric(memoryControlPlane, prometheus.GaugeValue, float64(re.MemoryControlPlane)*1024*1024, l...)
}
if re.MemoryControlPlaneUsed > 0 {
ch <- prometheus.MustNewConstMetric(memoryControlPlaneUsed, prometheus.GaugeValue, float64(re.MemoryControlPlaneUsed)*1024*1024, l...)
}
if re.MemoryDataPlane > 0 {
ch <- prometheus.MustNewConstMetric(memoryDataPlane, prometheus.GaugeValue, float64(re.MemoryDataPlane)*1024*1024, l...)
}
if re.MemoryDataPlaneUsed > 0 {
ch <- prometheus.MustNewConstMetric(memoryDataPlaneUsed, prometheus.GaugeValue, float64(re.MemoryDataPlaneUsed)*1024*1024, l...)
}

if re.MastershipState != "" {
ch <- prometheus.MustNewConstMetric(mastershipState, prometheus.GaugeValue, float64(1), append(l, re.MastershipState)...)
}

if re.MastershipPriority != "" {
ch <- prometheus.MustNewConstMetric(mastershipPriority, prometheus.GaugeValue, float64(1), append(l, re.MastershipPriority)...)
}

return nil
}

func parseXML(b []byte, res *RpcReply) error {
if strings.Contains(string(b), "multi-routing-engine-results") {
return xml.Unmarshal(b, res)
}

fi := RpcReplyNoRE{}

err := xml.Unmarshal(b, &fi)
if err != nil {
return err
}

res.MultiRoutingEngineResults.RoutingEngine = []RoutingEngine{
RoutingEngine{
Name: "N/A",
RouteEngineInformation: fi.RouteEngineInformation,
},
}

return nil
}
38 changes: 33 additions & 5 deletions routingengine/rpc.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
package routingengine

type RoutingEngineRpc struct {
Information struct {
RouteEngine []RouteEngine `xml:"route-engine"`
} `xml:"route-engine-information"`
import "encoding/xml"

type RpcReply struct {
XMLName xml.Name `xml:"rpc-reply"`
MultiRoutingEngineResults MultiRoutingEngineResults `xml:"multi-routing-engine-results"`
}

type MultiRoutingEngineResults struct {
RoutingEngine []RoutingEngine `xml:"multi-routing-engine-item"`
}

type RoutingEngine struct {
Name string `xml:"re-name"`
RouteEngineInformation RouteEngineInformation `xml:"route-engine-information"`
}

type RouteEngineInformation struct {
RouteEngines []RouteEngine `xml:"route-engine"`
}

type RouteEngine struct {
Slot string `xml:"slot"`
Slot string `xml:"slot,omitempty"`
Status string `xml:"status"`
Temperature RouteEngineTemperature `xml:"temperature"`
MemoryUtilization float64 `xml:"memory-buffer-utilization"`
Expand All @@ -23,8 +37,22 @@ type RouteEngine struct {
LoadAverageOne float64 `xml:"load-average-one"`
LoadAverageFive float64 `xml:"load-average-five"`
LoadAverageFifteen float64 `xml:"load-average-fifteen"`

MemorySystemTotal float64 `xml:"memory-system-total,omitempty"`
MemorySystemTotalUsed float64 `xml:"memory-system-total-used,omitempty"`
MemoryControlPlane float64 `xml:"memory-control-plane,omitempty"`
MemoryControlPlaneUsed float64 `xml:"memory-control-plane-used,omitempty"`
MemoryDataPlane float64 `xml:"memory-data-plane,omitempty"`
MemoryDataPlaneUsed float64 `xml:"memory-data-plane-used,omitempty"`
MastershipState string `xml:"mastership-state,omitempty"`
MastershipPriority string `xml:"mastership-priority,omitempty"`
}

type RouteEngineTemperature struct {
Value float64 `xml:"celsius,attr"`
}

type RpcReplyNoRE struct {
XMLName xml.Name `xml:"rpc-reply"`
RouteEngineInformation RouteEngineInformation `xml:"route-engine-information"`
}
Loading

0 comments on commit ecf3a52

Please sign in to comment.