web

package
v1.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 15, 2026 License: MIT Imports: 54 Imported by: 0

Documentation

Overview

Package web renders isutools measurements: a live report, a self-contained downloadable snapshot.html, machine-readable JSON, and a reset endpoint.

Index

Constants

View Source
const (
	SaveReasonMethodNotAllowed  = "method-not-allowed"
	SaveReasonDataDirUnset      = "data-dir-unset"
	SaveReasonInvalidPass       = "invalid-pass"
	SaveReasonRunNotActive      = "run-not-active"
	SaveReasonRunAlreadySaved   = "run-already-saved"
	SaveReasonMutationBusy      = "mutation-busy"
	SaveReasonSnapshotTooLarge  = "snapshot-too-large"
	SaveReasonPersistFailed     = "persist-failed"
	SaveReasonPersistenceUnsafe = "persistence-unavailable"
	SaveReasonSaved             = "saved"
)
View Source
const AdminReasonHeader = "X-Isutools-Reason"

AdminReasonHeader mirrors the stable machine-readable reason in an admin endpoint error response. It lets shell wrappers classify a failure without parsing human text.

Variables

This section is empty.

Functions

func NewHandler

func NewHandler(p Provider) http.Handler

NewHandler returns the report handler. Routes are relative: GET / (run index), GET /<run-id> (stored run detail), GET /live, GET /snapshot.html, GET /json, GET /files/<name>, POST /reset, POST /collect, POST /finish, POST /abort, POST /save.

func PruneProfileArtifacts added in v1.4.0

func PruneProfileArtifacts(dataDir, protectFile string)

PruneProfileArtifacts applies the shared raw-profile retention after a run-aligned CPU completion that may occur without any cumulative profile capture to trigger the handler-local path.

func SectionHealth added in v1.2.0

func SectionHealth(sections map[string]any) []health.Entry

SectionHealth derives the health entries a completed run's sections report, one per collector, sorted by collector name.

The baseline collectors carry their notes inside the section value instead of pushing them into a registry, because Collect must be pure. Somebody has to forward them; this is that step, and it is exported so the process-wide registry and this package's renderer forward exactly the same set.

Types

type AdminAudit added in v1.5.0

type AdminAudit struct {
	Time       time.Time `json:"time"`
	Operation  string    `json:"operation"`
	Status     int       `json:"status"`
	Reason     string    `json:"reason"`
	RunID      string    `json:"run_id,omitempty"`
	Generation int64     `json:"generation"`
}

AdminAudit is a bounded, secret-free audit event for mutating admin calls. Provider.AdminAudit may ship it to an application logger; otherwise web writes the JSON object to the standard logger.

type AdminErrorResponse added in v1.5.0

type AdminErrorResponse struct {
	Error  string `json:"error"`
	Reason string `json:"reason"`
}

AdminErrorResponse is deliberately small and stable. Internal errors, request values, filesystem paths, DSNs and credentials never enter it.

type BoundaryProfiler added in v1.2.0

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

BoundaryProfiler captures the opening half of a profile pair for a run that was opened outside this package's HTTP surface.

It exists because POST /reset is not the only way a run begins. An application that follows the documented initialize contract opens its runs from its own handler through isutools.ResetNow and may never send a reset at all; without this entry point such a process publishes no opening artifact, and every closing capture finds nothing to pair with and writes nothing.

Both entry points share one process-wide ledger keyed by the data directory, so a run opened here is closed by POST /finish or POST /save exactly as a run opened by POST /reset is, and the two halves are filed under one prefix.

func NewBoundaryProfiler added in v1.2.0

func NewBoundaryProfiler(p Provider) *BoundaryProfiler

NewBoundaryProfiler returns the capturer for a provider's profile configuration, or nil when the configuration captures nothing — no data directory to publish into, or no profile kinds enabled.

Only DataDir, RuntimeProfiles and Health are read; the capture path touches no collector and serves no request. The kinds are copied, so a caller that later rewrites its own slice cannot change what an opened run captures at its closing boundary.

func (*BoundaryProfiler) CaptureOpen added in v1.2.0

func (b *BoundaryProfiler) CaptureOpen(run RunStart, generation int64) []string

CaptureOpen writes the opening half of the run's profile pair and returns the artifacts it published.

Call it the moment the coordinator returns the boundary and before the response that releases the benchmarker: the capture is synchronous for the same reason the reset path's is, because a moment chosen by the scheduler is not a boundary.

A nil receiver captures nothing, so a caller never has to branch on whether profiling was configured. Nothing here is fatal.

type BoundaryWindow added in v1.2.0

type BoundaryWindow struct {
	Min    time.Time     `json:"min,omitzero"`
	Max    time.Time     `json:"max,omitzero"`
	Spread time.Duration `json:"spread_ns"`
}

BoundaryWindow is the measured span of one coordinated boundary.

type CPUCaptureCoordinator added in v1.4.0

type CPUCaptureCoordinator interface {
	StartRun(context.Context, CPUStartRequest) CPUStartResult
	StartFixed(context.Context, FixedCPUStartRequest) CPUStartResult
	RequestStop(CPUStopRequest) CPUStopTicket
	Await(CPUStopTicket, context.Context) CPUCaptureStatus
	Manifest(runID string, epoch uint64) *CPUIntervalCapture
	LabelDictionary(runID string, epoch uint64) *CPULabelDictionary
}

CPUCaptureCoordinator is the transport-facing view of the process-wide CPU profiler owner. Implementations must make RequestStop non-blocking; the runtime profiler's synchronous flush belongs to its worker, never an HTTP or run-controller goroutine.

