-
Notifications
You must be signed in to change notification settings - Fork 11
/
collector.go
executable file
·137 lines (116 loc) · 3.48 KB
/
collector.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package main
import (
"fmt"
"log"
"sync"
"github.com/maesoser/tplink_exporter/macdb"
"github.com/maesoser/tplink_exporter/tplink"
"github.com/prometheus/client_golang/prometheus"
)
//Define a struct for you collector that contains pointers
//to prometheus descriptors for each metric you wish to expose.
//Note you can also include fields of other types if they provide utility
//but we just won't be exposing them as metrics.
type routerCollector struct {
txWANTraffic *prometheus.Desc
rxWANTraffic *prometheus.Desc
LANTraffic *prometheus.Desc
LANLeases *prometheus.Desc
LANPackets *prometheus.Desc
router *tplink.Router
macs macdb.MACDB
mutex sync.Mutex
}
//You must create a constructor for you collector that
//initializes every descriptor and returns a pointer to the collector
func newRouterCollector(router *tplink.Router, macs macdb.MACDB) *routerCollector {
c := routerCollector{}
c.txWANTraffic = prometheus.NewDesc(
"tplink_wan_tx_bytes",
"Total bytes transmitted",
nil, nil,
)
c.rxWANTraffic = prometheus.NewDesc(
"tplink_wan_rx_bytes",
"Total bytes received",
nil, nil,
)
c.LANTraffic = prometheus.NewDesc(
"tplink_lan_traffic_bytes",
"Bytes sent/received per device",
[]string{"name", "ip", "mac"}, nil,
)
c.LANPackets = prometheus.NewDesc(
"tplink_lan_traffic_packets",
"Packets sent/received per device",
[]string{"name", "ip", "mac"}, nil,
)
c.LANLeases = prometheus.NewDesc(
"tplink_lan_lease_seconds",
"Lease seconds left",
[]string{"name", "ip", "mac"}, nil,
)
c.macs = macs
c.router = router
return &c
}
//Each and every collector must implement the Describe function.
//It essentially writes all descriptors to the prometheus desc channel.
func (collector *routerCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- collector.txWANTraffic
ch <- collector.rxWANTraffic
}
func (collector *routerCollector) scrape(ch chan<- prometheus.Metric) error {
err := collector.router.Login()
if err != nil {
return fmt.Errorf("Error logging: %v", err)
}
defer collector.router.Logout()
rx, tx, err := collector.router.GetWANTraffic()
if err != nil {
return fmt.Errorf("Error getting WAN metrics: %v", err)
}
ch <- prometheus.MustNewConstMetric(collector.rxWANTraffic,
prometheus.CounterValue, rx)
ch <- prometheus.MustNewConstMetric(collector.txWANTraffic,
prometheus.CounterValue, tx)
err = collector.router.Update()
if err != nil {
return fmt.Errorf("Error getting LAN metrics: %v", err)
}
for _, client := range collector.router.Clients {
name := collector.macs.Lookup(client.MACAddr)
if len(name) != 0 {
client.Name = name
}
ch <- prometheus.MustNewConstMetric(
collector.LANTraffic,
prometheus.GaugeValue,
client.Bytes,
client.Name, client.IPAddr, client.MACAddr)
ch <- prometheus.MustNewConstMetric(
collector.LANLeases,
prometheus.GaugeValue,
client.DHCPLease,
client.Name, client.IPAddr, client.MACAddr)
ch <- prometheus.MustNewConstMetric(
collector.LANPackets,
prometheus.GaugeValue,
client.Packets,
client.Name, client.IPAddr, client.MACAddr)
}
return nil
}
//Collect implements required collect function for all promehteus collectors
func (collector *routerCollector) Collect(ch chan<- prometheus.Metric) {
collector.mutex.Lock()
defer collector.mutex.Unlock()
err := collector.scrape(ch)
if err != nil {
log.Println("Error scraping data for router\n", err)
err := collector.scrape(ch)
if err != nil {
log.Println("Error scraping data for router\n", err)
}
}
}