sysmtee

package
v0.0.21 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package sysmtee writes the system-metrics plane into `boxer.facts`.

It is ADR-0090 P5 — the persistence tee reserved when the plane was designed and left unbuilt until something wanted history — in the shape ADR-0184 settles: a subscriber, not a fork of the producer. It consumes the same bundles any other consumer sees and writes them through the generated record store in github.com/stergiotis/boxer/public/keelson/runtime/sysmfacts. Producer and consumers are untouched by its presence.

It re-models rather than tees bytes

ADR-0090 §SD4 anticipated a tee that forwarded the wire bytes unchanged, which was possible while the wire was expected to be the facts codec. The plane shipped a CBOR codec instead and the swap never happened, so this decodes to github.com/stergiotis/boxer/public/observability/sysmetrics/sysmsnap structs and builds rows from them. That is the honest cost of the interim codec, not a design choice made here.

Losing samples is preferred to blocking the plane

The bus delivers on its own goroutine and a record store is single-goroutine, so bundles hand off to an owner goroutine through a bounded queue. When the queue is full — ClickHouse slow or down — the incoming bundle is dropped and counted rather than blocking delivery. The metric plane is one-way and unacknowledged by design (ADR-0090 §SD4 rejects JetStream for it), so a gap in stored history is the correct failure: the alternative is a stalled subscription that also delays every other consumer on an in-process bus.

Append-only

Every kind is append-shaped and the store has no state view to misuse — see github.com/stergiotis/boxer/public/keelson/runtime/sysmfacts. Re-writing a descriptor row is therefore harmless, which is what makes "on first sight of a host" a cheap heuristic rather than a correctness requirement.

Index

Constants

View Source
const (
	DefaultQueueDepth    = 64
	DefaultFlushInterval = 10 * time.Second
	DefaultFlushRows     = 256
)

Defaults for Options. The flush interval is the dominant one: it is the window of samples lost if the process dies, and the rate at which small inserts reach ClickHouse.

Variables

View Source
var PackageProps = packageprops.Props{
	WASMWASI:         packageprops.WASMBlocked,
	WASMJS:           packageprops.WASMBlocked,
	WASMFreestanding: packageprops.WASMBlocked,
}

PackageProps records this package's curated properties (ADR-0080). Blocked: it composes the generated record store, which pulls in the arrow and ClickHouse-executor stack.

Functions

This section is empty.

Types

type Options

type Options struct {
	// Bus is the metric plane to subscribe on — the same client the scraper
	// publishes through when co-located.
	Bus app.BusI
	// Store is the facts-bound record store rows are written to. The tee takes
	// ownership: it is used only from the tee's own goroutine, satisfying the
	// single-goroutine contract, and Close is the caller's after Stop returns.
	Store *sysmfacts.SysmetricsStore
	// Host is the token stored on every row.
	//
	// It is configured rather than read from the message because the host lives
	// in the subject and [sysmetricsbus.ConsumerOptions.Handler] receives only
	// the snapshot. A tee co-located with its scraper knows the token; a
	// standalone sink subscribing to several hosts would need the subject in
	// the handler, which is a sysmetricsbus change deferred until such a sink
	// exists (ADR-0184 §SD8).
	Host string
	// Subject defaults to this host's bundle subject. Set it to the wildcard
	// only when every publisher on it is the host named above.
	Subject string
	// QueueDepth bounds the handoff between the bus goroutine and the writer.
	// Zero takes DefaultQueueDepth.
	QueueDepth int
	// FlushInterval bounds how long a row waits before becoming durable. Zero
	// takes DefaultFlushInterval.
	FlushInterval time.Duration
	// FlushRows flushes early once this many rows are buffered, so a fast plane
	// does not build an unbounded batch between ticks. Zero takes
	// DefaultFlushRows.
	FlushRows int
	// PersistProcCmd opts into storing process command lines, user names and
	// uid/gid — the ADR-0090 §SD8 sensitive class, which
	// [sysmfacts.SysProcCmd] keeps in its own kind.
	//
	// Off by default, and deliberately not merely a masking flag: §SD8's
	// accepted exposure was scoped to a single-tenant, localhost-bound bus,
	// where a command line lives as long as its subscriber. A row in
	// `boxer.facts` outlives the process, is readable by anything with database
	// access, and is backed up with everything else. The masking switch §SD8
	// defers does not exist, so not writing is the only control that currently
	// enforces anything.
	//
	// The rest of the process table — pids, names, cpu, memory, the ADR-0126
	// topology marks — is stored either way.
	PersistProcCmd bool
	Log            zerolog.Logger
}

Options configures a tee. Bus, Store and Host are required.

type Stats

type Stats struct {
	// Bundles received from the plane.
	Bundles uint64
	// Dropped bundles — the queue was full when they arrived.
	Dropped uint64
	// Rows handed to the store.
	Rows uint64
	// Flushed rows made durable.
	Flushed uint64
	// FlushErrors counts failed flushes. The store keeps the batch pending and
	// the next flush reships it, so this is not a row-loss count.
	FlushErrors uint64
}

Stats reports what the tee has done. Counters are cumulative and safe to read from any goroutine.

type Tee

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

Tee is a running subscriber. Use Start to build one.

func Start

func Start(opts Options) (inst *Tee, err error)

Start subscribes and begins writing. The returned Tee runs until Stop.

func (*Tee) Stats

func (inst *Tee) Stats() (s Stats)

Stats snapshots the counters.

func (*Tee) Stop

func (inst *Tee) Stop() (err error)

Stop unsubscribes, drains what is already queued, and makes it durable. Safe to call more than once.

Jump to

Keyboard shortcuts

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