type CPUCaptureStatus added in v1.4.0

type CPUCaptureStatus struct {
	RunID            string
	CaptureID        string
	Epoch            uint64
	State            string
	Code             string
	Err              error
	BoundaryStart    time.Time
	BoundaryFinish   time.Time
	StartRequestedAt time.Time
	StartCompletedAt time.Time
	StopRequestedAt  time.Time
	StopCompletedAt  time.Time
	StopReason       string
	RunSpan          time.Duration
	CaptureSpan      time.Duration
	HeadLoss         time.Duration
	TailExcess       time.Duration
	TailLoss         time.Duration
	Complete         bool
}

type CPUIntervalCapture added in v1.4.0

type CPUIntervalCapture struct {
	RunID            string    `json:"run_id"`
	Epoch            uint64    `json:"epoch"`
	CaptureID        string    `json:"capture_id"`
	ExpectedFile     string    `json:"expected_file"`
	File             string    `json:"file,omitempty"`
	SHA256           string    `json:"sha256,omitempty"`
	Bytes            int64     `json:"bytes,omitempty"`
	Sidecar          string    `json:"sidecar,omitempty"`
	SidecarSHA256    string    `json:"sidecar_sha256,omitempty"`
	CoverageFile     string    `json:"coverage_file,omitempty"`
	CoverageSHA256   string    `json:"coverage_sha256,omitempty"`
	Status           string    `json:"status"`
	Code             string    `json:"code,omitempty"`
	BoundaryStart    time.Time `json:"boundary_start,omitzero"`
	BoundaryFinish   time.Time `json:"boundary_finish,omitzero"`
	StartRequestedAt time.Time `json:"start_requested_at,omitzero"`
	StartCompletedAt time.Time `json:"start_completed_at,omitzero"`
	StopRequestedAt  time.Time `json:"stop_requested_at,omitzero"`
	StopCompletedAt  time.Time `json:"stop_completed_at,omitzero"`
	StopReason       string    `json:"stop_reason,omitempty"`
	RunSpanNs        int64     `json:"run_span_ns,omitempty"`
	CaptureSpanNs    int64     `json:"capture_span_ns,omitempty"`
	HeadLossNs       int64     `json:"head_loss_ns,omitempty"`
	TailExcessNs     int64     `json:"tail_excess_ns,omitempty"`
	TailLossNs       int64     `json:"tail_loss_ns,omitempty"`
	Complete         bool      `json:"complete"`
}

CPUIntervalCapture is the immutable snapshot projection. Fields are added only when the underlying artifact and hash have been fixed.

type CPULabelDictionary added in v1.4.0

type CPULabelDictionary struct {
	RunID     string           `json:"run_id"`
	Epoch     uint64           `json:"epoch"`
	CaptureID string           `json:"capture_id"`
	Sealed    bool             `json:"sealed"`
	Tuples    []SafeLabelTuple `json:"tuples"`
	SHA256    string           `json:"sha256"`
}

type CPUStartRequest added in v1.4.0

type CPUStartRequest struct {
	RunID            string
	Epoch            uint64
	State            string
	Validity         string
	BoundaryStart    time.Time
	GenerationWindow BoundaryWindow
	BoundaryWindow   BoundaryWindow
}

type CPUStartResult added in v1.4.0

type CPUStartResult struct {
	RunID     string
	CaptureID string
	Epoch     uint64
	State     string
	Code      string
}

type CPUStopRequest added in v1.4.0

type CPUStopRequest struct {
	RunID      string
	Epoch      uint64
	State      string
	Validity   string
	Reason     string
	BoundaryAt time.Time
}

type CPUStopTicket added in v1.4.0

type CPUStopTicket struct {
	RunID      string
	CaptureID  string
	Epoch      uint64
	State      string
	Code       string
	BoundaryAt time.Time
}

type FixedCPUProfileRecord added in v1.4.0

type FixedCPUProfileRecord struct {
	Schema           string    `json:"schema"`
	Mode             string    `json:"mode"`
	CaptureID        string    `json:"capture_id"`
	Generation       int64     `json:"generation"`
	RequestedAt      time.Time `json:"requested_at"`
	StartCompletedAt time.Time `json:"start_completed_at,omitzero"`
	StopRequestedAt  time.Time `json:"stop_requested_at,omitzero"`
	StopCompletedAt  time.Time `json:"stop_completed_at,omitzero"`
	DurationNs       int64     `json:"duration_ns,omitempty"`
	File             string    `json:"file,omitempty"`
	SHA256           string    `json:"sha256,omitempty"`
	Bytes            int64     `json:"bytes,omitempty"`
	Status           string    `json:"status"`
	Code             string    `json:"code,omitempty"`
	Visibility       string    `json:"visibility,omitempty"`
	Durability       string    `json:"durability,omitempty"`
}

FixedCPUProfileRecord is the immutable evidence record for the legacy timer-only CPU capture mode. It deliberately contains no RunID because fixed mode is not aligned to a run boundary and must not be mistaken for one.

type FixedCPUProfiler added in v1.4.0

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

FixedCPUProfiler is the process-shared entry point for timer-only fixed capture. Handler and ResetNow can hold the same instance; the package-wide runtime guard also preserves compatibility for independently constructed legacy handlers.

func NewFixedCPUProfiler added in v1.4.0

func NewFixedCPUProfiler(dataDir string, duration time.Duration) *FixedCPUProfiler

