Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Net 818 #3

Merged
merged 14 commits into from
Dec 3, 2024
Merged
101 changes: 88 additions & 13 deletions pkg/features/isis/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,48 @@ package isis

import (
"strconv"
"strings"

"github.com/czerwonk/junos_exporter/pkg/collector"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"

"github.com/czerwonk/junos_exporter/pkg/collector"
)

const prefix string = "junos_isis_"

var (
upCount *prometheus.Desc
totalCount *prometheus.Desc
adjState *prometheus.Desc
upCountDesc *prometheus.Desc
totalCountDesc *prometheus.Desc
adjStateDesc *prometheus.Desc
adjCountDesc *prometheus.Desc
adjPriorityDesc *prometheus.Desc
adjMetricDesc *prometheus.Desc
adjHelloTimerDesc *prometheus.Desc
adjHoldTimerDesc *prometheus.Desc
lspIntervalDesc *prometheus.Desc
csnpIntervalDesc *prometheus.Desc
helloPaddingDesc *prometheus.Desc
maxHelloSizeDesc *prometheus.Desc
)

func init() {
l := []string{"target"}
upCount = prometheus.NewDesc(prefix+"up_count", "Number of ISIS Adjacencies in state up", l, nil)
totalCount = prometheus.NewDesc(prefix+"total_count", "Number of ISIS Adjacencies", l, nil)
l = append(l, "interface_name", "sysem_name", "level")
adjState = prometheus.NewDesc(prefix+"adjacency_state", "The ISIS Adjacency state (0 = DOWN, 1 = UP, 2 = NEW, 3 = ONE-WAY, 4 =INITIALIZING , 5 = REJECTED)", l, nil)
upCountDesc = prometheus.NewDesc(prefix+"up_count", "Number of ISIS Adjacencies in state up", l, nil)
totalCountDesc = prometheus.NewDesc(prefix+"total_count", "Number of ISIS Adjacencies", l, nil)
l = append(l, "interface_name")
lspIntervalDesc = prometheus.NewDesc(prefix+"lsp_interval_ms", "The ISIS LSP interval", l, nil)
csnpIntervalDesc = prometheus.NewDesc(prefix+"csnp_interval_seconds", "The ISIS CSNP interval", l, nil)
helloPaddingDesc = prometheus.NewDesc(prefix+"hello_padding", "The ISIS hello padding (0 = UNKNOWN, 1 = ADAPTIVE, 2 = DISABLE, 3 = LOOSE, 4 = STRICT)", l, nil)
maxHelloSizeDesc = prometheus.NewDesc(prefix+"max_hello_size_bytes", "The ISIS max hello size", l, nil)
l = append(l, "system_name", "level")
adjStateDesc = prometheus.NewDesc(prefix+"adjacency_state", "The ISIS Adjacency state (0 = DOWN, 1 = UP, 2 = NEW, 3 = ONE-WAY, 4 =INITIALIZING , 5 = REJECTED)", l, nil)
interfaceMetricsLabels := []string{"target", "interface_name", "level"}
adjCountDesc = prometheus.NewDesc(prefix+"adjacency_count", "The number of ISIS adjacencies for an interface", interfaceMetricsLabels, nil)
adjPriorityDesc = prometheus.NewDesc(prefix+"adjacency_priority", "The ISIS adjacency priority", interfaceMetricsLabels, nil)
adjMetricDesc = prometheus.NewDesc(prefix+"adjacency_metric", "The ISIS adjacency metric", interfaceMetricsLabels, nil)
adjHelloTimerDesc = prometheus.NewDesc(prefix+"adjacency_hello_timer_seconds", "The ISIS adjacency hello timer", interfaceMetricsLabels, nil)
adjHoldTimerDesc = prometheus.NewDesc(prefix+"adjacency_hold_timer_seconds", "The ISIS adjacency hold timer", interfaceMetricsLabels, nil)
}

