Documentation
¶
Overview ¶
Package dashboard renders a real-time, browser-friendly health dashboard from a github.com/larsartmann/go-health Probe. It composes go-health (health checking), github.com/larsartmann/templ-components (UI rendering), and github.com/larsartmann/go-datastar (SSE patch protocol) into a single drop-in handler.
The dashboard lives at /health and uses Datastar SSE for real-time updates. It serves HTML by default but returns JSON when the client sends Accept: application/json. Kubernetes probe endpoints (/healthz, /readyz, /startupz) are wired separately as JSON-only.
Quick Start ¶
probe := health.New(injector, health.WithVersion("1.2.3"))
_ = probe.Start(ctx)
dash := dashboard.New(probe,
dashboard.WithTitle("My Service"),
)
_ = dash.Start(ctx)
defer dash.Shutdown()
mux := http.NewServeMux()
dash.RegisterRoutes(mux)
http.ListenAndServe(":8080", mux)
Browser visits http://localhost:8080/health and sees a live status dashboard that updates in real-time via SSE. Kubelet hits http://localhost:8080/readyz and gets the JSON readiness response.
templ: version: v0.3.1020
Index ¶
- Constants
- Variables
- func View(data viewModel) templ.Component
- type Config
- type Dashboard
- func (d *Dashboard) FaviconHandler() http.HandlerFunc
- func (d *Dashboard) Handler() http.HandlerFunc
- func (d *Dashboard) HealthCheck(_ context.Context) error
- func (d *Dashboard) RegisterRoutes(mux *http.ServeMux)
- func (d *Dashboard) SSEHandler() http.HandlerFunc
- func (d *Dashboard) Shutdown()
- func (d *Dashboard) Start(ctx context.Context) error
- func (d *Dashboard) SubscriberCount() int64
- type Option
- func WithBasePath(prefix string) Option
- func WithCSSPath(path string) Option
- func WithDatastarSrc(src string) Option
- func WithHeartbeatInterval(d time.Duration) Option
- func WithMaxSSEConnections(n int) Option
- func WithNonce(nonce string) Option
- func WithNonceExtractor(fn func(*http.Request) string) Option
- func WithPushInterval(d time.Duration) Option
- func WithPushMode(mode PushMode) Option
- func WithRetryInterval(d time.Duration) Option
- func WithRoutes(routes Routes) Option
- func WithTitle(title string) Option
- type PushMode
- type Routes
Constants ¶
const Version = "0.2.0"
Version is the current package version.
Variables ¶
var ErrPusherNotActive = errors.New("dashboard: SSE pusher is not active")
ErrPusherNotActive is returned by HealthCheck when the SSE pusher has not been started or has been shut down.
Functions ¶
Types ¶
type Config ¶
type Config struct {
Title string
PushInterval time.Duration
PushMode PushMode
Routes Routes
Nonce string
NonceExtractor func(*http.Request) string
CSSPath string
DatastarSrc string
HeartbeatInterval time.Duration
MaxSSEConnections int
RetryInterval time.Duration
}
Config holds construction-only configuration for a Dashboard. It is populated by Option functions and consumed by New.
type Dashboard ¶
type Dashboard struct {
// contains filtered or unexported fields
}
Dashboard renders a browser-friendly health dashboard from a go-health Probe using Datastar SSE for real-time updates.
The dashboard lives at a dedicated HTML route (default /health). It serves HTML by default but returns JSON when the client sends Accept: application/json. Kubernetes probe endpoints (/healthz, /readyz, /startupz) are wired separately as JSON-only.
Dashboard is safe for concurrent use by multiple goroutines.
func New ¶
New creates a Dashboard wired to the given Probe. The Probe provides health data (via CachedResponse) and JSON handlers (via ReadinessHandler, LivenessHandler, StartupHandler).
Default configuration:
- Title: "Health Dashboard"
- PushInterval: probe's RefreshInterval, or 2s if probe is live
- PushMode: PushOnChange
- Routes: DefaultRoutes()
func Register ¶ added in v0.3.0
Register creates a Dashboard wired to the given Probe and registers it in the injector so it participates in container lifecycle cascades.
After registration:
- do.Shutdown(injector) calls Dashboard.Shutdown(), closing the SSE broadcaster and releasing the pusher.
- do.HealthCheck[*Dashboard](injector) calls Dashboard.HealthCheck(), reporting whether the SSE pusher is active.
The returned *Dashboard is the same instance stored in the container. Call Start before serving HTTP traffic and RegisterRoutes to wire routes.
Example:
injector := do.New()
probe := health.New(injector, health.WithCriticalServices("db"))
dash := dashboard.Register(injector, probe, dashboard.WithTitle("API"))
dash.Start(ctx)
dash.RegisterRoutes(mux)
// On shutdown: do.Shutdown(injector) cascades to dash.Shutdown().
func (*Dashboard) FaviconHandler ¶
func (d *Dashboard) FaviconHandler() http.HandlerFunc
FaviconHandler returns an http.HandlerFunc that serves the dashboard favicon as an SVG image. Register it at your favicon route.
func (*Dashboard) Handler ¶
func (d *Dashboard) Handler() http.HandlerFunc
Handler returns an http.HandlerFunc that serves the health dashboard with content negotiation based on the Accept header:
- Accept: application/json → returns the probe's cached health response as JSON. HTTP status is 503 when any check is failing, 200 otherwise.
- Any other Accept value (or none) → renders the full HTML dashboard page.
Register it at your dashboard route (e.g. /health).
func (*Dashboard) HealthCheck ¶ added in v0.3.0
HealthCheck reports whether the dashboard's real-time update mechanism is healthy. Returns an error when the SSE pusher has not been started or has been shut down.
This method satisfies do.HealthcheckerWithContext, enabling the dashboard to participate in container-wide health checks when registered in a samber/do injector.
func (*Dashboard) RegisterRoutes ¶
RegisterRoutes registers all dashboard and probe endpoints on the given mux using the dashboard's configured routes (set via WithRoutes or WithBasePath, defaulting to DefaultRoutes).
This wires up:
- Dashboard route (HTML page with Datastar SSE)
- SSE route (Datastar patch stream)
- Favicon route (SVG favicon)
- Liveness, Readiness, Startup probe endpoints (JSON)
func (*Dashboard) SSEHandler ¶
func (d *Dashboard) SSEHandler() http.HandlerFunc
SSEHandler returns an http.HandlerFunc that upgrades to an SSE connection and streams Datastar patches to the browser.
func (*Dashboard) Shutdown ¶
func (d *Dashboard) Shutdown()
Shutdown stops the SSE pusher and closes all broadcaster connections. Safe to call multiple times.
func (*Dashboard) Start ¶
Start launches the SSE pusher goroutine that broadcasts health updates to connected clients. Call before serving HTTP traffic.
The ctx controls the lifetime of the pusher goroutine. Call Shutdown to stop it cleanly.
func (*Dashboard) SubscriberCount ¶
SubscriberCount returns the number of active SSE connections. Returns 0 when the pusher has not been started.
type Option ¶
type Option func(*Config)
Option configures a Dashboard. Use the With* functions to create options.
func WithBasePath ¶ added in v0.3.0
WithBasePath prefixes all dashboard and probe routes with the given path. Use this when mounting the dashboard under a non-root path — for example WithBasePath("/admin") produces "/admin/health", "/admin/health/sse", etc.
The prefix is applied to whatever routes are currently configured. When combined with WithRoutes, call WithBasePath last so it prefixes the custom routes; calling WithRoutes after WithBasePath replaces the prefixed set.
func WithCSSPath ¶
WithCSSPath sets the URL path to a compiled CSS stylesheet. When set, the dashboard uses a <link> tag instead of the Tailwind Play CDN <script> tag. Use this in production to avoid the runtime overhead of the CDN.
func WithDatastarSrc ¶ added in v0.3.0
WithDatastarSrc sets a self-hosted URL for the Datastar SDK script. When set, the dashboard renders <script src=...> pointing at this URL instead of the default jsdelivr CDN. Use this when the host application's Content-Security-Policy only allows 'self' scripts (e.g. the HTTP server serves a local copy of datastar.js).
func WithHeartbeatInterval ¶
WithHeartbeatInterval sets how often the SSE handler sends a comment-line keepalive to prevent proxy/load-balancer timeout. When zero (the default), the dashboard uses 15s.
func WithMaxSSEConnections ¶
WithMaxSSEConnections limits the number of concurrent SSE clients. When zero (the default), the number of connections is unlimited. Use this to prevent DoS via connection exhaustion.
func WithNonce ¶
WithNonce sets a fixed CSP nonce used in script and style tags. Required when the host application uses a strict Content-Security-Policy but cannot provide per-request nonces (e.g. because the dashboard is constructed once at startup). For stronger security, prefer WithNonceExtractor.
func WithNonceExtractor ¶ added in v0.2.0
WithNonceExtractor provides a function that extracts the CSP nonce from each incoming request. This enables per-request nonces (more secure than a fixed construction-time nonce) when the host application uses middleware such as httputil.Nonce that stores a unique nonce in the request context.
When set, the extractor takes precedence over WithNonce. If the extractor returns an empty string for a given request, the dashboard falls back to the fixed Nonce from WithNonce.
Example wiring with httputil:
dashboard.New(probe, dashboard.WithNonceExtractor(httputil.NonceFromRequest))
func WithPushInterval ¶
WithPushInterval sets the SSE push cadence. When zero (the default), the dashboard uses the probe's configured RefreshInterval, falling back to 2s when the probe is in live mode (interval == 0).
func WithPushMode ¶
WithPushMode selects when the pusher sends updates: only on change (default) or on every tick.
func WithRetryInterval ¶ added in v0.3.0
WithRetryInterval sets the SSE retry field (in milliseconds) that tells the browser how long to wait before reconnecting after a disconnect. When zero (the default), the browser's built-in default (~3s) is used.
A shorter interval means faster recovery from transient network blips; a longer interval reduces server load when many clients reconnect at once. Negative values are treated as zero.
func WithRoutes ¶
WithRoutes overrides the default URL paths for dashboard and probe endpoints.
type PushMode ¶
type PushMode string
PushMode controls when the SSE pusher sends updates to connected clients.
const ( // PushOnChange broadcasts only when the overall status or any individual // check result changes (default). Minimises SSE traffic for NOC monitors // that stay connected for long periods. PushOnChange PushMode = "on-change" // PushAlways broadcasts on every tick, regardless of whether anything // changed. Use this when you want continuous confirmation that the // pusher is alive. PushAlways PushMode = "always" )
type Routes ¶
type Routes struct {
Dashboard string // HTML dashboard page (default: /health)
SSE string // SSE push endpoint for real-time updates (default: /health/sse)
Favicon string // SVG favicon endpoint (default: /favicon.svg)
Liveness string // Kubernetes liveness probe — JSON (default: /healthz)
Readiness string // Kubernetes readiness probe — JSON (default: /readyz)
Startup string // Kubernetes startup probe — JSON (default: /startupz)
}
Routes configures the URL paths for Dashboard.RegisterRoutes.
func DefaultRoutes ¶
func DefaultRoutes() Routes
DefaultRoutes returns conventional paths for the dashboard and Kubernetes health probes. The HTML dashboard lives at /health; kubelet endpoints use the standard /healthz, /readyz, /startupz paths.