func (*FixedCPUProfiler) Capture added in v1.4.0

func (p *FixedCPUProfiler) Capture(generation int64) bool

type FixedCPUStartRequest added in v1.4.0

type FixedCPUStartRequest struct {
	RunID            string
	Epoch            uint64
	State            string
	Validity         string
	Generation       int64
	Duration         time.Duration
	RequestedAt      time.Time
	GenerationWindow BoundaryWindow
	BoundaryWindow   BoundaryWindow
}

type Meta

type Meta struct {
	SchemaVersion int    `json:"schema_version"`
	Time          string `json:"time"`
	Generation    int64  `json:"generation"`
	Revision      string `json:"revision"`
	Dirty         bool   `json:"dirty"`
	// BuildSource says how Revision was obtained (vcs, ldflags, env, unknown).
	// ProvenanceValid is false for an unknown or dirty build, where a snapshot
	// cannot be reproduced from Revision alone.
	BuildSource     string `json:"build_source"`
	ProvenanceValid bool   `json:"provenance_valid"`
	// Score is the benchmark score supplied via POST /save?score=; persisted
	// snapshots always carry it so every report is attributable to a result.
	Score         string         `json:"score,omitempty"`
	BenchmarkPass *bool          `json:"benchmark_pass,omitempty"`
	Host          sysinfo.Info   `json:"host"`
	Partial       bool           `json:"partial"`
	Health        []health.Entry `json:"health,omitempty"`
	Run           *RunInfo       `json:"run,omitempty"`
	// Profiles is the run's runtime-profile record: every capture attempted at
	// either boundary and the pairs that can be differenced. It is filled when
	// a run is persisted, because that is the first moment both halves exist;
	// a live report has no closing half yet and omits the field. Additive and
	// omitempty, so a v1.0 reader of this JSON is unaffected.
	Profiles *ProfileManifest `json:"profiles,omitempty"`
}

Meta identifies when, on which host, and from which revision a snapshot was taken. Generation increments on every reset so runs are comparable.

type ProfileAnalysisCapabilities added in v1.4.0

type ProfileAnalysisCapabilities struct {
	Schema                     string                   `json:"schema"`
	StrongAtomicVisibility     bool                     `json:"strong_atomic_visibility"`
	CrashDurability            string                   `json:"crash_durability"`
	CapabilityError            string                   `json:"capability_error,omitempty"`
	RetentionRuns              int                      `json:"retention_runs"`
	RetentionBytes             uint64                   `json:"retention_bytes"`
	ProfileCaptureMaxBytes     uint64                   `json:"profile_capture_max_bytes"`
	CaptureSidecarMaxBytes     uint64                   `json:"capture_sidecar_max_bytes"`
	CPUCoverageMaxBytes        uint64                   `json:"cpu_coverage_max_bytes"`
	CPULabelDictionaryMaxBytes uint64                   `json:"cpu_label_dictionary_max_bytes"`
	ExpectedProfileFilesPerRun uint64                   `json:"expected_profile_files_per_run"`
	SnapshotArtifactMaxPerRun  uint64                   `json:"snapshot_artifact_max_bytes_per_run"`
	PerRunCeilingBytes         uint64                   `json:"per_run_ceiling_bytes"`
	ProfileUsageKnown          bool                     `json:"profile_usage_known"`
	ProfileUsageBytes          uint64                   `json:"profile_usage_bytes,omitempty"`
	DataDirAvailableKnown      bool                     `json:"data_dir_available_known"`
	DataDirAvailableBytes      uint64                   `json:"data_dir_available_bytes,omitempty"`
	CurrentGeneration          int64                    `json:"current_generation"`
	EnabledProfileKinds        []string                 `json:"enabled_profile_kinds"`
	RuntimeProfileSemantics    []RuntimeProfileSemantic `json:"runtime_profile_semantics"`
}

type ProfileAnalysisCommit added in v1.4.0

type ProfileAnalysisCommit struct {
	ProfileAnalysisCurrent
	PreviousCommitSequence uint64 `json:"previous_commit_sequence,omitempty"`
	PreviousCommitFile     string `json:"previous_commit_file,omitempty"`
}

type ProfileAnalysisCurrent added in v1.4.0

type ProfileAnalysisCurrent struct {
	SchemaVersion  int              `json:"schema_version"`
	AnalysisID     string           `json:"analysis_id"`
	ArtifactID     string           `json:"artifact_id"`
	CommitSequence uint64           `json:"commit_sequence"`
	SnapshotSHA256 string           `json:"snapshot_sha256"`
	JSONFile       string           `json:"json_file"`
	JSONSHA256     string           `json:"json_sha256"`
	HTMLFile       string           `json:"html_file"`
	HTMLSHA256     string           `json:"html_sha256"`
	CommitFile     string           `json:"commit_file"`
	Renderer       RendererIdentity `json:"renderer"`
}

type ProfileAnalysisPublishRequest added in v1.4.0

type ProfileAnalysisPublishRequest struct {
	ExpectedCurrentArtifactID string                         `json:"expected_current_artifact_id"`
	Analysis                  profilemodel.ProfileAnalysisV1 `json:"analysis"`
}

type ProfileAnalysisPublishResponse added in v1.4.0

type ProfileAnalysisPublishResponse struct {
	AnalysisID        string            `json:"analysis_id"`
	ArtifactID        string            `json:"artifact_id"`
	CommitSequence    uint64            `json:"commit_sequence"`
	JSONFile          string            `json:"json_file"`
	HTMLFile          string            `json:"html_file"`
	CurrentArtifactID string            `json:"current_artifact_id"`
	Renderer          RendererIdentity  `json:"renderer"`
	Visibility        string            `json:"visibility"`
	Durability        safefs.Durability `json:"durability"`
}

