view

package
v0.4.2 Latest Latest
Warning

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

Go to latest
Published: Sep 30, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

templ: version: v0.3.1020

templ: version: v0.3.1020

templ: version: v0.3.1020

templ: version: v0.3.1020

templ: version: v0.3.1020

templ: version: v0.3.1020

templ: version: v0.3.1020

templ: version: v0.3.1020

templ: version: v0.3.1020

templ: version: v0.3.1020

templ: version: v0.3.1020

Index

Constants

View Source
const AssetPrefix = "/assets/"

AssetPrefix is the route the asset tree is served under, relative to the mount path.

View Source
const FeedRows = 25

FeedRows is the number of traces the live feed holds, which the view states under the table and the handler cuts the feed to.

Variables

View Source
var LimitOptions = []int{20, 50, 100, 200}

LimitOptions are the row counts offered on the trace list.

SortKeys lists the sortable columns, so an unknown value in a URL falls back to the default rather than sorting by nothing.

Functions

func Assets

func Assets() fs.FS

Assets returns the embedded tree, whose paths line up with the URLs they are served at.

func Detail

func Detail(ctx context.Context, w io.Writer, page Page) error

Detail renders the trace detail: the timeline, the spans, the logs and the facts beside them.

func Filter

func Filter(traces []model.Trace, page Page) []model.Trace

Filter applies the list filters of a page.

func Hosts

func Hosts(ctx context.Context, w io.Writer, page Page) error

Hosts renders the landing page, one row per host the service answered for.

func Layout

func Layout(page Page) templ.Component

Layout renders the page chrome shared by every view.

func List

func List(ctx context.Context, w io.Writer, page Page) error

List renders the retained traces, filtered and sorted the way the page asks.

func Live

func Live(ctx context.Context, w io.Writer, page Page) error

Live renders the live feed: traces in flight and completed traces in one stream.

func LiveScript

func LiveScript() string

LiveScript returns the embedded live view script of the debug front end. It subscribes to the event stream and swaps in the section the server renders.

func LiveSection

func LiveSection(ctx context.Context, w io.Writer, page Page) error

LiveSection renders the feed alone, which is what the event stream pushes on every change: the page around it is already in the browser.

func Login

func Login(ctx context.Context, w io.Writer, page Page) error

Login renders the sign in screen.

func Slowest

func Slowest(traces []model.Trace) time.Duration

Slowest returns the longest duration in a set of traces, used to scale the inline bars so rows compare against each other.

func Sort

func Sort(traces []model.Trace, key SortKey, ascending bool)

Sort orders traces by key. Ascending means "smallest first" for numbers and "oldest first" for age, which is what the arrow in the header claims.

func Statistics

func Statistics(ctx context.Context, w io.Writer, page Page) error

Statistics renders the rolling window grouped by route.

func StyleSheet

func StyleSheet(base string) string

StyleSheet returns the embedded stylesheet of the debug front end, with its asset URLs resolved against base, which is the mount path plus /assets/.

func Text

func Text(w io.Writer, page Page)

Text renders a page as fixed width plain text, for terminals and curl.

Types

type AxisTick

type AxisTick struct {
	Share float64 `json:"share_percent"`
	Label string  `json:"label"`
}

AxisTick is one labelled step of the time axis under a timeline.

type MemoryBudget

type MemoryBudget struct {
	// Limit is the ceiling the transaction ran under, Used what it had in use
	// when it finished, and Share the second as a percentage of the first.
	Limit int64   `json:"limit_bytes,omitempty"`
	Used  int64   `json:"used_bytes,omitempty"`
	Share float64 `json:"used_percent,omitempty"`

	HasLimit bool `json:"-"`
	HasUsed  bool `json:"-"`

	// Peak is the largest reading any span reported, and Spans whether any of
	// them did. The per span bars are drawn against the peak and not against
	// the limit, which would draw a whole trace as identical slivers.
	Peak  int64 `json:"peak_bytes,omitempty"`
	Spans bool  `json:"-"`
}

MemoryBudget is the memory_limit and memory_usage a trace recorded, read off the trace and off its spans. Every part of it is optional.

func TraceMemory

func TraceMemory(trace model.Trace, rows []SpanRow) MemoryBudget

TraceMemory reads the memory a trace reported, from its attributes and from the rows flattened out of its spans.

func (MemoryBudget) Known

func (b MemoryBudget) Known() bool

Known reports whether the trace recorded any memory at all.

