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

logserver

package
v1.3.102 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2026 License: AGPL-3.0 Imports: 38 Imported by: 0

Documentation

Overview

Package logserver pkg/visor/logserver/api.go c3-vis-core

Package logserver pkg/visor/logserver/loglevel.go c3-vis-core

Package logserver pkg/visor/logserver/reach.go c3-vis-core

Package logserver pkg/visor/logserver/stats.go c3-vis-core /stats/* endpoints that expose the visor's local telemetry store.

These routes are mounted under the existing authRoute group, so the survey whitelist gates them. The whitelist here is a DoS bound on arbitrary historical-range queries — the same data flows openly on the visor's CXO publisher feed (added in a follow-up commit), so these endpoints are not the confidentiality boundary.

Bitmaps are rendered to 288-char ASCII at the HTTP boundary ('.' = set, ' ' = unset), matching the format the Transport Discovery already uses for its v3 timeline endpoint so dashboards can consume either source unchanged.

Package logserver pkg/visor/logserver/transports.go c3-vis-core

Package logserver pkg/visor/logserver/uptime.go c3-vis-core pkg/serviceuptime HTTP handlers. Wires /uptime/* onto the visor's existing logserver router so a CLI client can render the visor's session history without going through the unix-socket RPC.

Package logserver pkg/visor/logserver/visorlog_filter.go c3-vis-core filtering for the /visor.log endpoint.

/visor.log is logrus-formatted text on disk; over dmsg/skynet the wire is often the slowest hop, so filtering at the source — even at the cost of a regex per line — typically beats shipping the whole file to a client that's only going to grep it. The endpoint stays compatible when no query params are set (caller still receives the raw file via http.ServeFile).

Package logserver pkg/visor/logserver/visorlog_html.go c3-vis-core HTML rendering for the /skywire.log (and /visor.log alias) endpoint.

The on-disk log is logrus-formatted plain text (DisableColors:true), e.g.

[2026-06-18T14:54:52-05:00] DEBUG [tp:02af…]: Serving. remote_pk=… tp_id=…

i.e. `[<timestamp>] LEVEL [module]: message key=val…`. We parse the line into its elements and wrap each (HTML-escaped) part in its own colored <span> so the page mirrors logrus's console TextFormatter rather than flattening to one uniform color:

timestamp   → dim gray            message → bright/light (the focus)
key=         → dimmed             value   → default
LEVEL + [module] colored by level:
  TRACE → gray   DEBUG → blue/gray   INFO → green   WARN → yellow
  ERROR → red    FATAL/PANIC → bold bright-red

Everything is inline CSS/HTML — no external assets, no JS, dependency-free. All log content is HTML-escaped before being written, so a log line that happens to contain markup can't inject anything into the page.

A plaintext escape hatch (?raw=1) bypasses the HTML wrapper entirely so log-scraping tooling keeps receiving the file verbatim.

Package logserver pkg/visor/logserver/wasm.go c3-vis-core

Index

Constants

View Source
const AnyVhost = "*"

AnyVhost is the name of the vhost that serves every name no other has.

View Source
const DefaultTempLogLevelTTL = 15 * time.Minute

DefaultTempLogLevelTTL is how long POST /debug/loglevel holds a level when the request names no ttl.

Variables

View Source
var ErrNotReachable = errors.New("this visor does not advertise how to reach it")

ErrNotReachable is what a ReachCardProvider returns while the visor is not advertising itself, the same choice that keeps it out of the address resolver.

Functions

func OverTransport added in v1.3.100

func OverTransport(ctx context.Context) bool

OverTransport reports whether the request arrived over a skywire transport.

func WithOverTransport added in v1.3.100

func WithOverTransport(ctx context.Context) context.Context

WithOverTransport marks a request context as having arrived over a skywire transport rather than a dmsg server.

Types

type API

type API struct {
	http.Handler
	// contains filtered or unexported fields
}

API register all the API endpoints. It implements a net/http.Handler.

func New

func New(log *logging.Logger, localPath, _ string, whitelistedPKs []cipher.PubKey, survey *visorconfig.Survey, printLog bool) *API

New creates a new API.

The trailing unused string parameter is legacy: historical bandwidth is now served from the bbolt stats store via /stats/transports/history, and the on-disk CSV transport-log store (with its /transport_logs/:file route) has been removed.

func (*API) OwnPages

func (api *API) OwnPages() http.Handler

OwnPages serves the visor's own pages, with its landing page at /, for a port or a name other than its bare one.

func (*API) SetCXOFeedsLister

func (api *API) SetCXOFeedsLister(lister CXOFeedsLister)

func (*API) SetForwardedPortLister

func (api *API) SetForwardedPortLister(lister ForwardedPortLister)

SetForwardedPortLister sets the forwarded port provider for the landing page.

func (*API) SetHealthStatsProvider

func (api *API) SetHealthStatsProvider(provider HealthStatsProvider)

SetHealthStatsProvider sets the health stats provider after initialization.

func (*API) SetHomePage

func (api *API) SetHomePage(render func(suffix string, ownUser bool) []byte)

SetHomePage installs the renderer for the mesh directory at home.skynet.

func (*API) SetIdentity

func (api *API) SetIdentity(publicKey, dmsgAddress string)

SetIdentity records the visor's public key (hex) and dmsg listening address (`<pk>:<dmsg-port>`). The two are surfaced on different pages to avoid redundancy: the landing page names itself by public key, while the /health response carries the dmsg address (whose host part is the same key). Called from visor init.

func (*API) SetLogLevelController added in v1.3.100

func (api *API) SetLogLevelController(c LogLevelController)

SetLogLevelController enables /debug/loglevel. Until it is called the routes answer 503.

func (*API) SetPtyHandler

func (api *API) SetPtyHandler(h http.Handler, whitelist pty.Whitelist)

SetCXOFeedsLister sets the CXO feed catalog provider. Called from visor init after the user-feed registry is wired up. SetPtyHandler installs the dmsgpty UI handler under /pty, gated by the supplied whitelist. The whitelist is expected to mirror the dmsgpty Host's whitelist (configured PKs + hypervisor PKs + the visor's own PK), so the same set of peers that can connect directly to dmsgpty over dmsg can also reach the web terminal. Pass a nil/empty whitelist or nil handler to disable; the route stays registered and returns 404/403, which is the correct signal to a probing client.

func (*API) SetReachCardProvider added in v1.3.100

func (api *API) SetReachCardProvider(p ReachCardProvider)

SetReachCardProvider installs the provider behind GET /reach.

func (*API) SetRelatedNodesProvider

func (api *API) SetRelatedNodesProvider(p RelatedNodesProvider)

SetRelatedNodesProvider installs the provider whose managed-visors and configured-hypervisors lists are shown (as links) on the landing page to authenticated callers. Called from visor init.

func (*API) SetServiceLister

func (api *API) SetServiceLister(lister ServiceLister)

SetServiceLister sets the service catalog provider. Called from visor init after the ServiceRegistry is populated.

func (*API) SetStatsReader

func (api *API) SetStatsReader(r StatsReader)

SetStatsReader wires the telemetry store into the log server. Safe to call with nil — handlers degrade to "stats unavailable" 503.

func (*API) SetStatusPage added in v1.3.101

func (api *API) SetStatusPage(h http.Handler)

SetStatusPage serves h at /status and links it from the landing page.

func (*API) SetTransportListProvider added in v1.3.100

func (api *API) SetTransportListProvider(p TransportListProvider)

SetTransportListProvider installs the provider behind GET /transports.

func (*API) SetUptimeRecorder

func (api *API) SetUptimeRecorder(r *serviceuptime.Recorder)

SetUptimeRecorder wires the recorder into the log server. Safe to call before or after handler registration; the routes nil-check at request time, so a recorder attached after some early traffic still works for subsequent requests.

func (*API) SetVhosts added in v1.3.101

func (api *API) SetVhosts(vs []Vhost)

SetVhosts replaces the sites served by Host. Nil or empty serves none.

func (*API) SetVisorStatusPage

func (api *API) SetVisorStatusPage(h http.Handler, readers func() []cipher.PubKey)

SetVisorStatusPage serves h at /status/visor to this visor, the survey whitelist and the keys readers returns, and links it from their landing page.

func (*API) SetWasmModule added in v1.3.101

func (api *API) SetWasmModule(path string)

SetWasmModule serves the js/wasm module at path and its manifest beside it under GET /wasm/, so other visors can refresh their copy from this one.

func (*API) SetWebsiteHandler

func (api *API) SetWebsiteHandler(h http.Handler)

SetWebsiteHandler sets a custom HTTP handler for serving unmatched routes on the visor's DMSG/skynet port 80. Visor system endpoints (/health, /node-info, /services, etc.) always take priority.

Use cases: - Static file server: http.FileServer(http.Dir("/path/to/site")) - Reverse proxy to a local web app: httputil.ReverseProxy - The reward system UI handler

type CXOFeedEntry

type CXOFeedEntry struct {
	Name        string `json:"name"`
	DmsgPort    uint16 `json:"dmsg_port"`
	Description string `json:"description,omitempty"`
	System      bool   `json:"system,omitempty"`
}

CXOFeedEntry describes one CXO TreeStore feed published by the visor. Subscribers connect to (visor PK, DmsgPort) over DMSG and request the registered prefix, mirroring the data into their own subscriber.

type CXOFeedsLister

type CXOFeedsLister interface {
	ListCXOFeeds() []CXOFeedEntry
}

CXOFeedsLister provides the list of CXO feeds the visor is publishing. Returns the always-on system feed (stats/telemetry) plus any user-registered feeds. Pure metadata — actual feed content is served out-of-band over DMSG by treestore.Publisher.

type ForwardedPortEntry

type ForwardedPortEntry struct {
	Port        int    `json:"port"`
	Label       string `json:"label"`
	Description string `json:"description"`
}

ForwardedPortEntry describes a user-forwarded port for the landing page.

type ForwardedPortLister

type ForwardedPortLister interface {
	LandingPageEntries() []ForwardedPortEntry
	// PortWhitelist returns the PK whitelist for a given port.
	// An empty slice means the port is accessible to everyone.
	PortWhitelist(port int) []cipher.PubKey
}

ForwardedPortLister provides forwarded ports for the landing page and per-port whitelist for access control.

type HealthStatsProvider

type HealthStatsProvider interface {
	// IsPublicAutoconnectRunning returns true if the public autoconnect module is running.
	IsPublicAutoconnectRunning() bool
	// GetTransportCounts returns the count of STCPR and SUDPH transports (excluding "user" labeled).
	GetTransportCounts() (stcpr, sudph int)
	// GetTransportTypeCounts returns a count of live transports keyed by their
	// actual network type (excluding "user" labeled) — every present type, not
	// just stcpr/sudph.
	GetTransportTypeCounts() map[string]int
	// GetNetworkTypes returns the network types used by the visor.
	GetNetworkTypes() []string
}

HealthStatsProvider provides transport statistics for the /health endpoint.

type LogLevelController added in v1.3.100

type LogLevelController interface {
	LogLevelStatus() LogLevelStatus
	SetTempLogLevel(level logrus.Level, ttl time.Duration) (LogLevelStatus, error)
	ClearTempLogLevel() LogLevelStatus
}

LogLevelController changes the visor's log level for a bounded time. A temporary level is never written to the config, so a restart ends it too.

type LogLevelStatus added in v1.3.100

type LogLevelStatus struct {
	Level string     `json:"level"`
	Base  string     `json:"base,omitempty"`
	Until *time.Time `json:"until,omitempty"`
}

LogLevelStatus is the visor's log level as /debug/loglevel reports it. Base and Until are set only while a temporary level is in force: Base is the level the visor goes back to at Until.

type ReachCardProvider added in v1.3.100

type ReachCardProvider interface {
	ReachCardBody() ([]byte, error)
}

ReachCardProvider supplies this visor's signed reach card as a JSON body.

type RelatedNodesProvider

type RelatedNodesProvider interface {
	// ManagedVisors returns the PKs of the visors this node currently
	// manages as a hypervisor (the same set as `hv ls`). Empty when this
	// node is not acting as a hypervisor or has no connected visors.
	ManagedVisors() []cipher.PubKey
	// ConfiguredHypervisors returns the PKs of the hypervisors this visor
	// is configured to be managed by (v.conf.Hypervisors).
	ConfiguredHypervisors() []cipher.PubKey
}

RelatedNodesProvider exposes this node's mesh relationships for the landing page: the visors a hypervisor manages, and the hypervisors a visor is configured to trust. Both are shown ONLY to an authenticated (survey-whitelisted, or self-loopback) caller — they reveal the node's management topology — and rendered as links to each peer's landing page (http://<pk>.dmsg), reachable through a resolving proxy.

Implemented by the visor. A nil provider (or empty slices) renders no related-nodes section.

type ServiceEntry

type ServiceEntry struct {
	Port  uint16 `json:"port"`
	Label string `json:"label"`
}

ServiceEntry describes a port-forwarded service for the /services catalog.

type ServiceLister

type ServiceLister interface {
	ListPublic() []ServiceEntry
}

ServiceLister provides the service catalog for the /services endpoint. Implemented by visor's ServiceRegistry.

type SiteList

type SiteList struct {
	PK    string   `json:"pk"`
	Sites []string `json:"sites"`
}

SiteList is what GET /.skywire/sites returns.

type StatsReader

type StatsReader interface {
	AllTransportRecords() ([]*stats.TransportRecord, error)
	GetTransportRecord(id uuid.UUID) (*stats.TransportRecord, error)
	TierNames() ([]string, error)
	TierBitmap(tier string, date time.Time) ([]byte, error)
	TierDates(tier string) ([]string, error)
	ServiceNames() ([]string, error)
	ServiceBitmap(svc string, date time.Time) ([]byte, error)
	ServiceDates(svc string) ([]string, error)
}

StatsReader is the read-only view of the visor's telemetry store the log server needs. Implemented by *stats.Store via structural typing — no explicit assertion needed.

type TransportListProvider added in v1.3.100

type TransportListProvider interface {
	TransportListBody() (body []byte, version string, err error)
}

TransportListProvider supplies this visor's signed transport list as a JSON body and the version that names the set.

type Vhost added in v1.3.101

type Vhost struct {
	Name      string   // shown on the landing page
	Names     []string // Host names, lower case: the name and its aliases
	Handler   http.Handler
	Whitelist []cipher.PubKey // empty = everyone
	// Sites are the names its backend serves, for a vhost that takes many.
	Sites func() []string
	// VisorPages serves the visor's own pages under this name instead of a site.
	VisorPages bool
}

Vhost is a site served on port 80 for the Host names it lists, ahead of the visor's own pages, which stay on its bare name.

Directories

Path Synopsis
Package landingpage pkg/visor/logserver/landingpage/landingpage.go c3-vis-core http://<pk>.dmsg/ (and skywire.dmsg → the visor's own PK).
Package landingpage pkg/visor/logserver/landingpage/landingpage.go c3-vis-core http://<pk>.dmsg/ (and skywire.dmsg → the visor's own PK).

Jump to

Keyboard shortcuts

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