type ProfileCapture added in v1.2.0

type ProfileCapture struct {
	RunID string       `json:"run_id"`
	Epoch uint64       `json:"epoch"`
	Point ProfilePoint `json:"point"`
	Kind  string       `json:"kind"`
	// File is the published ".pprof" name, empty when nothing was published.
	File   string `json:"file,omitempty"`
	SHA256 string `json:"sha256,omitempty"`
	// Sidecar is this record's own file name, so a manifest entry can be
	// followed back to the record on disk.
	Sidecar  string `json:"sidecar"`
	OpenGate string `json:"open_gate,omitempty"`
	// Orphan marks an artifact whose run never reached a closing boundary. It
	// is written into the record rather than left to inference, because a lone
	// opening profile is otherwise indistinguishable from half of a pair whose
	// other half has not been taken yet.
	Orphan bool `json:"orphan,omitempty"`

	// The reference point this capture is measured from, copied from the
	// coordinator's boundary record. A boundary is an interval rather than an
	// instant, so the measured spreads travel with it and form the uncertainty
	// floor under every residual below. Legacy providers leave them zero, which
	// means "not reported", not "measured as zero".
	RefPhase         string    `json:"ref_phase"`
	RefAt            time.Time `json:"ref_at,omitzero"`
	RefSpreadNs      int64     `json:"ref_spread_ns"`
	BoundaryAt       time.Time `json:"boundary_at,omitzero"`
	BoundarySpreadNs int64     `json:"boundary_spread_ns"`

	// The measured capture instants. LagFromRefNs is the distance from the
	// boundary to the moment the write actually began, which is the number the
	// residual error is built out of.
	StartedAt    time.Time `json:"started_at,omitzero"`
	FinishedAt   time.Time `json:"finished_at,omitzero"`
	LagFromRefNs int64     `json:"lag_from_ref_ns"`
	DurationNs   int64     `json:"duration_ns"`
	Bytes        int64     `json:"bytes"`

	Status string `json:"status"`
	Code   string `json:"code,omitempty"`
	Err    string `json:"err,omitempty"`
}

ProfileCapture is one profile file's record: what was captured, when, and how far after the boundary it claims to bracket. It is the content of the ".meta.json" sidecar written next to every artifact.

The sidecar is the durable primary record. An opening capture is written at reset, long before any snapshot exists to hold a manifest, so the sidecar is the only place the opening moment can survive a process that never finishes the run.

type ProfileExpectation added in v1.4.0

type ProfileExpectation struct {
	Kind   string                 `json:"kind"`
	Mode   string                 `json:"mode"`
	Status string                 `json:"status,omitempty"`
	Code   string                 `json:"code,omitempty"`
	Inputs []ProfileExpectedInput `json:"inputs"`
}

type ProfileExpectedInput added in v1.4.0

type ProfileExpectedInput struct {
	Kind  string `json:"kind"`
	Point string `json:"point"`
	File  string `json:"file"`
}

type ProfileManifest added in v1.2.0

type ProfileManifest struct {
	RunID    string           `json:"run_id"`
	Epoch    uint64           `json:"epoch"`
	Validity string           `json:"validity,omitempty"`
	Captures []ProfileCapture `json:"captures,omitempty"`
	// Pairs holds only the kinds whose two halves both exist. A kind with one
	// half is deliberately absent: a difference cannot be taken from it, and
	// listing it would invite the reader to try.
	Pairs    []ProfilePair        `json:"pairs,omitempty"`
	Expected []ProfileExpectation `json:"expected,omitempty"`
	// CPU is the separately owned interval profile. Unlike Captures/Pairs it
	// has one run-aligned input rather than cumulative open/close halves.
	CPU                *CPUIntervalCapture           `json:"cpu,omitempty"`
	Trace              *TraceIntervalCapture         `json:"trace,omitempty"`
	CPULabelDictionary *CPULabelDictionary           `json:"cpu_label_dictionary,omitempty"`
	Executable         *buildinfo.ExecutableIdentity `json:"executable,omitempty"`
}

ProfileManifest is a run's whole profile record: every capture attempted at either boundary, and the pairs that can actually be differenced.

type ProfilePair added in v1.2.0

type ProfilePair struct {
	Kind        string `json:"kind"`
	OpenFile    string `json:"open_file"`
	CloseFile   string `json:"close_file"`
	OpenSHA256  string `json:"open_sha256"`
	CloseSHA256 string `json:"close_sha256"`
	OpenGate    string `json:"open_gate,omitempty"`
	// RunSpanNs is the distance between the two boundaries themselves.
	RunSpanNs int64 `json:"run_span_ns"`
	// HeadLossNs is the run's beginning that the difference does not contain.
	HeadLossNs int64 `json:"head_loss_ns"`
	// TailExcessNs is the post-boundary tail that the difference does contain.
	TailExcessNs int64 `json:"tail_excess_ns"`
	// ApproxErrorNs is HeadLossNs + TailExcessNs: the total by which the
	// difference is not the run.
	ApproxErrorNs int64  `json:"approx_error_ns"`
	DiffCommand   string `json:"diff_command"`
}

ProfilePair is one kind's difference over a run: the two artifacts plus the measured error in treating their difference as the run.