func (MemoryBudget) ShareOf

func (b MemoryBudget) ShareOf(size int64) float64

ShareOf returns a reading as a percentage of the largest one in the trace.

type MemoryPoint

type MemoryPoint struct {
	// Name is the span the reading came from, and Offset when the span
	// finished, relative to the start of the trace.
	Name   string        `json:"name"`
	Offset time.Duration `json:"offset_ns"`
	Bytes  int64         `json:"bytes"`

	// X is the offset as a percentage of the trace width, and Y the reading
	// as a percentage down from the top of the plot, both ready to draw.
	X float64 `json:"x_percent"`
	Y float64 `json:"y_percent"`
}

MemoryPoint is one reading on the memory graph: the memory a span reported in use when it finished, placed at the moment it finished.

type MemorySeries

type MemorySeries struct {
	Points []MemoryPoint `json:"points"`

	// Ceiling is the top of the value scale, in bytes: the limit when it sits
	// close enough to the readings to share a scale with them, the peak
	// reading otherwise.
	Ceiling int64 `json:"ceiling_bytes"`

	// Limited reports whether the limit is drawn as a reference line, and
	// LimitY where the line sits, as a percentage down from the top.
	Limited bool    `json:"-"`
	LimitY  float64 `json:"-"`
}

MemorySeries is the data behind the memory graph: the readings the spans reported, ordered by when they were taken.

func (MemorySeries) Last

func (s MemorySeries) Last() MemoryPoint

Last returns the newest reading, which is the one the graph labels.

type Page

type Page struct {
	Snapshot model.Snapshot
	View     View
	Path     string
	Title    string
	Limit    int
	Query    string
	Kind     model.Kind

	// Host is the domain filter, empty for every host. RequestHost is the
	// domain this dashboard was reached on, which is the sensible default
	// label when no filter is set.
	Host        string
	RequestHost string

	Status    string
	Sort      SortKey
	Ascending bool
	Refresh   int
	Stream    bool
	Slowest   time.Duration

	// Feed is the live view: traces in flight and completed traces in one
	// stream, newest first.
	Feed []model.Trace

	Trace    *model.Trace
	Rows     []SpanRow
	Segments []Segment

	// Memory is the memory the detail view trace reported, read once because
	// every row of the span table draws against it.
	Memory MemoryBudget

	// LoginUsername is the username a failed login was attempted with, kept so
	// the form does not empty itself. LoginError is what went wrong, worded
	// with what to do next.
	// LoginBack is where a successful login returns to, carried through the
	// redirect and the form as ?back.
	LoginUsername string
	LoginError    string
	LoginBack     string
}

Page is the view model handed to every templ component. Components take nothing else, so they can be rendered in tests from a hand built page.

func NewLivePage

func NewLivePage(opts model.Options, snapshot model.Snapshot, r *http.Request) Page

NewLivePage builds the live view: traces in flight and completed traces merged into one feed, newest first, so a request appears the moment it starts and stays put as it finishes rather than jumping between two tables.

func NewPage

func NewPage(opts model.Options, snapshot model.Snapshot, name View, r *http.Request) Page

NewPage builds the view model shared by every component: the snapshot to render, the page it is rendered as, and the filters the request asks for.

func (Page) Active

func (p Page) Active(view View) bool

Active reports whether view is the rendered one.

func (Page) Age

func (p Page) Age(at time.Time) string

Age renders how long ago a timestamp is, relative to the snapshot.

func (Page) AssetURL

func (p Page) AssetURL(name string) string

AssetURL links a file in the embedded asset tree.

func (Page) CSSURL

func (p Page) CSSURL() string

CSSURL is the link to the embedded stylesheet.

func (Page) Composition

func (p Page) Composition(trace model.Trace) []Segment

Composition returns the timeline of a trace scaled to the slowest trace on the page, so one row of bars compares traces against each other rather than against themselves. The shape of a request (how much of it was database, how much was waiting on someone else) is the thing worth seeing in a list.

func (Page) Domain

func (p Page) Domain() string

Domain is the label of the switcher in the masthead, where unfiltered means every host rather than the one the dashboard was reached on.

func (Page) DurationShare

func (p Page) DurationShare(trace model.Trace) float64

DurationShare returns the duration of a trace relative to the slowest trace on the page.

func (Page) EventsURL

func (p Page) EventsURL() string

EventsURL is the link to the live view event stream.

func (Page) Fields

func (p Page) Fields() []SelectField

