Skip to content

Commit

Permalink
exporter: add tilt and gps metrics (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuasing authored Dec 26, 2024
1 parent 59496cc commit af611b6
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 50 deletions.
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,4 @@ gen:

.PHONY: gen-deps
gen-deps:
# Use @master because latest does not contain proto-out-dir yet
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@master
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
36 changes: 20 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[![Go Reference](https://pkg.go.dev/badge/github.com/joshuasing/starlink_exporter.svg)](https://pkg.go.dev/github.com/joshuasing/starlink_exporter)
[![Go Report Card](https://goreportcard.com/badge/github.com/joshuasing/starlink_exporter)](https://goreportcard.com/report/github.com/joshuasing/starlink_exporter)
[![Go Build Status](https://github.com/joshuasing/starlink_exporter/actions/workflows/go.yml/badge.svg)](https://github.com/joshuasing/starlink_exporter/actions/workflows/go.yml)
[![Starlink Dishy Software Version](https://img.shields.io/badge/Starlink_Dishy_Version-2024.12.17.mr47156.1-blue)](internal/spacex/README.md)
[![MIT License](https://img.shields.io/badge/license-MIT-2155cc)](LICENSE)

A simple Starlink exporter for Prometheus. *Not affiliated with Starlink or SpaceX.*
Expand All @@ -13,30 +14,33 @@ The following metrics are exposed by this exporter:

| Metric name | Description |
|----------------------------------------------------|-------------------------------------------------------------------------------|
| `starlink_exporter_scrapes_total` | Total number of Starlink dish scrapes |
| `starlink_exporter_scrape_duration_seconds` | Time taken to scrape metrics from the Starlink dish |
| `starlink_dish_up` | Whether scraping metrics from the Starlink dish was successful |
| `starlink_dish_info` | Starlink dish software information |
| `starlink_dish_uptime_seconds` | Starlink dish uptime in seconds |
| `starlink_dish_snr_above_noise_floor` | Whether Starlink dish signal-to-noise ratio is above noise floor |
| `starlink_dish_snr_persistently_low` | Whether Starlink dish signal-to-noise ratio is persistently low |
| `starlink_dish_uplink_throughput_bps` | Starlink dish uplink throughput in bits/sec |
| `starlink_dish_downlink_throughput_bps` | Starlink dish downlink throughput in bit/sec |
| `starlink_dish_downlink_throughput_bps_histogram` | Histogram of Starlink dish downlink throughput over last 15 minutes |
| `starlink_dish_uplink_throughput_bps_histogram` | Histogram of Starlink dish uplink throughput in bits/sec over last 15 minutes |
| `starlink_dish_pop_ping_drop_ratio` | Starlink PoP ping drop ratio |
| `starlink_dish_pop_ping_latency_seconds` | Starlink PoP ping latency in seconds |
| `starlink_dish_pop_ping_latency_seconds_histogram` | Histogram of Starlink dish PoP ping latency in seconds over last 15 minutes |
| `starlink_dish_software_update_reboot_ready` | Whether the Starlink dish is ready to reboot to apply a software update |
| `starlink_dish_boresight_azimuth_deg` | Starlink dish boresight azimuth degrees |
| `starlink_dish_boresight_elevation_deg` | Starlink dish boresight elevation degrees |
| `starlink_dish_currently_obstructed` | Whether the Starlink dish is currently obstructed |
| `starlink_dish_desired_boresight_azimuth_deg` | Starlink dish desired boresight azimuth degrees |
| `starlink_dish_desired_boresight_elevation_deg` | Starlink dish desired boresight elevation degrees |
| `starlink_dish_currently_obstructed` | Whether the Starlink dish is currently obstructed |
| `starlink_dish_downlink_throughput_bps_histogram` | Histogram of Starlink dish downlink throughput over last 15 minutes |
| `starlink_dish_downlink_throughput_bps` | Starlink dish downlink throughput in bit/sec |
| `starlink_dish_fraction_obstruction_ratio` | Fraction of Starlink dish that is obstructed |
| `starlink_dish_gps_satellites` | Number of GPS satellites visible to the Starlink dish |
| `starlink_dish_gps_valid` | Whether the Starlink dish GPS is valid |
| `starlink_dish_info` | Starlink dish software information |
| `starlink_dish_last_24h_obstructed_seconds` | Number of seconds the Starlink dish was obstructed in the past 24 hours |
| `starlink_dish_pop_ping_drop_ratio` | Starlink PoP ping drop ratio |
| `starlink_dish_pop_ping_latency_seconds_histogram` | Histogram of Starlink dish PoP ping latency in seconds over last 15 minutes |
| `starlink_dish_pop_ping_latency_seconds` | Starlink PoP ping latency in seconds |
| `starlink_dish_power_input_watts_histogram` | Histogram of Starlink dish power input in watts over last 15 minutes |
| `starlink_dish_power_input_watts` | Current power input for the Starlink dish |
| `starlink_dish_snr_above_noise_floor` | Whether Starlink dish signal-to-noise ratio is above noise floor |
| `starlink_dish_snr_persistently_low` | Whether Starlink dish signal-to-noise ratio is persistently low |
| `starlink_dish_software_update_reboot_ready` | Whether the Starlink dish is ready to reboot to apply a software update |
| `starlink_dish_tilt_angle_deg` | Starlink dish tilt angle degrees |
| `starlink_dish_up` | Whether scraping metrics from the Starlink dish was successful |
| `starlink_dish_uplink_throughput_bps_histogram` | Histogram of Starlink dish uplink throughput in bits/sec over last 15 minutes |
| `starlink_dish_uplink_throughput_bps` | Starlink dish uplink throughput in bits/sec |
| `starlink_dish_uptime_seconds` | Starlink dish uptime in seconds |
| `starlink_exporter_scrape_duration_seconds` | Time taken to scrape metrics from the Starlink dish |
| `starlink_exporter_scrapes_total` | Total number of Starlink dish scrapes |

## Installation

Expand Down
38 changes: 35 additions & 3 deletions internal/exporter/desc.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@

package exporter

import "github.com/prometheus/client_golang/prometheus"
import (
"github.com/prometheus/client_golang/prometheus"
)

const (
namespace = "starlink"
Expand Down Expand Up @@ -162,6 +164,28 @@ var (
Help: "Whether the Starlink dish is ready to reboot to apply a software update",
}

// GPS
dishGPSValid = Desc{
Namespace: namespace,
Subsystem: dishSubsystem,
Name: "gps_valid",
Help: "Whether the Starlink dish GPS is valid",
}
dishGPSSatellites = Desc{
Namespace: namespace,
Subsystem: dishSubsystem,
Name: "gps_satellites",
Help: "Number of GPS satellites visible to the Starlink dish",
}

// Tilt Angle
dishTiltAngleDeg = Desc{
Namespace: namespace,
Subsystem: dishSubsystem,
Name: "tilt_angle_deg",
Help: "Starlink dish tilt angle degrees",
}

// Boresight
dishBoresightAzimuthDeg = Desc{
Namespace: namespace,
Expand Down Expand Up @@ -225,6 +249,9 @@ var Descs = []Desc{
dishPopPingLatencySeconds,
dishPopPingLatencyHistogram,
dishSoftwareUpdateRebootReady,
dishGPSValid,
dishGPSSatellites,
dishTiltAngleDeg,
dishBoresightAzimuthDeg,
dishBoresightElevationDeg,
dishDesiredBoresightAzimuthDeg,
Expand All @@ -243,11 +270,16 @@ type Desc struct {
Help string
Labels []string
ConstLabels prometheus.Labels
desc *prometheus.Desc

fqName string
desc *prometheus.Desc
}

func (d Desc) FQName() string {
return prometheus.BuildFQName(d.Namespace, d.Subsystem, d.Name)
if d.fqName == "" {
d.fqName = prometheus.BuildFQName(d.Namespace, d.Subsystem, d.Name)
}
return d.fqName
}

func (d Desc) Desc() *prometheus.Desc {
Expand Down
61 changes: 32 additions & 29 deletions internal/exporter/scrape.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) bool {
return runScrapers(ch,
e.scrapeDishStatus,
e.scrapeDishHistory,
e.scrapeDishDiagnostics,
)
}

Expand Down Expand Up @@ -142,6 +141,18 @@ func (e *Exporter) scrapeDishStatus(ctx context.Context, ch chan<- prometheus.Me
float64(dishStatus.GetPopPingLatencyMs()/1000),
)

// starlink_dish_gps_valid
ch <- prometheus.MustNewConstMetric(
dishGPSValid.Desc(), prometheus.GaugeValue,
btof(dishStatus.GetGpsStats().GetGpsValid()),
)

// starlink_dish_gps_satellites
ch <- prometheus.MustNewConstMetric(
dishGPSSatellites.Desc(), prometheus.GaugeValue,
float64(dishStatus.GetGpsStats().GetGpsSats()),
)

// starlink_dish_snr_above_noise_floor
ch <- prometheus.MustNewConstMetric(
dishSnrAboveNoiseFloor.Desc(), prometheus.GaugeValue,
Expand Down Expand Up @@ -172,16 +183,34 @@ func (e *Exporter) scrapeDishStatus(ctx context.Context, ch chan<- prometheus.Me
btof(dishStatus.GetSwupdateRebootReady()),
)

// starlink_dish_tilt_angle_deg
ch <- prometheus.MustNewConstMetric(
dishTiltAngleDeg.Desc(), prometheus.GaugeValue,
float64(dishStatus.GetAlignmentStats().GetTiltAngleDeg()),
)

// starlink_dish_boresight_azimuth_deg
ch <- prometheus.MustNewConstMetric(
dishBoresightAzimuthDeg.Desc(), prometheus.GaugeValue,
float64(dishStatus.GetBoresightAzimuthDeg()),
float64(dishStatus.GetAlignmentStats().GetBoresightAzimuthDeg()),
)

// starlink_dish_boresight_elevation_deg
ch <- prometheus.MustNewConstMetric(
dishBoresightElevationDeg.Desc(), prometheus.GaugeValue,
float64(dishStatus.GetBoresightElevationDeg()),
float64(dishStatus.GetAlignmentStats().GetBoresightElevationDeg()),
)

// starlink_dish_desired_boresight_azimuth_deg
ch <- prometheus.MustNewConstMetric(
dishDesiredBoresightAzimuthDeg.Desc(), prometheus.GaugeValue,
float64(dishStatus.GetAlignmentStats().GetDesiredBoresightAzimuthDeg()),
)

// starlink_dish_desired_boresight_elevation_deg
ch <- prometheus.MustNewConstMetric(
dishDesiredBoresightElevationDeg.Desc(), prometheus.GaugeValue,
float64(dishStatus.GetAlignmentStats().GetDesiredBoresightElevationDeg()),
)

// starlink_dish_currently_obstructed
Expand Down Expand Up @@ -274,29 +303,3 @@ func (e *Exporter) scrapeDishHistory(ctx context.Context, ch chan<- prometheus.M

return true
}

func (e *Exporter) scrapeDishDiagnostics(ctx context.Context, ch chan<- prometheus.Metric) bool {
res, err := e.client.Handle(ctx, &device.Request{
Request: new(device.Request_GetDiagnostics),
})
if err != nil {
slog.Error("Failed to scrape dish diagnostics", slog.Any("err", err))
return false
}

diag := res.GetDishGetDiagnostics()

// starlink_dish_desired_boresight_azimuth_deg
ch <- prometheus.MustNewConstMetric(
dishDesiredBoresightAzimuthDeg.Desc(), prometheus.GaugeValue,
float64(diag.GetAlignmentStats().GetDesiredBoresightAzimuthDeg()),
)

// starlink_dish_desired_boresight_elevation_deg
ch <- prometheus.MustNewConstMetric(
dishDesiredBoresightElevationDeg.Desc(), prometheus.GaugeValue,
float64(diag.GetAlignmentStats().GetDesiredBoresightElevationDeg()),
)

return true
}

0 comments on commit af611b6

Please sign in to comment.