dashboard

package
v1.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2026 License: AGPL-3.0 Imports: 15 Imported by: 0

Documentation

Overview

Package dashboard implements the HTTP dashboard server, probe loop, and pulse-sample ring for the Pilot Protocol registry. It is extracted from pkg/registry/server as part of the R5.1 registry decomposition.

Thread safety: all exported Handler methods are safe for concurrent use.

Index

Constants

View Source
const ProbeRetention = 30 * 24 * time.Hour

ProbeRetention is the maximum age of probe downtime intervals kept in memory and persisted to snapshots.

Variables

This section is empty.

Functions

func WriteBucketedStats

func WriteBucketedStats(ring []StatsSample, idxPtr *int, sample StatsSample, bucketSecs int64)

WriteBucketedStats writes a sample into a fixed ring buffer with time-bucket dedup: if the most recently written slot holds a sample in the same bucket, it is overwritten in place instead of advancing the index. This prevents duplicate entries (e.g. two samples on the same UTC day after a restart).

Types

type BeaconStatsProvider

type BeaconStatsProvider interface {
	RelayForwarded() uint64
	RelayDropped() uint64
	RelayNotFound() uint64
}

BeaconStatsProvider exposes relay counters the dashboard surfaces in /api/stats. Implemented by pkg/beacon.Server.

type Callbacks

type Callbacks struct {
	// GetDashboardToken returns the current dashboard token.
	GetDashboardToken func() string
	// GetAdminToken returns the current admin token.
	GetAdminToken func() string
	// BuildStatsPayload assembles the core /api/stats JSON payload (without
	// probe state and maintenance banner, which are owned by Handler).
	// The returned map is JSON-safe; callers must not mutate it.
	BuildStatsPayload func(authenticated bool) map[string]interface{}
	// GetNodes returns a snapshot of registered nodes for /api/nodes.
	GetNodes func() []NodeSnapshot
	// RequestCount returns the current total request count.
	RequestCount func() int64
	// StartTime returns when the server started.
	StartTime func() time.Time
	// NodeCount returns the number of registered nodes.
	NodeCount func() int
	// OnlineCount returns the number of nodes online at or after threshold.
	OnlineCount func(threshold time.Time) int
	// StaleThreshold returns the configured stale-node threshold.
	StaleThreshold func() time.Duration
	// TriggerSnapshot triggers a snapshot save.
	TriggerSnapshot func() error
	// UpdateGauges updates Prometheus gauges before /metrics scrape.
	UpdateGauges func()
	// WriteMetrics writes Prometheus metrics to w.
	WriteMetrics func(w io.Writer)
	// ListenerAddr returns the registry TCP listener address for probeRegistry.
	// Returns "" when no listener is bound.
	ListenerAddr func() string
	// BeaconAddr returns the beacon UDP address for probeBeacon. "" = disabled.
	BeaconAddr func() string
	// ReadyCh returns the channel closed when the server is ready.
	ReadyCh func() <-chan struct{}
	// Done returns the channel closed on server shutdown.
	Done func() <-chan struct{}
	// Save triggers a debounced snapshot after probe state changes.
	Save func()
}

Callbacks bundles the side-effect functions Handler calls on the parent server. All functions must be safe for concurrent use.

type DashboardStats

type DashboardStats struct {
	TotalNodes        int                    `json:"total_nodes"`
	ActiveNodes       int                    `json:"active_nodes"`
	TotalTrustLinks   int                    `json:"-"`
	TotalRequests     int64                  `json:"total_requests"`
	RelayForwarded    uint64                 `json:"relay_forwarded,omitempty"`
	RelayDropped      uint64                 `json:"relay_dropped,omitempty"`
	RelayNotFound     uint64                 `json:"relay_not_found,omitempty"`
	ReqPerDay         int64                  `json:"req_per_day"`
	UptimeSecs        int64                  `json:"uptime_secs"`
	Versions          map[string]int         `json:"versions,omitempty"`
	Networks          []NetworkStats         `json:"networks,omitempty"` // only populated with dashboard token
	Hourly            []StatsSample          `json:"hourly,omitempty"`
	Daily             []StatsSample          `json:"daily,omitempty"`
	RestartEvents     []int64                `json:"restart_events,omitempty"`
	DowntimeIntervals [][2]int64             `json:"downtime_intervals,omitempty"`
	Probes            map[string]*ProbeState `json:"probes,omitempty"`
	ReleaseBanner     *ReleaseBanner         `json:"release_banner,omitempty"`
}

DashboardStats is the public-safe data returned by the dashboard API.

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler owns the dashboard HTTP mux, probe state, pulse ring, and the maintenance banner. It is wired into the parent server via Callbacks.

func NewHandler

func NewHandler(cb Callbacks) *Handler

NewHandler creates a ready-to-use dashboard Handler backed by cb.

func (*Handler) GetProbeStates

func (h *Handler) GetProbeStates() map[string]*ProbeState

GetProbeStates returns a deep-copy snapshot of all probe states.

func (*Handler) GetPulseSamples

func (h *Handler) GetPulseSamples() []PulseSample

GetPulseSamples returns the ordered pulse samples from the ring buffer.

func (*Handler) MaintenanceBanner

func (h *Handler) MaintenanceBanner() string

MaintenanceBanner returns the currently-set maintenance notice (or "").

func (*Handler) ProbeLoop

func (h *Handler) ProbeLoop()

ProbeLoop runs the 4 component probes at a steady cadence. Must be called in a separate goroutine (typically by the parent server).

func (*Handler) PulseLoop

