72
pkg/metrics/devices.go
Normal file
72
pkg/metrics/devices.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"tailscale-exporter/pkg/tailscale"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func collectDevices(client *tailscale.Client) []prometheus.Collector {
|
||||
deviceExpiry := prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "tailscale_devices_expiry_time",
|
||||
Help: "The expiry time of devices authentication",
|
||||
ConstLabels: prometheus.Labels{
|
||||
"tailnet": client.GetTailnet(),
|
||||
},
|
||||
},
|
||||
[]string{"id", "created", "name"},
|
||||
)
|
||||
|
||||
deviceSecondsRemaining := prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "tailscale_devices_expiry_seconds_remaining",
|
||||
Help: "The number of seconds remaining until a device expires",
|
||||
ConstLabels: prometheus.Labels{
|
||||
"tailnet": client.GetTailnet(),
|
||||
},
|
||||
},
|
||||
[]string{"id", "created", "name"},
|
||||
)
|
||||
|
||||
deviceUpdateAvailable := prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "tailscale_devices_update_available",
|
||||
Help: "If the device can be updated (1) or is running the latest version of Tailscale (0)",
|
||||
ConstLabels: prometheus.Labels{
|
||||
"tailnet": client.GetTailnet(),
|
||||
},
|
||||
},
|
||||
[]string{"id", "created", "name", "version"},
|
||||
)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
devices, err := client.GetDevices()
|
||||
if err != nil {
|
||||
fmt.Println("Failed to get devices: ", err)
|
||||
} else {
|
||||
for _, device := range devices {
|
||||
if !device.KeyExpiryDisabled {
|
||||
remainingSeconds := time.Until(device.Expires.Time).Seconds()
|
||||
|
||||
deviceExpiry.With(prometheus.Labels{"id": device.ID, "created": device.Created.String(), "name": device.Name}).Set(float64(device.Expires.Unix()))
|
||||
deviceSecondsRemaining.With(prometheus.Labels{"id": device.ID, "created": device.Created.String(), "name": device.Name}).Set(remainingSeconds)
|
||||
}
|
||||
|
||||
updateAvailable := 0.0
|
||||
if device.UpdateAvailable {
|
||||
updateAvailable = 1.0
|
||||
}
|
||||
deviceUpdateAvailable.With(prometheus.Labels{"id": device.ID, "created": device.Created.String(), "name": device.Name, "version": device.ClientVersion}).Set(updateAvailable)
|
||||
}
|
||||
}
|
||||
|
||||
time.Sleep(60 * time.Second)
|
||||
}
|
||||
}()
|
||||
|
||||
return []prometheus.Collector{deviceExpiry, deviceSecondsRemaining, deviceUpdateAvailable}
|
||||
}
|
56
pkg/metrics/keys.go
Normal file
56
pkg/metrics/keys.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"tailscale-exporter/pkg/tailscale"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func collectKeys(client *tailscale.Client) []prometheus.Collector {
|
||||
keyExpiry := prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "tailscale_keys_expiry_time",
|
||||
Help: "The expiry time of auth keys",
|
||||
ConstLabels: prometheus.Labels{
|
||||
"tailnet": client.GetTailnet(),
|
||||
},
|
||||
},
|
||||
[]string{"id", "created", "description", "type"},
|
||||
)
|
||||
|
||||
keySecondsRemaining := prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "tailscale_keys_expiry_seconds_remaining",
|
||||
Help: "The number of seconds remaining until a key expires",
|
||||
ConstLabels: prometheus.Labels{
|
||||
"tailnet": client.GetTailnet(),
|
||||
},
|
||||
},
|
||||
[]string{"id", "created", "description", "type"},
|
||||
)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
keys, err := client.GetKeys()
|
||||
if err != nil {
|
||||
fmt.Println("Failed to get keys: ", err)
|
||||
} else {
|
||||
for _, key := range keys {
|
||||
remainingSeconds := time.Until(key.Expires).Seconds()
|
||||
keyType := "auth_key"
|
||||
if key.Capabilities == nil {
|
||||
keyType = "api_access_token"
|
||||
}
|
||||
keyExpiry.With(prometheus.Labels{"id": key.ID, "created": key.Created.String(), "description": key.Description, "type": keyType}).Set(float64(key.Expires.Unix()))
|
||||
keySecondsRemaining.With(prometheus.Labels{"id": key.ID, "created": key.Created.String(), "description": key.Description, "type": keyType}).Set(remainingSeconds)
|
||||
}
|
||||
}
|
||||
|
||||
time.Sleep(60 * time.Second)
|
||||
}
|
||||
}()
|
||||
|
||||
return []prometheus.Collector{keyExpiry, keySecondsRemaining}
|
||||
}
|
19
pkg/metrics/metrics.go
Normal file
19
pkg/metrics/metrics.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"tailscale-exporter/pkg/tailscale"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||
)
|
||||
|
||||
var defaultCollectors = []prometheus.Collector{
|
||||
collectors.NewGoCollector(),
|
||||
collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),
|
||||
}
|
||||
|
||||
func Collect(client *tailscale.Client, reg *prometheus.Registry) {
|
||||
reg.MustRegister(defaultCollectors...)
|
||||
reg.MustRegister(collectKeys(client)...)
|
||||
reg.MustRegister(collectDevices(client)...)
|
||||
}
|
Reference in New Issue
Block a user