type isisCollector struct {
Expand All @@ -40,8 +63,17 @@ func (*isisCollector) Name() string {

// Describe describes the metrics
func (*isisCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- upCount
ch <- totalCount
ch <- upCountDesc
ch <- totalCountDesc
ch <- adjCountDesc
ch <- adjPriorityDesc
ch <- adjMetricDesc
ch <- adjHelloTimerDesc
ch <- adjHoldTimerDesc
ch <- lspIntervalDesc
ch <- csnpIntervalDesc
ch <- helloPaddingDesc
ch <- maxHelloSizeDesc
}

// Collect collects metrics from JunOS
Expand All @@ -51,8 +83,8 @@ func (c *isisCollector) Collect(client collector.Client, ch chan<- prometheus.Me
return err
}

ch <- prometheus.MustNewConstMetric(upCount, prometheus.GaugeValue, adjancies.Up, labelValues...)
ch <- prometheus.MustNewConstMetric(totalCount, prometheus.GaugeValue, adjancies.Total, labelValues...)
ch <- prometheus.MustNewConstMetric(upCountDesc, prometheus.GaugeValue, adjancies.Up, labelValues...)
ch <- prometheus.MustNewConstMetric(totalCountDesc, prometheus.GaugeValue, adjancies.Total, labelValues...)

if adjancies.Adjacencies != nil {
for _, adj := range adjancies.Adjacencies {
Expand All @@ -73,10 +105,16 @@ func (c *isisCollector) Collect(client collector.Client, ch chan<- prometheus.Me
state = 5.0
}

ch <- prometheus.MustNewConstMetric(adjState, prometheus.GaugeValue, state, localLabelvalues...)
ch <- prometheus.MustNewConstMetric(adjStateDesc, prometheus.GaugeValue, state, localLabelvalues...)
}
}

var ifas interfaces
err = client.RunCommandAndParse("show isis interface extensive", &ifas)
if err != nil {
return errors.Wrap(err, "failed to run command 'show isis interface extensive'")
}
c.isisInterfaces(ifas, ch, labelValues)
return nil
}

Expand All @@ -99,3 +137,40 @@ func (c *isisCollector) isisAdjancies(client collector.Client) (*adjacencies, er

return &adjacencies{Up: float64(up), Total: float64(total), Adjacencies: x.Information.Adjacencies}, nil
}

func (c *isisCollector) isisInterfaces(interfaces interfaces, ch chan<- prometheus.Metric, labelValues []string) {
for _, i := range interfaces.IsisInterfaceInformation.IsisInterface {
if strings.ToLower(i.InterfaceLevelData.Passive) == "passive" {
continue
}
labels := append(labelValues,
i.InterfaceName,
i.InterfaceLevelData.Level)
ch <- prometheus.MustNewConstMetric(adjCountDesc, prometheus.CounterValue, i.InterfaceLevelData.AdjacencyCount, labels...)
ch <- prometheus.MustNewConstMetric(adjPriorityDesc, prometheus.GaugeValue, i.InterfaceLevelData.InterfacePriority, labels...)
ch <- prometheus.MustNewConstMetric(adjMetricDesc, prometheus.GaugeValue, i.InterfaceLevelData.Metric, labels...)
ch <- prometheus.MustNewConstMetric(adjHelloTimerDesc, prometheus.GaugeValue, i.InterfaceLevelData.HelloTime, labels...)
ch <- prometheus.MustNewConstMetric(adjHoldTimerDesc, prometheus.GaugeValue, i.InterfaceLevelData.HoldTime, labels...)
additionaLabels := append(labelValues, i.InterfaceName)
helloPadding := getHelloPadding(i.HelloPadding)
ch <- prometheus.MustNewConstMetric(lspIntervalDesc, prometheus.GaugeValue, i.LSPInterval, additionaLabels...)
ch <- prometheus.MustNewConstMetric(csnpIntervalDesc, prometheus.GaugeValue, i.CSNPInterval, additionaLabels...)
ch <- prometheus.MustNewConstMetric(helloPaddingDesc, prometheus.GaugeValue, helloPadding, additionaLabels...)
ch <- prometheus.MustNewConstMetric(maxHelloSizeDesc, prometheus.GaugeValue, i.MaxHelloSize, additionaLabels...)
}
}

func getHelloPadding(h string) float64 {
switch strings.ToLower(h) {
case "adaptive":
return 1.0
case "disable":
return 2.0
case "loose":
return 3.0
case "strict":
return 4.0
default:
return 0.0
}
}
32 changes: 32 additions & 0 deletions pkg/features/isis/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

package isis

import "encoding/xml"

type result struct {
Information struct {
Adjacencies []adjacency `xml:"isis-adjacency"`
Expand All @@ -16,3 +18,33 @@ type adjacency struct {
Holdtime int64 `xml:"holdtime"`
SNPA string `xml:"snpa"`
}

type interfaces struct {
XMLName xml.Name `xml:"rpc-reply"`
Text string `xml:",chardata"`
Junos string `xml:"junos,attr"`
IsisInterfaceInformation struct {
Text string `xml:",chardata"`
Xmlns string `xml:"xmlns,attr"`
IsisInterface []struct {
InterfaceName string `xml:"interface-name"`
LSPInterval float64 `xml:"lsp-interval"`
CSNPInterval float64 `xml:"csnp-interval"`
HelloPadding string `xml:"hello-padding"`
MaxHelloSize float64 `xml:"max-hello-size"`
InterfaceLevelData struct {
Level string `xml:"level"`
AdjacencyCount float64 `xml:"adjacency-count"`
InterfacePriority float64 `xml:"interface-priority"`
Metric float64 `xml:"metric"`
HelloTime float64 `xml:"hello-time"`
HoldTime float64 `xml:"holdtime"`
Passive string `xml:"passive"`
} `xml:"interface-level-data"`
} `xml:"isis-interface"`
} `xml:"isis-interface-information"`
Cli struct {
Text string `xml:",chardata"`
Banner string `xml:"banner"`
} `xml:"cli"`
}