It is an approximation and says so. The difference starts a little after the run does (HeadLossNs, not included) and ends a little after the run ends (TailExcessNs, included), because both halves are taken by the caller after the coordinator has already fixed the boundary.

func (ProfilePair) Lagging added in v1.2.0

func (p ProfilePair) Lagging() bool

Lagging reports whether either half of the pair was taken too far from the boundary it names. The Runs detail page and the health verdict both call this, so the badge on the page and the entry in health can never disagree.

func (ProfilePair) Notes added in v1.2.0

func (p ProfilePair) Notes() []string

Notes returns the sentences the Runs detail page prints under a pair.

The approximation notice is unconditional. A small residual is still a residual, and a reader who sees the notice only on bad runs will read its absence as "this one is exact", which no pair ever is.

func (ProfilePair) ResidualText added in v1.2.0

func (p ProfilePair) ResidualText() string

ResidualText renders the pair's residual error for the Runs detail page.

type ProfilePoint added in v1.2.0

type ProfilePoint string

ProfilePoint names the run boundary a runtime profile was captured at. A mutex, block or heap profile is process-wide and cumulative, so a single file says nothing about a run: only the difference between the two boundaries does, and the point is what tells them apart.

const (
	// ProfilePointOpen is the capture taken as the run opens.
	ProfilePointOpen ProfilePoint = "open"
	// ProfilePointClose is the capture taken as the run's boundary is frozen.
	ProfilePointClose ProfilePoint = "close"
)

type Provider

type Provider struct {
	SQL sqlSnapshotter
	// SQLGeneration and RotateSQL opt into atomic generation boundaries. They
	// are separate callbacks so simple aggregation tables remain usable in
	// tests and custom integrations.
	SQLGeneration func() int64
	RotateSQL     func() (generation int64, entries []agg.Entry)
	// RunGenerationManaged is shorthand for custom providers whose SQL, HTTP,
	// and Counters generations are all owned by StartRun. The per-collector
	// flags below let production preserve that guarantee when only a subset
	// registered successfully.
	RunGenerationManaged      bool
	SQLGenerationManaged      bool
	HTTPGenerationManaged     bool
	CountersGenerationManaged bool
	RedisGenerationManaged    bool
	FlowGenerationManaged     bool
	FlowSource                string
	Health                    *health.Registry
	HTTP                      httpCollector
	AccessLog                 accessLogCollector
	AccessLogQuiet            time.Duration
	AccessLogPoll             time.Duration
	// AccessLogGenerationManaged says the access log's generation adapter is
	// registered with the run coordinator, so the coordinator's
	// BeginBoundary → Drain → Release cycle owns the aggregate's lifetime.
	//
	// POST /reset must then keep its hands off the legacy Snapshot()+Reset()
	// pair. Reset re-opens the log at the current end of file, drops the
	// aggregate and zeroes the health counters the drain's file-replacement
	// guard reads; running it between a closing boundary and that boundary's
	// drain leaves the drain nothing to seal, and the finished run's
	// access-log section silently comes out empty.
	AccessLogGenerationManaged bool
	CollectTimeout             time.Duration
	// InspectionTimeout bounds the context passed to DB and Advisor callbacks.
	InspectionTimeout time.Duration
	Proc              processCollector
	// ProcRunManaged says Proc is registered with the run coordinator. Its
	// reset and final snapshot then happen inside StartRun/FinishRun for both
	// the HTTP and embedded ResetNow entry points.
	ProcRunManaged bool
	// DB captures the database schema (tables/indexes). Called at handler
	// startup and on every reset so each generation records the pre-run state.
	DB func(context.Context) *dbinspect.Schema
	// DBCapabilities returns credential-free, per-target support states.
	DBCapabilities func() []dbcap.Target
	// PeerResults returns the sealed, host-by-host multi-host evidence. Values
	// are displayed separately and are never summed across machines.
	PeerResults func() []multihost.PeerResult
	// Advisor reports well-known settings that are not configured. Captured
	// alongside the DB schema at startup and on every reset.
	Advisor func(context.Context) []advisor.Check
	// CacheTelemetry is evaluated at snapshot time so application cache
	// hit/miss/eviction counters can match the measured interval.
	CacheTelemetry func() (*advisor.CacheTelemetry, error)
	// QUICTelemetry is evaluated at snapshot time so packet counters can match
	// the completed benchmark interval rather than handler startup.
	QUICTelemetry func() (*advisor.QUICTelemetry, error)
	// ProtocolTrafficClientFacing is false when a CDN/LB terminates the client
	// connection before the locally collected access log.
	ProtocolTrafficClientFacing *bool
	// Counters exposes user-defined counters (isutools.Count). Reset per
	// generation.
	Counters interface {
		Snapshot() []counters.Entry
		Reset()
	}
	// Redis exposes sanitized command-only latency aggregates.
	Redis interface {
		Snapshot() []redisstats.Entry
		Reset()
	}
	// Flow exposes proxy-independent middleware journeys.
	Flow interface {
		Snapshot() flowstats.Snapshot
		Reset()
	}
	// DataDir persists snapshots for the dashboard history ("" = disabled).
	DataDir    string
	Executable *buildinfo.ExecutableIdentity
	// AdminAudit receives bounded structured audit records for /save failures
	// and publication. Request values and underlying error strings are omitted.
	AdminAudit func(AdminAudit)
	// ProfileAnalysis enables the opt-in derived analysis publication endpoint.
	// Original snapshot bytes remain immutable regardless of this setting.
	ProfileAnalysis bool
	// PprofDuration > 0 captures a CPU profile for that long after every
	// reset (i.e. covering the benchmark), stored in DataDir (0 = disabled).
	PprofDuration time.Duration
	// CPUProfiles is the process-wide managed CPU profiler owner. Nil preserves
	// the standalone fixed-duration compatibility path.
	CPUProfiles CPUCaptureCoordinator
	// CPUProfileMode is "run", "fixed", or empty/off.
	CPUProfileMode string
	// TraceCapture is the optional, run-aligned execution trace owner. It is
	// nil by default and must not be configured with another managed profiler.
	TraceCapture TraceCaptureCoordinator
	// StartRun opens a measurement run at the reset boundary and names it in
	// the reset response. Nil keeps the legacy behaviour, in which a reset
	// only rotates the collector generations and no run id exists.
	//
	// A failure is not fatal to the reset: the generations have already been
	// rotated by the time it is called, and refusing to answer would leave the
	// bench script unable to proceed with measurements that are, in fact,
	// running.
	StartRun func(ctx context.Context) (RunStart, error)
	// FinishRun fixes the closing boundary of the run in flight and returns as
	// soon as that boundary exists. POST /finish calls it and answers 202:
	// draining and snapshot building continue in the background, and making
	// the caller wait for them would put snapshot-building time inside the
	// measured window of whatever runs next.
	//
	// Nil leaves POST /finish unavailable, which is the legacy behaviour of a
	// transport wired without a run coordinator.
	FinishRun func(ctx context.Context) (RunFinish, error)
	// CompleteRun finishes the run in flight, waits for its immutable
	// snapshot, and acknowledges it. POST /save calls it before rendering, so
	// the persisted report describes the interval the run measured rather than
	// whatever the live collectors happen to hold after their generations were
	// frozen.
	//
	// A process that never opened a run must report the zero RunFinish and no
	// error: /save predates the run lifecycle and has to keep working without
	// one.
	CompleteRun func(ctx context.Context) (RunFinish, error)
	// AbortRun abandons the run in flight and fences its background worker.
	// POST /abort is idempotent and publishes no snapshot; profile artifacts
	// already captured at the opening boundary are marked as orphans.
	AbortRun func(ctx context.Context) (RunAbort, error)
	// Sections supplies the completed run's collector sections keyed by
	// collector name, as produced by the run coordinator. Unknown keys and
	// unexpected types are ignored, so a collector can be added on one side of
	// the wiring before the other catches up.
	Sections func() map[string]any
	// RunSnapshot supplies the same sections together with the lifecycle
	// evidence that makes a completed run auditable. When set it supersedes
	// Sections; the older callback remains for custom-provider compatibility.
	RunSnapshot func() *RunSnapshot
	// Timeline resolves the bounded, run/epoch-aligned phase analysis. Nil is
	// the default-off compatibility path.
	Timeline func(runID string, epoch uint64) *timeline.Section
	// RuntimeProfiles lists the runtime profiles ("mutex", "block", "heap",
	// "allocs", "goroutine", "threadcreate", or "goroutineleak")
	// captured at a run boundary, in capture order. Empty — the default —
	// captures nothing. The rates themselves are process-wide runtime
	// settings owned by the caller; this package only writes what it is told
	// is enabled, so a profile whose rate is zero must not appear here.
	RuntimeProfiles []string
}

Provider supplies the collectors to render. Nil fields are skipped.

type RendererIdentity added in v1.4.0

type RendererIdentity struct {
	Version        string `json:"version"`
	TemplateSHA256 string `json:"template_sha256"`
	HTMLSHA256     string `json:"html_sha256"`
}

type RunAbort added in v1.2.0

type RunAbort struct {
	RunID     string    `json:"run_id,omitempty"`
	Epoch     uint64    `json:"epoch,omitempty"`
	Reason    string    `json:"reason,omitempty"`
	Detached  bool      `json:"detached,omitempty"`
	AbortedAt time.Time `json:"aborted_at,omitzero"`
	Partial   []string  `json:"partial,omitempty"`
}

RunAbort is the transport projection of the coordinator's abort result. POST /abort itself answers 204, but the handler needs this record to orphan the right profile pair and report the run id back in its header.

type RunCollectorBoundary added in v1.2.0

type RunCollectorBoundary struct {
	Name      string    `json:"name"`
	Kind      string    `json:"kind"`
	Required  bool      `json:"required"`
	Phase     string    `json:"phase"`
	At        time.Time `json:"at,omitzero"`
	Committed bool      `json:"committed"`
	Code      string    `json:"code,omitempty"`
	Err       string    `json:"err,omitempty"`
	Dropped   bool      `json:"dropped,omitempty"`
}

RunCollectorBoundary records one collector operation at a run boundary.

type RunFinish added in v1.2.0