Fields returns the filter bar controls in display order. The domain is not among them: it is chosen once in the masthead and every view inherits it.

func (Page) Filtered

func (p Page) Filtered() bool

Filtered reports whether the view is narrowed to one host.

func (Page) HostLiveURL

func (p Page) HostLiveURL(host string) string

HostLiveURL builds a link to the live feed of one host.

func (Page) HostURL

func (p Page) HostURL(host string) string

HostURL builds a link to the trace list filtered to one host.

func (Page) Hosts

func (p Page) Hosts() []model.HostStat

Hosts returns the hosts seen by the process, for the filter control.

func (Page) JSURL

func (p Page) JSURL() string

JSURL is the link to the embedded live view script.

func (Page) KindField

func (p Page) KindField() SelectField

KindField filters the list by the span kinds a trace recorded.

func (Page) KindShares

func (p Page) KindShares() []Segment

KindShares totals the timeline by kind, newest share first, for the legend.

func (Page) LimitOptions

func (p Page) LimitOptions() []int

LimitOptions returns the selectable row counts.

func (Page) LimitURL

func (p Page) LimitURL(limit int) string

LimitURL builds a link to the trace list with a different row count.

func (Page) LogCount

func (p Page) LogCount() int

LogCount returns the number of log entries of the detail view trace.

func (Page) LogOffset

func (p Page) LogOffset(entry model.LogEntry) time.Duration

LogOffset returns when an entry was written, relative to the trace start.

func (Page) LogSpan

func (p Page) LogSpan(entry model.LogEntry) *model.Span

LogSpan returns the span an entry was written under, or nil when the entry was written outside one or the span was dropped.

func (Page) LogSpanName

func (p Page) LogSpanName(entry model.LogEntry) string

LogSpanName returns the name of the span an entry was written under, or nothing when the entry was written outside any open span.

func (Page) LoginPath

func (p Page) LoginPath() string

LoginPath is where the sign in form lives and submits.

func (Page) MemorySeries

func (p Page) MemorySeries() MemorySeries

MemorySeries returns the readings behind the memory graph: one point per span that reported memory_usage, placed where the span finished and ordered by it. A reading is the memory in use at that moment, so the line holds flat between readings and moves where one was taken.

The scale runs to the limit when the limit is within reach of the readings, and to the peak reading when it is not: a transaction far under its limit still draws its own shape rather than a sliver along the floor.

func (Page) Now

func (p Page) Now() time.Time

Now returns the moment the snapshot was taken.

func (Page) RowsField

func (p Page) RowsField() SelectField

RowsField picks how many rows the list shows.

func (Page) Service

func (p Page) Service() string

Service returns the configured service name, or a placeholder.

func (Page) SortClass

func (p Page) SortClass(key SortKey) string

SortClass marks the active sort column for the header link.

func (Page) SortURL

func (p Page) SortURL(key SortKey) string

SortURL builds a link that sorts by key. Clicking the active column flips the direction; clicking another column starts it at the useful end, which for every one of these is largest first.

func (Page) StatusField

func (p Page) StatusField() SelectField

StatusField filters the list down to failures.

func (Page) StatusURL

func (p Page) StatusURL(status string) string

StatusURL builds a link to the trace list with a different status filter.

func (Page) SwitchHostURL

func (p Page) SwitchHostURL(host string) string

SwitchHostURL keeps the reader on the current view and changes the domain.

func (Page) Ticks

func (p Page) Ticks() []AxisTick

Ticks returns the labelled steps of the detail view time axis.

func (Page) TraceURL

func (p Page) TraceURL(id string) string

TraceURL builds a link to the detail view of a trace.

func (Page) TracesPath

func (p Page) TracesPath() string

TracesPath is where the filter form submits. It is a path with no query, because a GET form replaces the query with its own fields.

func (Page) URL

func (p Page) URL(view View) string

URL builds a link to a view of the front end, preserving the active filters.

func (Page) WaveSpans

func (p Page) WaveSpans() []WaveSpan

WaveSpans returns every span of the trace in the shape the drawing fills: where it ran as a fraction of the trace, and how deep it sat.

The legend attributes each moment to the innermost span running, which is the right way to answer where the time went, and the wrong way to draw the stack: a request that spends its life inside three queries reports as three queries, and the handler and the request holding them never appear. The drawing wants the opposite, so it gets the spans whole. Parents included, the root included: at any moment, everything that was running.

