statuspage

package
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package statuspage builds the opt-in public status page: component probing, 90-day uptime bars, operator-authored incidents and the whitelisted public view. Nothing beyond View is ever published.

Index

Constants

View Source
const (
	PagePath    = "/public/status"
	SummaryPath = "/public/status.json"
	FeedPath    = "/public/status.rss"
)

FeedPath and SummaryPath are the public asset paths, relative to the page.

View Source
const (
	DefaultSampleInterval = time.Minute
	DefaultCacheTTL       = 30 * time.Second
	DefaultCheckTimeout   = 8 * time.Second
)

Defaults for Config, overridable via environment in cmd/levelrail.

View Source
const (
	Operational = "operational"
	Degraded    = "degraded"
	Outage      = "outage"
	Maintenance = "maintenance"
	Unknown     = "unknown"
	NoData      = "nodata"
)

Component and overall statuses.

View Source
const (
	KindApp    = "app"
	KindDomain = "domain"
	KindCheck  = "check"
)

Component kinds.

View Source
const (
	IncidentKind    = "incident"
	MaintenanceKind = "maintenance"

	StatusInvestigating = "investigating"
	StatusIdentified    = "identified"
	StatusMonitoring    = "monitoring"
	StatusResolved      = "resolved"
	StatusScheduled     = "scheduled"
	StatusInProgress    = "in_progress"
	StatusCompleted     = "completed"

	ImpactNone     = "none"
	ImpactMinor    = "minor"
	ImpactMajor    = "major"
	ImpactCritical = "critical"
)

Incident kinds, statuses and impacts.

View Source
const UptimeDays = 90

UptimeDays is the number of daily bars on the page.

Variables

This section is empty.

Functions

func OverallStatus

func OverallStatus(statuses []string) string

OverallStatus folds component statuses into one headline status.

func RenderHTML

func RenderHTML(v View) ([]byte, error)

RenderHTML renders the public page.

func RenderMarkdownLite

func RenderMarkdownLite(src string) template.HTML

RenderMarkdownLite converts operator text to safe HTML. All input is escaped first; only paragraphs, line breaks, "- " lists, **bold**, `code` and http(s) links are then re-introduced.

func RenderRSS

func RenderRSS(v View, baseURL string) ([]byte, error)

RenderRSS renders incidents and maintenance as an RSS 2.0 feed with plain-text descriptions. baseURL is the page's own origin, e.g. "https://status.example.com".

func StatusText

func StatusText(s string) string

StatusText is the human headline for an overall status.

Types

type AppSource

type AppSource interface {
	AppStatus(ctx context.Context, name string) (string, error)
}

AppSource reports an app's current status as one of the status constants.

type ComponentView

type ComponentView struct {
	Name     string    `json:"name"`
	Status   string    `json:"status"`
	Uptime90 *float64  `json:"uptime_90d"`
	Days     []DayView `json:"days"`
}

ComponentView is one component as the public sees it.

type Config

type Config struct {
	SampleInterval time.Duration
	CacheTTL       time.Duration
	CheckTimeout   time.Duration
	Parallelism    int
}

Config tunes sampling and caching; zero values take the defaults.

type DayView

type DayView struct {
	Date   string   `json:"date"`
	Status string   `json:"status"`
	Uptime *float64 `json:"uptime,omitempty"`
}

DayView is one uptime bar.

type DomainSource

type DomainSource interface {
	CheckDomainStatus(ctx context.Context, domain string) (string, error)
}

DomainSource is the existing DNS domain check.

type IncidentView

type IncidentView struct {
	ID         string       `json:"id"`
	Title      string       `json:"title"`
	Status     string       `json:"status"`
	Impact     string       `json:"impact"`
	StartsAt   time.Time    `json:"starts_at"`
	EndsAt     *time.Time   `json:"ends_at,omitempty"`
	ResolvedAt *time.Time   `json:"resolved_at,omitempty"`
	Components []string     `json:"components,omitempty"`
	Updates    []UpdateView `json:"updates"`
}

IncidentView is an incident or maintenance announcement.

type Service

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

Service samples component health and builds the public View.

func New

func New(st Store, apps AppSource, domains DomainSource, cfg Config, logger *slog.Logger) *Service

New builds a Service. apps and domains may be nil, in which case components of that kind report unknown.

func (*Service) Enabled

func (s *Service) Enabled(ctx context.Context) (bool, error)

Enabled reports whether the public page is switched on.

func (*Service) Invalidate

func (s *Service) Invalidate()

Invalidate drops the cached view so the next read reflects a management change.

func (*Service) PreviewView

func (s *Service) PreviewView(ctx context.Context) (View, error)

PreviewView builds an uncached view regardless of the enabled flag, for the management UI.

func (*Service) Run

func (s *Service) Run(ctx context.Context) error

Run samples every component on the configured interval until ctx ends.

func (*Service) Sample

func (s *Service) Sample(ctx context.Context) error

Sample probes every component once and records the result. It does nothing while the page is disabled.

func (*Service) View

func (s *Service) View(ctx context.Context) (View, error)

View returns the public view, cached for the configured TTL.

type Store

type Store interface {
	GetStatusPageSettings(ctx context.Context) (store.StatusPageSettings, error)
	ListStatusComponents(ctx context.Context) ([]store.StatusComponent, error)
	AddStatusSamples(ctx context.Context, componentID, day string, ok, degraded, down int) error
	ListStatusDaily(ctx context.Context, sinceDay string) ([]store.StatusDaily, error)
	PruneStatusDaily(ctx context.Context, beforeDay string) error
	ListStatusIncidents(ctx context.Context, limit int) ([]store.StatusIncident, error)
	ListStatusIncidentUpdates(ctx context.Context) ([]store.StatusIncidentUpdate, error)
}

Store is what Service reads and writes. *store.DB satisfies it.

type UpdateView

type UpdateView struct {
	Status string    `json:"status"`
	Body   string    `json:"body"`
	At     time.Time `json:"at"`
}

UpdateView is one timeline entry.

type View

type View struct {
	Title       string          `json:"title"`
	Description string          `json:"description,omitempty"`
	Status      string          `json:"status"`
	StatusText  string          `json:"status_text"`
	GeneratedAt time.Time       `json:"generated_at"`
	Components  []ComponentView `json:"components"`
	Incidents   []IncidentView  `json:"incidents"`
	Maintenance []IncidentView  `json:"maintenance"`
}

View is the entire public payload. Every field is deliberate: a privacy test fails when one is added without updating its whitelist.

Jump to

Keyboard shortcuts

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