type RunFinish struct {
	// RunID names the run whose boundary was fixed. Empty means no run was in
	// flight, which is not an error: the save/collect loop predates runs.
	RunID string `json:"run_id,omitempty"`
	// Epoch is the coordinator fencing token for this closing boundary.
	Epoch uint64 `json:"epoch,omitempty"`
	// Validity is the run's data-quality verdict ("valid", "partial",
	// "invalid"), copied verbatim like RunStart.Validity.
	Validity string `json:"validity,omitempty"`
	// State is normally omitted. Recovery saves set it to the terminal state
	// that prevented a normal finish, so an expired run can never look like a
	// successfully completed interval.
	State string `json:"state,omitempty"`
	// StartedAt is copied from the opening boundary for a recovery save. Normal
	// completions obtain the same value from RunSnapshot instead.
	StartedAt time.Time `json:"started_at,omitzero"`
	// AcceptedAt is the measured moment the closing boundary was fixed. It is
	// the end of the interval every section of this run describes.
	AcceptedAt time.Time `json:"accepted_at,omitzero"`
	// Recovered marks the explicit fail-open path used when StartedTTL already
	// abandoned the run before /save arrived. RecoveryReason is the stable
	// lifecycle reason (currently "started-ttl").
	Recovered      bool   `json:"recovered,omitempty"`
	RecoveryReason string `json:"recovery_reason,omitempty"`
	// GenerationWindow and BoundaryWindow preserve the coordinator's measured
	// uncertainty at the closing boundary for profile residual accounting.
	GenerationWindow BoundaryWindow `json:"generation_window,omitzero"`
	BoundaryWindow   BoundaryWindow `json:"boundary_window,omitzero"`
}

RunFinish is the record of a run's closing boundary, as reported by Provider.FinishRun and Provider.CompleteRun.

type RunInfo added in v1.2.0

type RunInfo struct {
	RunID            string                 `json:"run_id"`
	Epoch            uint64                 `json:"epoch"`
	Validity         string                 `json:"validity"`
	State            string                 `json:"state,omitempty"`
	Recovered        bool                   `json:"recovered,omitempty"`
	RecoveryReason   string                 `json:"recovery_reason,omitempty"`
	Trigger          string                 `json:"trigger,omitempty"`
	Collectors       []RunCollectorBoundary `json:"collectors,omitempty"`
	GenerationWindow BoundaryWindow         `json:"generation_window"`
	BoundaryWindow   BoundaryWindow         `json:"boundary_window"`
	StartedAt        time.Time              `json:"started_at,omitzero"`
	FinishedAt       time.Time              `json:"finished_at,omitzero"`
}

RunInfo is the immutable lifecycle envelope persisted with a report.

type RunSnapshot added in v1.2.0

type RunSnapshot struct {
	Info     RunInfo
	Sections map[string]any
}

RunSnapshot is the provider-side form of a completed run. Sections remain top-level in the report while Info is persisted under Meta.Run.

type RunStart added in v1.2.0

type RunStart struct {
	// RunID is the coordinator's run identifier, echoed in the reset response
	// so a bench script can name the run it started.
	RunID string
	// Epoch is the coordinator fencing token. It prevents a delayed boundary
	// artifact from being attached to a newer incarnation of the same run id.
	Epoch uint64
	// State is the coordinator state at the completed opening boundary. A
	// managed reset is allowed to begin profiling only for "started"; notably,
	// a required collector failure returns "aborted" with a nil error.
	State string
	// StartedAt is the opening boundary's moment. Boundary artifacts are named
	// after it rather than after the moment they are written, so an opening
	// and a closing artifact of one run share a filename prefix.
	StartedAt time.Time
	// Validity is the run's data-quality verdict ("valid", "partial",
	// "invalid"). It is a plain string because the transport copies it
	// verbatim and never branches on it.
	Validity string
	// GenerationWindow and BoundaryWindow preserve the coordinator's measured
	// uncertainty at the opening boundary for profile residual accounting.
	GenerationWindow BoundaryWindow
	BoundaryWindow   BoundaryWindow
}

RunStart identifies the measurement run a reset opened.

type RuntimeProfileSemantic added in v1.7.0

type RuntimeProfileSemantic struct {
	Kind         string   `json:"kind"`
	Available    bool     `json:"available"`
	Mode         string   `json:"mode"`
	CapturePoint string   `json:"capture_point"`
	SampleTypes  []string `json:"sample_types"`
	Approximate  bool     `json:"approximate"`
	Interference string   `json:"interference,omitempty"`
}

RuntimeProfileSemantic is the stable contract for each runtime profile. Interval profiles are close-boundary snapshots; cumulative profiles require both boundaries and include measured head/tail approximation.

func RuntimeProfileSemantics added in v1.7.0

func RuntimeProfileSemantics() []RuntimeProfileSemantic

RuntimeProfileSemantics reports runtime availability instead of assuming a profile added by a newer Go release exists in the running binary.

type SafeLabelTuple added in v1.4.0

type SafeLabelTuple struct {
	TupleID  string `json:"tuple_id"`
	Method   string `json:"method"`
	Route    string `json:"route"`
	Scenario string `json:"scenario,omitempty"`
	Region   string `json:"region,omitempty"`
	Overflow bool   `json:"overflow,omitempty"`
}

type SaveResponse added in v1.4.0

type SaveResponse struct {
	File                  string `json:"file"`
	SnapshotBase          string `json:"snapshot_base"`
	SnapshotFile          string `json:"snapshot_file"`
	SnapshotSchemaVersion int    `json:"snapshot_schema_version"`
	RunID                 string `json:"run_id,omitempty"`
	SnapshotSHA256        string `json:"snapshot_sha256"`
	Visibility            string `json:"visibility"`
	Durability            string `json:"durability"`
}

SaveResponse pins the exact raw snapshot bytes at the moment /save publishes them. Callers can put this hash into an ABBA ledger without a later fetch racing retention or another generation.

type Snapshot

