Add new experimental metrics (#4)
This commit is contained in:
parent
4bac289600
commit
136f95a9b7
12 changed files with 592 additions and 18 deletions
9
internal/poller/common.go
Normal file
9
internal/poller/common.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package poller
|
||||
|
||||
import "math"
|
||||
|
||||
const maxMbits = 2150
|
||||
|
||||
func sanitizeMbits(mbits float64) float64 {
|
||||
return math.Min(mbits, maxMbits)
|
||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/Tomy2e/livebox-api-client"
|
||||
"github.com/Tomy2e/livebox-api-client/api/request"
|
||||
"github.com/Tomy2e/livebox-exporter/pkg/bitrate"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
|
@ -44,10 +45,6 @@ func (im *InterfaceMbits) Collectors() []prometheus.Collector {
|
|||
return []prometheus.Collector{im.txMbits, im.rxMbits}
|
||||
}
|
||||
|
||||
func bitsPer30SecsToMbitsPerSec(v int) float64 {
|
||||
return float64(v) / 30000000
|
||||
}
|
||||
|
||||
// Poll polls the current bandwidth usage.
|
||||
func (im *InterfaceMbits) Poll(ctx context.Context) error {
|
||||
var counters struct {
|
||||
|
@ -87,10 +84,10 @@ func (im *InterfaceMbits) Poll(ctx context.Context) error {
|
|||
|
||||
im.rxMbits.
|
||||
With(prometheus.Labels{"interface": iface}).
|
||||
Set(bitsPer30SecsToMbitsPerSec(rxCounter))
|
||||
Set(bitrate.BitsPer30SecsToMbits(rxCounter))
|
||||
im.txMbits.
|
||||
With(prometheus.Labels{"interface": iface}).
|
||||
Set(bitsPer30SecsToMbitsPerSec(txCounter))
|
||||
Set(bitrate.BitsPer30SecsToMbits(txCounter))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
110
internal/poller/interface_homelan.go
Normal file
110
internal/poller/interface_homelan.go
Normal file
|
@ -0,0 +1,110 @@
|
|||
package poller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Tomy2e/livebox-api-client"
|
||||
"github.com/Tomy2e/livebox-api-client/api/request"
|
||||
"github.com/Tomy2e/livebox-exporter/pkg/bitrate"
|
||||
exporterLivebox "github.com/Tomy2e/livebox-exporter/pkg/livebox"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// InterfaceHomeLanMbitsMinDelay set the minimum delay between each poll.
|
||||
// Polling must only be done once every 30 seconds as Livebox updates data
|
||||
// only every 30 seconds.
|
||||
const InterfaceHomeLanMbitsMinDelay = 30 * time.Second
|
||||
|
||||
var _ Poller = &InterfaceHomeLanMbits{}
|
||||
|
||||
// InterfaceHomeLanMbits is an experimental poller to get the current bandwidth
|
||||
// usage on the Livebox interfaces.
|
||||
type InterfaceHomeLanMbits struct {
|
||||
client livebox.Client
|
||||
interfaces []*exporterLivebox.Interface
|
||||
bitrate *bitrate.Bitrate
|
||||
txMbits, rxMbits *prometheus.GaugeVec
|
||||
}
|
||||
|
||||
// NewInterfaceHomeLanMbits returns a new InterfaceMbits poller.
|
||||
func NewInterfaceHomeLanMbits(client livebox.Client, interfaces []*exporterLivebox.Interface) *InterfaceHomeLanMbits {
|
||||
return &InterfaceHomeLanMbits{
|
||||
client: client,
|
||||
interfaces: interfaces,
|
||||
bitrate: bitrate.New(InterfaceHomeLanMbitsMinDelay),
|
||||
txMbits: prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "livebox_interface_homelan_tx_mbits",
|
||||
Help: "Transmitted Mbits per second.",
|
||||
}, []string{
|
||||
// Name of the interface.
|
||||
"interface",
|
||||
}),
|
||||
rxMbits: prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "livebox_interface_homelan_rx_mbits",
|
||||
Help: "Received Mbits per second.",
|
||||
}, []string{
|
||||
// Name of the interface.
|
||||
"interface",
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
// Collectors returns all metrics.
|
||||
func (im *InterfaceHomeLanMbits) Collectors() []prometheus.Collector {
|
||||
return []prometheus.Collector{
|
||||
im.txMbits,
|
||||
im.rxMbits,
|
||||
}
|
||||
}
|
||||
|
||||
// Poll polls the current bandwidth usage.
|
||||
func (im *InterfaceHomeLanMbits) Poll(ctx context.Context) error {
|
||||
for _, itf := range im.interfaces {
|
||||
// Enforce InterfaceHomeLanMbitsMinDelay.
|
||||
if !im.bitrate.ShouldMeasure(itf.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
var stats struct {
|
||||
Status struct {
|
||||
BytesReceived uint64 `json:"BytesReceived"`
|
||||
BytesSent uint64 `json:"BytesSent"`
|
||||
} `json:"status"`
|
||||
}
|
||||
|
||||
if err := im.client.Request(ctx, request.New(
|
||||
fmt.Sprintf("HomeLan.Interface.%s.Stats", itf.Name),
|
||||
"get",
|
||||
nil,
|
||||
), &stats); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
counters := &bitrate.Counters{
|
||||
Tx: stats.Status.BytesSent,
|
||||
Rx: stats.Status.BytesReceived,
|
||||
}
|
||||
|
||||
if !itf.IsWAN() {
|
||||
counters.Swap()
|
||||
}
|
||||
|
||||
bitrates := im.bitrate.Measure(itf.Name, counters)
|
||||
|
||||
if bitrates.Rx != nil && !bitrates.Rx.Reset {
|
||||
im.rxMbits.
|
||||
With(prometheus.Labels{"interface": itf.Name}).
|
||||
Set(sanitizeMbits(bitrates.Rx.Value))
|
||||
}
|
||||
|
||||
if bitrates.Tx != nil && !bitrates.Tx.Reset {
|
||||
im.txMbits.
|
||||
With(prometheus.Labels{"interface": itf.Name}).
|
||||
Set(sanitizeMbits(bitrates.Tx.Value))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
99
internal/poller/interface_netdev.go
Normal file
99
internal/poller/interface_netdev.go
Normal file
|
@ -0,0 +1,99 @@
|
|||
package poller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Tomy2e/livebox-api-client"
|
||||
"github.com/Tomy2e/livebox-api-client/api/request"
|
||||
"github.com/Tomy2e/livebox-exporter/pkg/bitrate"
|
||||
exporterLivebox "github.com/Tomy2e/livebox-exporter/pkg/livebox"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
var _ Poller = &InterfaceNetDevMbits{}
|
||||
|
||||
// InterfaceNetDevMbits is an experimental poller to get the current bandwidth
|
||||
// usage on the Livebox interfaces.
|
||||
type InterfaceNetDevMbits struct {
|
||||
client livebox.Client
|
||||
interfaces []*exporterLivebox.Interface
|
||||
bitrate *bitrate.Bitrate
|
||||
txMbits, rxMbits *prometheus.GaugeVec
|
||||
}
|
||||
|
||||
// NewInterfaceNetDevMbits returns a new InterfaceNetDevMbits poller.
|
||||
func NewInterfaceNetDevMbits(client livebox.Client, interfaces []*exporterLivebox.Interface) *InterfaceNetDevMbits {
|
||||
return &InterfaceNetDevMbits{
|
||||
client: client,
|
||||
interfaces: interfaces,
|
||||
bitrate: bitrate.New(0),
|
||||
txMbits: prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "livebox_interface_netdev_tx_mbits",
|
||||
Help: "Transmitted Mbits per second.",
|
||||
}, []string{
|
||||
// Name of the interface.
|
||||
"interface",
|
||||
}),
|
||||
rxMbits: prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "livebox_interface_netdev_rx_mbits",
|
||||
Help: "Received Mbits per second.",
|
||||
}, []string{
|
||||
// Name of the interface.
|
||||
"interface",
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
// Collectors returns all metrics.
|
||||
func (im *InterfaceNetDevMbits) Collectors() []prometheus.Collector {
|
||||
return []prometheus.Collector{
|
||||
im.txMbits,
|
||||
im.rxMbits,
|
||||
}
|
||||
}
|
||||
|
||||
// Poll polls the current bandwidth usage.
|
||||
func (im *InterfaceNetDevMbits) Poll(ctx context.Context) error {
|
||||
for _, itf := range im.interfaces {
|
||||
var stats struct {
|
||||
Status struct {
|
||||
RxBytes uint64 `json:"RxBytes"`
|
||||
TxBytes uint64 `json:"TxBytes"`
|
||||
} `json:"status"`
|
||||
}
|
||||
|
||||
if err := im.client.Request(ctx, request.New(
|
||||
fmt.Sprintf("NeMo.Intf.%s", itf.Name),
|
||||
"getNetDevStats",
|
||||
nil,
|
||||
), &stats); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
counters := &bitrate.Counters{
|
||||
Tx: stats.Status.TxBytes,
|
||||
Rx: stats.Status.RxBytes,
|
||||
}
|
||||
|
||||
if !itf.IsWAN() {
|
||||
counters.Swap()
|
||||
}
|
||||
|
||||
bitrates := im.bitrate.Measure(itf.Name, counters)
|
||||
|
||||
if bitrates.Rx != nil && !bitrates.Rx.Reset {
|
||||
im.rxMbits.
|
||||
With(prometheus.Labels{"interface": itf.Name}).
|
||||
Set(sanitizeMbits(bitrates.Rx.Value))
|
||||
}
|
||||
|
||||
if bitrates.Tx != nil && !bitrates.Tx.Reset {
|
||||
im.txMbits.
|
||||
With(prometheus.Labels{"interface": itf.Name}).
|
||||
Set(sanitizeMbits(bitrates.Tx.Value))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
81
internal/poller/wan.go
Normal file
81
internal/poller/wan.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package poller
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Tomy2e/livebox-api-client"
|
||||
"github.com/Tomy2e/livebox-api-client/api/request"
|
||||
"github.com/Tomy2e/livebox-exporter/pkg/bitrate"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
var _ Poller = &WANMbits{}
|
||||
|
||||
// WANMbits is an experimental poller to get the current bandwidth usage on the
|
||||
// WAN interface of the Livebox.
|
||||
type WANMbits struct {
|
||||
client livebox.Client
|
||||
bitrate *bitrate.Bitrate
|
||||
txMbits, rxMbits prometheus.Gauge
|
||||
}
|
||||
|
||||
// NewWANMbits returns a new WANMbits poller.
|
||||
func NewWANMbits(client livebox.Client) *WANMbits {
|
||||
return &WANMbits{
|
||||
client: client,
|
||||
bitrate: bitrate.New(InterfaceHomeLanMbitsMinDelay),
|
||||
txMbits: prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "livebox_wan_tx_mbits",
|
||||
Help: "Transmitted Mbits per second on the WAN interface.",
|
||||
}),
|
||||
rxMbits: prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "livebox_wan_rx_mbits",
|
||||
Help: "Received Mbits per second on the WAN interface.",
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
// Collectors returns all metrics.
|
||||
func (im *WANMbits) Collectors() []prometheus.Collector {
|
||||
return []prometheus.Collector{
|
||||
im.txMbits,
|
||||
im.rxMbits,
|
||||
}
|
||||
}
|
||||
|
||||
// Poll polls the current bandwidth usage on the WAN interface.
|
||||
func (im *WANMbits) Poll(ctx context.Context) error {
|
||||
var stats struct {
|
||||
Status struct {
|
||||
BytesReceived uint64 `json:"BytesReceived"`
|
||||
BytesSent uint64 `json:"BytesSent"`
|
||||
} `json:"status"`
|
||||
}
|
||||
|
||||
if err := im.client.Request(
|
||||
ctx,
|
||||
request.New("HomeLan", "getWANCounters", nil),
|
||||
&stats,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
counters := &bitrate.Counters{
|
||||
Tx: stats.Status.BytesSent,
|
||||
Rx: stats.Status.BytesReceived,
|
||||
}
|
||||
|
||||
counters.Swap()
|
||||
|
||||
bitrates := im.bitrate.Measure("WAN", counters)
|
||||
|
||||
if bitrates.Rx != nil && !bitrates.Rx.Reset {
|
||||
im.rxMbits.Set(sanitizeMbits(bitrates.Rx.Value))
|
||||
}
|
||||
|
||||
if bitrates.Tx != nil && !bitrates.Tx.Reset {
|
||||
im.txMbits.Set(sanitizeMbits(bitrates.Tx.Value))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue