Help us shape the future of Go! Take the 2026 Go Developer Survey

uptimestats

package
v1.3.97 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2026 License: AGPL-3.0 Imports: 13 Imported by: 0

Documentation

Overview

Package uptimestats pkg/uptimestats/client.go c2-net-discovery integrated uptime endpoints exposed by the service-discovery, transport-discovery, and dmsg-discovery services.

The same endpoint shape (/uptimes with optional ?v=v2&v=v3 and ?visors= filter) lives on all three discoveries, plus a handful of transport-specific endpoints on the transport-discovery. This package consolidates the request/response handling so both the CLI (cmd/skywire-cli/commands/{sd,mdisc,ut,tp}) and future hypervisor RPC / UI code share the same fetcher and types.

Package uptimestats pkg/uptimestats/filter.go c2-net-discovery

Filter / stats helpers shared by the CLI consumers. Kept here rather than in each per-service CLI package so the hypervisor RPC layer can apply the same filter + counting semantics when it eventually exposes this data to the UI.

Package uptimestats pkg/uptimestats/timeline.go c2-net-discovery

The shaded-block timeline glyphs, hoisted out of the CLI.

`skywire cli ut <svc> graph` renders the v3 per-5-minute bitmaps as hourly blocks at five density levels. That rendering lived entirely inside cmd/skywire-cli/cliuptime as unexported helpers, so the second consumer (cmd/skywire-cli/commands/visor/info.go) copy-pasted shadeForCount verbatim with a comment saying pkg-level helpers were not exported. This file is that comment's fix: the glyph mapping and the bar builders are pure functions of the timeline map, so they belong beside the types they read rather than beside one of the printers.

The package doc for cliuptime already anticipated this — "keep this thin ... so the hypervisor UI / RPC layer can eventually render the same data without going through a CLI subprocess". A third consumer (the reward server's statistics panel) is what forced it.

Index

Constants

View Source
const (
	// TimelineSlotsPerHour is the v3 bitmap's resolution: one character
	// per five minutes.
	TimelineSlotsPerHour = 12
	// TimelineHours is how many hours one day's bitmap covers.
	TimelineHours = 24
	// TimelineSlots is the full length of a day's bitmap.
	TimelineSlots = TimelineHours * TimelineSlotsPerHour
	// TimelineOnline is the character the tracker writes for a slot the
	// visor was seen in. Anything else means not seen.
	TimelineOnline = '.'
)

Variables

This section is empty.

Functions

func BitmapToBlocks

func BitmapToBlocks(bitmap string) string

BitmapToBlocks turns one day's bitmap into TimelineHours hourly blocks. A bitmap longer than a full day is truncated and a shorter one is scaled, so a publisher that changes resolution still renders 24 blocks rather than a bar of a different width than every other row.

func CountOnlineSlots

func CountOnlineSlots(timelines map[string]string, from, to time.Time) int

CountOnlineSlots returns how many five-minute slots in [from, to) are marked online across the per-day bitmaps.

func RollingBar

func RollingBar(timelines map[string]string, now time.Time, hoursBack int) string

RollingBar renders the hoursBack hours ending at now as one block per hour, oldest on the left. Crossing a day boundary is handled by CountOnlineSlots, which is why this is not just a concatenation of BitmapToBlocks over whole days.

func ShadeForCount

func ShadeForCount(count int) string

ShadeForCount maps a count of online five-minute slots within one hour to a block glyph. Five levels, so an hour that was half up is visibly different from one that was fully up or fully down — a two-state on/off glyph would render an intermittent visor identically to a solid one.

Types

type Client

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

Client queries a single discovery-service base URL. All fetch helpers accept a context so callers can enforce timeouts; the default HTTP client's timeout is also set from NewClient.

func NewClient

func NewClient(baseURL string, timeout time.Duration) *Client

NewClient returns a Client rooted at baseURL (e.g. "https://sd.skycoin.com"). A zero timeout falls back to 30 s.

func (*Client) NetworkUptime

func (c *Client) NetworkUptime(ctx context.Context) (NetworkUptime, error)

NetworkUptime fetches transport-discovery's /metrics/uptime — network-wide transport uptime aggregate.

func (*Client) TransportUptimeForIDs

func (c *Client) TransportUptimeForIDs(ctx context.Context, ids []uuid.UUID) ([]TransportSummary, error)

TransportUptimeForIDs fetches transport-discovery's /metrics/uptime/{ids} — per-transport uptime for explicit IDs.

func (*Client) TransportUptimeForVisors

func (c *Client) TransportUptimeForVisors(ctx context.Context, pks []cipher.PubKey) ([]TransportSummary, error)

TransportUptimeForVisors fetches transport-discovery's /metrics/uptime/visor/{pks} — transport uptime scoped to the given visor PKs.

func (*Client) TransportUptimes

func (c *Client) TransportUptimes(ctx context.Context, version Version) ([]TransportSummary, error)

TransportUptimes fetches transport-discovery's /uptimes/transports. Returns an error if called against a non-TPD base URL (the path 404s on sd / mdisc). Version selects v1/v2/v3 like VisorUptimes.

func (*Client) VisorUptimes

func (c *Client) VisorUptimes(ctx context.Context, opts VisorUptimesOptions) ([]VisorSummary, error)

VisorUptimes fetches the /uptimes endpoint on the base URL. Works against sd, tpd, and dmsg-discovery unchanged.

type NetworkUptime

type NetworkUptime struct {
	TotalTransports int                      `json:"total_transports"`
	Online          int                      `json:"online"`
	ByType          map[string]TypeBreakdown `json:"by_type,omitempty"`
	Daily           map[string]string        `json:"daily,omitempty"`
}

NetworkUptime is the shape returned by transport-discovery's /metrics/uptime (network-wide aggregate).

Example (live endpoint):

{"total_transports":12815,"online":5443,
 "by_type":{"stcpr":{"total":5735,"online":1135},
            "sudph":{"total":7080,"online":4308}}}

type TransportSummary

type TransportSummary struct {
	ID       uuid.UUID         `json:"id"`
	Online   bool              `json:"on"`
	Type     string            `json:"type,omitempty"`
	EdgeA    string            `json:"edge_a,omitempty"`
	EdgeB    string            `json:"edge_b,omitempty"`
	Daily    map[string]string `json:"daily,omitempty"`
	Timeline map[string]string `json:"timeline,omitempty"`
}

TransportSummary is the per-transport uptime shape returned by transport-discovery's /uptimes/transports endpoint. Edge A/B are hex-encoded visor public keys, Type is the transport type (stcp/stcpr/sudph/dmsg).

type TypeBreakdown

type TypeBreakdown struct {
	Total  int `json:"total"`
	Online int `json:"online"`
}

TypeBreakdown is the nested per-transport-type total/online pair that /metrics/uptime returns under by_type.

type Version

type Version string

Version selects which response shape the endpoint returns.

V1 (default): pk + online only
V2:           adds version + daily uptime percentages
V3:           adds per-minute timeline bitmaps (heavy — use sparingly)
const (
	V1 Version = ""
	V2 Version = "v2"
	V3 Version = "v3"
)

Response-shape versions.

type VersionCount

type VersionCount struct {
	Version string
	Count   int
}

VersionCounts returns a sorted-by-count (desc) slice of (version, count) pairs for the given entries. Useful for the `--stats` / `--list-versions` style CLI output.

func VersionCounts

func VersionCounts(entries []VisorSummary) []VersionCount

VersionCounts tallies the Version field across entries and returns the counts sorted by count desc, then by version asc for stability.

type VisorFilter

type VisorFilter struct {
	OnlineOnly    bool   // drop entries where Online == false
	PKSubstr      string // PK must contain this substring (useful for CLI grep-style matching)
	VersionEquals string // version must equal exactly (after trimming "v" prefix + anything after a space)
	MinVersion    string // version must be >= this semver (same trimming)
}

VisorFilter is a declarative filter applied after fetch. Zero value matches every entry.

type VisorSummary

type VisorSummary struct {
	PK       cipher.PubKey     `json:"pk"`
	Online   bool              `json:"on"`
	Version  string            `json:"version,omitempty"`
	Daily    map[string]string `json:"daily,omitempty"`    // YYYY-MM-DD → "0".."100"
	Timeline map[string]string `json:"timeline,omitempty"` // YYYY-MM-DD → bitmap
}

VisorSummary mirrors the shared JSON shape returned by every discovery service's /uptimes endpoint. Fields beyond PK + Online are populated only when the corresponding Version is requested.

func Filter

func Filter(entries []VisorSummary, f VisorFilter) []VisorSummary

Filter returns a new slice containing only entries that match f. Original slice is untouched.

func MinDailyUptime

func MinDailyUptime(entries []VisorSummary, threshold int) []VisorSummary

MinDailyUptime returns entries whose minimum daily uptime percentage (across all recorded days in Daily) is >= threshold. Entries with no Daily data are excluded. Threshold is 0..100.

type VisorUptimesOptions

type VisorUptimesOptions struct {
	Version Version         // V1 / V2 / V3
	Visors  []cipher.PubKey // filter to these PKs (comma-joined into ?visors=)
}

VisorUptimesOptions tunes /uptimes fetches. Zero value is valid — returns every visor with V1 fields.

Jump to

Keyboard shortcuts

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