tailscale-exporter/pkg/metrics/devices.go

106 lines
3.3 KiB
Go

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"},
)
deviceLastSeen := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "tailscale_devices_last_seen",
Help: "The last time the device was active on the tailnet",
ConstLabels: prometheus.Labels{
"tailnet": client.GetTailnet(),
},
},
[]string{"id", "created", "name"},
)
deviceLastSeenAgo := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "tailscale_devices_last_seen_ago",
Help: "The number of seconds since the device was last active on the tailnet",
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 {
// Reset gauges so we don't leave old devices around
deviceExpiry.Reset()
deviceSecondsRemaining.Reset()
deviceLastSeen.Reset()
deviceLastSeenAgo.Reset()
deviceUpdateAvailable.Reset()
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)
}
secondsAgo := time.Since(device.LastSeen.Time).Seconds()
deviceLastSeen.With(prometheus.Labels{"id": device.ID, "created": device.Created.String(), "name": device.Name}).Set(float64(device.LastSeen.Unix()))
deviceLastSeenAgo.With(prometheus.Labels{"id": device.ID, "created": device.Created.String(), "name": device.Name}).Set(secondsAgo)
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, deviceLastSeen, deviceLastSeenAgo, deviceUpdateAvailable}
}