func (Page) WaveTrace

func (p Page) WaveTrace() WaveTrace

WaveTrace is the span data plus the length and the depth of the trace, which is what the drawing scales itself to.

type Segment

type Segment struct {
	Kind        model.Kind    `json:"kind"`
	Offset      time.Duration `json:"offset_ns"`
	Duration    time.Duration `json:"duration_ns"`
	OffsetShare float64       `json:"offset_percent"`
	Share       float64       `json:"share_percent"`
}

Segment is one point-in-time region of a trace where a span kind was the innermost active span.

func Timeline

func Timeline(trace model.Trace) []Segment

Timeline converts the spans of a trace into non overlapping segments, each attributed to the innermost span that was active during it. Shares are percentages of the trace duration, so segments render directly as CSS offsets and widths.

type SelectField

type SelectField struct {
	ID      string         `json:"id"`
	Name    string         `json:"name"`
	Label   string         `json:"label"`
	Value   string         `json:"value"`
	Options []SelectOption `json:"options"`
}

SelectField is a dropdown on the filter bar. The control is rendered rather than delegated to a native select, because a native select cannot be styled consistently across platforms, least of all its open menu.

func (SelectField) IsSelected

func (f SelectField) IsSelected(option SelectOption) bool

IsSelected reports whether an option is the chosen one.

func (SelectField) Selected

func (f SelectField) Selected() string

Selected returns the label of the chosen option, falling back to the first one, so the closed control always names its own state.

type SelectOption

type SelectOption struct {
	Value string `json:"value"`
	Label string `json:"label"`

	// Note is the secondary text on the right of the option, such as a count.
	Note string `json:"note,omitempty"`
}

SelectOption is one choice in a SelectField.

type SortKey

type SortKey string

SortKey names a column the trace list can be ordered by.

const (
	SortAge       SortKey = "age"
	SortDuration  SortKey = "duration"
	SortSpans     SortKey = "spans"
	SortAllocated SortKey = "allocated"
)

The columns the trace list can be ordered by.

type SpanRow

type SpanRow struct {
	model.Span

	Offset      time.Duration `json:"offset_ns"`
	OffsetShare float64       `json:"offset_percent"`
	Share       float64       `json:"share_percent"`
	Open        bool          `json:"open,omitempty"`
	Last        bool          `json:"-"`

	// Memory is the memory_usage the span reported, and HasMemory whether it
	// reported one. Zero bytes in use and no reading are different answers.
	Memory    int64 `json:"memory_usage_bytes,omitempty"`
	HasMemory bool  `json:"-"`
}

SpanRow is the flattened render model of one span within a trace.

func Rows

func Rows(trace model.Trace) []SpanRow

Rows flattens the spans of a trace into depth first render rows.

type View

type View string

View identifies one rendered page of the debug front end.

const (
	// ViewHosts is the landing page: which domains this process serves, and
	// how much traffic each one carries. Everything else is a drill down.
	ViewHosts  View = "hosts"
	ViewList   View = "list"
	ViewLive   View = "live"
	ViewStats  View = "stats"
	ViewDetail View = "detail"

	// ViewLogin is the sign in screen, rendered when authentication is
	// configured and the request carries no valid session or bearer token. It
	// draws none of the recorded data.
	ViewLogin View = "login"
)

The pages the front end serves. Page.URL builds a link to any of them.

type WaveSpan

type WaveSpan struct {
	Name   string  `json:"name"`
	Kind   string  `json:"kind"`
	Color  string  `json:"color"`
	Start  float64 `json:"start"`
	End    float64 `json:"end"`
	Depth  int     `json:"depth"`
	Failed bool    `json:"failed,omitempty"`
}

WaveSpan is one span in the shape the drawing wants: where it ran as a fraction of the trace, how deep it sat, and what colour it draws in.

Every span is handed over, parents and root included, because the drawing is of the stack: a span that wraps the whole trace is the reason there is a floor under everything else. The legend answers the other question, where the time went, and answers it from the sweep instead.

type WaveTrace

type WaveTrace struct {
	Milliseconds float64    `json:"ms"`
	Depth        int        `json:"depth"`
	Spans        []WaveSpan `json:"spans"`
}

WaveTrace is the payload behind the drawing: the spans, how long the trace took, and how deep it nested. The duration lets the drawing work in time rather than in pixels; the depth lets it scale itself to the trace it has rather than to a number someone guessed.

Jump to

Keyboard shortcuts

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