Skip to content

Commit

Permalink
scrape underlying interfaces (subscriber module) (czerwonk#238)
Browse files Browse the repository at this point in the history
* netdev-786/collect-subscriber-information
* now scrapes interface information to include underlying interfaces for each subscriber

---------

Co-authored-by: Jakob Gastinger <jgastinger@anexia-it.com>
Co-authored-by: Jakob Gastinger <jgastinger@anexia.com>
  • Loading branch information
3 people authored Jan 17, 2024
1 parent 143e797 commit dac0d11
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 14 deletions.
65 changes: 57 additions & 8 deletions pkg/features/subscriber/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@
package subscriber

import (
"errors"
"fmt"
"strings"

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

const prefix string = "junos_subscriber_info"

var subscriberInfoDesc *prometheus.Desc
var subscriberInfo *prometheus.Desc

func init() {
l := []string{"target", "interface", "agent_circuit_id", "agent_remote_id"}
subscriberInfoDesc = prometheus.NewDesc(prefix+"", "Subscriber Detail", l, nil)
l := []string{"target", "interface", "agent_circuit_id", "agent_remote_id", "underlying_ifd"}
subscriberInfo = prometheus.NewDesc(prefix+"", "Subscriber Detail", l, nil)
}

// Name implements collector.RPCCollector.
Expand All @@ -28,21 +32,66 @@ func NewCollector() collector.RPCCollector {

// Describe describes the metrics
func (*subcsribers_information) Describe(ch chan<- *prometheus.Desc) {
ch <- subscriberInfoDesc
ch <- subscriberInfo
}

// Collect collects metrics from JunOS
func (c *subcsribers_information) Collect(client collector.Client, ch chan<- prometheus.Metric, labelValues []string) error {
var x = subcsribers_information{}
err := client.RunCommandAndParse("show subscribers client-type dhcp detail", &x)
err := client.RunCommandAndParse("show subscribers client-type dhcp detail", &x) //TODO: see if client-type dhcp can be left out
if err != nil {
return err
}

for _, subscriber := range x.SubscribersInformation.Subscriber {
labels := append(labelValues, subscriber.Interface, subscriber.AgentCircuitID, subscriber.AgentRemoteID)
ch <- prometheus.MustNewConstMetric(subscriberInfoDesc, prometheus.CounterValue, 1, labels...)
logicalInterfaceMap, err := getLogicalInterfaceInformation(client)
if err != nil {
return err
}

for _, subscriber := range x.SubscribersInformation.Subscriber {
underlying_interface, err := findUnderlyingInterface(client, subscriber.UnderlyingInterface, logicalInterfaceMap, 2)
if err != nil {
fmt.Println(err)
}

labels := append(labelValues, subscriber.Interface, subscriber.AgentCircuitId, subscriber.AgentRemoteId, underlying_interface)
ch <- prometheus.MustNewConstMetric(subscriberInfo, prometheus.CounterValue, 1, labels...)
}
return nil
}

func getLogicalInterfaceInformation(client collector.Client) (map[string]string, error) {

var interfaceInformation = &InterfaceInformation{}
var interfaceMap = make(map[string]string)

err := client.RunCommandAndParse("show interfaces demux0 brief", interfaceInformation)
if err != nil {
return nil, err
}

for _, logicalInterface := range interfaceInformation.LogicalInterfaces {
interfaceMap[logicalInterface.Name] = logicalInterface.DemuxUnderlyingIfName
}

return interfaceMap, nil
}

func findUnderlyingInterface(client collector.Client, ifName string, logicalIfMap map[string]string, maxDepth int) (string, error) {

if !(strings.HasPrefix(ifName, "demux")) {
return ifName, nil
}

if maxDepth < 0 {
return "", errors.New("no underlying interface found, max treshold reached")
}

logicalIfName, exists := logicalIfMap[ifName]
if !exists {
return "", errors.New("no underlying interface found")
}

return findUnderlyingInterface(client, logicalIfName, logicalIfMap, maxDepth-1)

}
22 changes: 16 additions & 6 deletions pkg/features/subscriber/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@ package subscriber

type subcsribers_information struct {
SubscribersInformation struct {
Subscriber []subscriber `xml:"subscriber"`
Subscriber []Subscriber `xml:"subscriber"`
} `xml:"subscribers-information"`
}

type subscriber struct {
AccessType string `xml:"access-type"`
Interface string `xml:"interface"`
AgentCircuitID string `xml:"agent-circuit-id"`
AgentRemoteID string `xml:"agent-remote-id"`
type Subscriber struct {
AccessType string `xml:"access-type"`
Interface string `xml:"interface"`
AgentCircuitId string `xml:"agent-circuit-id"`
AgentRemoteId string `xml:"agent-remote-id"`
UnderlyingInterface string `xml:"underlying-interface"`
}

type InterfaceInformation struct {
LogicalInterfaces []LogicalInterface `xml:"interface-information>physical-interface>logical-interface"`
}

type LogicalInterface struct {
Name string `xml:"name"`
DemuxUnderlyingIfName string `xml:"demux-information>demux-interface>demux-underlying-interface-name"`
}

0 comments on commit dac0d11

Please sign in to comment.