type Snapshot struct {
	Meta               Meta                    `json:"meta"`
	DB                 *dbinspect.Schema       `json:"db,omitempty"`
	DBCapabilities     []dbcap.Target          `json:"db_capabilities,omitempty"`
	DBCapabilityMatrix []dbcap.MatrixRow       `json:"db_capability_matrix,omitempty"`
	Advisor            []advisor.Check         `json:"advisor,omitempty"`
	Counters           []counters.Entry        `json:"counters,omitempty"`
	Redis              []redisstats.Entry      `json:"redis,omitempty"`
	Flow               *flowstats.Snapshot     `json:"flow,omitempty"`
	FlowSource         string                  `json:"flow_source,omitempty"`
	Connections        *httpstats.ConnSnapshot `json:"connections,omitempty"`
	SQL                []agg.Entry             `json:"sql"`
	HTTP               httpstats.Snapshot      `json:"http,omitempty"`
	AccessLog          *accesslog.Snapshot     `json:"accesslog,omitempty"`
	Proc               *procstats.Snapshot     `json:"proc,omitempty"`
	Timeline           *timeline.Section       `json:"timeline,omitempty"`

	// The sections below come from the run coordinator's baseline collectors
	// rather than from a live collector read, so they describe the interval
	// between two run boundaries and are absent until a run has completed.
	// Every one of them is additive and omitempty: a v1.0 reader of this JSON
	// is unaffected by their presence.
	//
	// The JSON keys are the collector names the coordinator registers under,
	// so a section can be traced from the snapshot back to the collector that
	// filled it without a translation table.
	Host    *hoststats.Section     `json:"hoststats,omitempty"`
	Network *netstats.NetworkStats `json:"network,omitempty"`
	SQLRows *sqlrows.Section       `json:"sqlrows,omitempty"`
	DBPool  []dbpool.Entry         `json:"dbpool,omitempty"`
	// QueryPlan holds the EXPLAIN output captured in the run's enrich phase.
	// It is filled from the same section map as the others rather than from a
	// live read, which is what keeps a dashboard refresh from putting EXPLAIN
	// statements on the measured database.
	QueryPlan *queryplan.Section     `json:"queryplan,omitempty"`
	Peers     []multihost.PeerResult `json:"peers,omitempty"`
}

Snapshot is the complete state of all measurements at one point in time.

func (Snapshot) FlowVisualization added in v1.7.0

func (s Snapshot) FlowVisualization() *flowviz.Snapshot

FlowVisualization follows the same single-source contract as UserFlows. It never combines middleware and proxy observations from one request.

func (Snapshot) ScenarioStories added in v1.6.0

func (s Snapshot) ScenarioStories() []accesslog.StoryEntry

ScenarioStories enforces the configured source. Auto mode prefers the proxy-independent middleware collector and falls back to legacy proxy-log labels only when middleware produced no observations.

func (Snapshot) UserFlows added in v1.6.0

func (s Snapshot) UserFlows() []accesslog.FlowEntry

UserFlows follows the same single-source preference as ScenarioStories.

type TraceCaptureCoordinator added in v1.7.0

type TraceCaptureCoordinator interface {
	StartRun(TraceStartRequest) TraceStartResult
	RequestStop(TraceStopRequest) TraceStopTicket
	Await(TraceStopTicket, context.Context) TraceCaptureStatus
	Manifest(runID string, epoch uint64) *TraceIntervalCapture
}

TraceCaptureCoordinator is the transport-facing owner of one bounded runtime execution trace. Stop must be non-blocking.

type TraceCaptureStatus added in v1.7.0

type TraceCaptureStatus struct {
	State string
	Code  string
}

type TraceIntervalCapture added in v1.7.0

type TraceIntervalCapture struct {
	RunID           string    `json:"run_id"`
	Epoch           uint64    `json:"epoch"`
	CaptureID       string    `json:"capture_id"`
	ExpectedFile    string    `json:"expected_file"`
	File            string    `json:"file,omitempty"`
	SHA256          string    `json:"sha256,omitempty"`
	Bytes           int64     `json:"bytes,omitempty"`
	Sidecar         string    `json:"sidecar,omitempty"`
	SidecarSHA256   string    `json:"sidecar_sha256,omitempty"`
	Status          string    `json:"status"`
	Code            string    `json:"code,omitempty"`
	BoundaryStart   time.Time `json:"boundary_start,omitzero"`
	BoundaryFinish  time.Time `json:"boundary_finish,omitzero"`
	StartCompleted  time.Time `json:"start_completed_at,omitzero"`
	StopCompleted   time.Time `json:"stop_completed_at,omitzero"`
	StopReason      string    `json:"stop_reason,omitempty"`
	RequestedSpanNs int64     `json:"requested_span_ns"`
	CaptureSpanNs   int64     `json:"capture_span_ns"`
	HeadLossNs      int64     `json:"head_loss_ns"`
	TailExcessNs    int64     `json:"tail_excess_ns"`
	Complete        bool      `json:"complete"`
}

type TraceStartRequest added in v1.7.0

type TraceStartRequest struct {
	RunID      string
	Epoch      uint64
	State      string
	Validity   string
	BoundaryAt time.Time
}

type TraceStartResult added in v1.7.0

type TraceStartResult struct {
	RunID     string
	Epoch     uint64
	CaptureID string
	State     string
	Code      string
}

type TraceStopRequest added in v1.7.0

type TraceStopRequest struct {
	RunID      string
	Epoch      uint64
	Reason     string
	BoundaryAt time.Time
	Abort      bool
}

type TraceStopTicket added in v1.7.0

type TraceStopTicket struct {
	RunID     string
	Epoch     uint64
	CaptureID string
	State     string
	Code      string
}

Jump to

Keyboard shortcuts

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