func (h *Handler) PulseLoop()

PulseLoop records one request-count sample per second into the ring. Must be called in a separate goroutine.

func (*Handler) Serve

func (h *Handler) Serve(addr string) error

Serve starts an HTTP server serving the dashboard UI and stats API.

func (*Handler) SetBannerPath

func (h *Handler) SetBannerPath(path string)

SetBannerPath wires a disk-persistence path for the maintenance banner. If the file already exists, its contents become the in-memory banner.

func (*Handler) SetHTTPProbeAddr

func (h *Handler) SetHTTPProbeAddr(addr string)

SetHTTPProbeAddr records the dashboard HTTP listen address so the probe loop knows where to dial for the dashboard + metrics probes.

func (*Handler) SetMaintenanceBanner

func (h *Handler) SetMaintenanceBanner(msg string)

SetMaintenanceBanner sets a free-form notice rendered on the dashboard. Empty string clears it. If a bannerPath has been configured, the new value is atomically written to disk.

func (*Handler) SetProbeStates

func (h *Handler) SetProbeStates(states map[string]*ProbeState)

SetProbeStates replaces the probe state map (used during snapshot restore).

func (*Handler) StatsCollectorLoop

func (h *Handler) StatsCollectorLoop(
	readyCh <-chan struct{},
	done <-chan struct{},
	sampleFn func() StatsSampleResult,
	recordFn func(StatsSampleResult, bool),
)

StatsCollectorLoop runs in the background and samples stats for history charts. Hourly samples are taken every hour; daily samples every 24 hours.

readyCh is closed when the parent server is ready to serve (load complete). done is closed on server shutdown. sampleFn returns a fresh StatsSampleResult under whatever locking the caller requires. recordFn persists the sample into the parent server's ring buffers; it must acquire any required server locks internally.

type NetHistoryRing

type NetHistoryRing struct {
	Samples []NetworkSampleEntry // length == Size; heap-allocated per ring
	Size    int                  // ring capacity (24 for hourly, 30 for daily)
	Idx     int                  // next write index
}

NetHistoryRing is a fixed-size ring buffer for per-network history samples.

func NewNetHistoryRing

func NewNetHistoryRing(size int) *NetHistoryRing

NewNetHistoryRing allocates a new ring of the given capacity.

func (*NetHistoryRing) Read

func (r *NetHistoryRing) Read() []NetworkSampleEntry

Read returns all non-zero entries in chronological order.

func (*NetHistoryRing) Write

func (r *NetHistoryRing) Write(e NetworkSampleEntry)

Write appends a new entry, overwriting the oldest on wraparound.

func (*NetHistoryRing) WriteBucketed

func (r *NetHistoryRing) WriteBucketed(e NetworkSampleEntry, bucketSecs int64)

WriteBucketed overwrites the most recent entry if its timestamp falls in the same time bucket (e.g. 86400s for per-day dedup); otherwise behaves like Write. Guarantees at most one entry per bucket across restarts.

type NetworkSampleEntry

type NetworkSampleEntry struct {
	Timestamp int64  `json:"ts"`
	ID        uint16 `json:"id"`
	Name      string `json:"name"`
	Members   int    `json:"members"`
	Online    int    `json:"online"`
	Requests  int64  `json:"requests"`
}

NetworkSampleEntry holds per-network stats within a time-series sample.

type NetworkStats

type NetworkStats struct {
	ID         uint16               `json:"id"`
	Name       string               `json:"name"`
	Members    int                  `json:"members"`
	Online     int                  `json:"online"`
	Requests   int64                `json:"requests"`
	TrustLinks int                  `json:"-"`
	Hourly     []NetworkSampleEntry `json:"hourly,omitempty"`
	Daily      []NetworkSampleEntry `json:"daily,omitempty"`
}

NetworkStats holds per-network statistics for the authenticated dashboard view.

type NodeSnapshot

type NodeSnapshot struct {
	ID       uint32
	Hostname string
	LastSeen time.Time
}

NodeSnapshot is a minimal node record for the /api/nodes endpoint.

type ProbeState

type ProbeState struct {
	LastSuccess       int64      `json:"last_success,omitempty"`       // millis
	DowntimeIntervals [][2]int64 `json:"downtime_intervals,omitempty"` // pruned to 30d
	CurrentDownStart  int64      `json:"current_down_start,omitempty"` // 0 when up
}

ProbeState holds the health history for a single named probe.

type PulseSample

type PulseSample struct {
	Ts    int64 `json:"ts"`
	Total int64 `json:"total"`
}

PulseSample is one entry in the server-side 1/sec request-count ring.

type ReleaseBanner

type ReleaseBanner struct {
	Version     string `json:"version"`
	PublishedAt int64  `json:"published_at"`
}

ReleaseBanner is the public-safe snapshot of the latest GitHub release. Surfaced on the dashboard so users see why peers may be briefly unreachable while the fleet upgrades.

type StatsSample

type StatsSample struct {
	Timestamp     int64 `json:"ts"`
	TotalNodes    int   `json:"total_nodes"`
	OnlineNodes   int   `json:"online_nodes"`
	TrustLinks    int   `json:"trust_links,omitempty"`
	TotalRequests int64 `json:"total_requests"`
}

StatsSample is a single time-series data point for dashboard history charts.

type StatsSampleResult

type StatsSampleResult struct {
	Global   StatsSample
	Networks map[uint16]NetworkSampleEntry
}

StatsSampleResult holds both global and per-network samples from a single snapshot. It is produced by the server's sampleStats callback and consumed by recordSample.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL