2023-07-29 20:48:11 +00:00
|
|
|
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 {
|
2023-07-30 12:29:02 +00:00
|
|
|
// Reset gauges so we don't leave old devices around
|
|
|
|
deviceExpiry.Reset()
|
|
|
|
deviceSecondsRemaining.Reset()
|
|
|
|
deviceUpdateAvailable.Reset()
|
|
|
|
|
2023-07-29 20:48:11 +00:00
|
|
|
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}
|
|
|
|
}
|