query

package
v0.1.15 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: Apache-2.0 Imports: 30 Imported by: 0

Documentation

Index

Constants

View Source
const (
	RenderLogs  = "logs"
	RenderTrace = "trace"
	RenderTop   = "top"
)

Render values the frontend keys presentation off (x-clicky-render): RenderLogs selects the canonical LogsTable; RenderTrace and RenderTop select the session-backed live views and are derived from the profile kind when Render is not set explicitly.

View Source
const (
	// DefaultMaxDuration bounds a trace or top session when the spec omits one.
	DefaultMaxDuration = 15 * time.Minute

	// DefaultMaxEvents caps a trace session's event ring buffer.
	DefaultMaxEvents = 10000

	// DefaultTopInterval is the sampling interval when a TopSpec omits one.
	DefaultTopInterval = 5 * time.Second

	// MinTopInterval is the floor for a TopSpec interval.
	MinTopInterval = time.Second
)
View Source
const DefaultSampleLimit = 100

Variables

View Source
var CommonFields = map[string]func(ctx context.Context, tx *gorm.DB, val string) (*gorm.DB, error){
	"limit": func(ctx context.Context, tx *gorm.DB, val string) (*gorm.DB, error) {
		if i, err := strconv.Atoi(val); err == nil {
			return tx.Limit(i), nil
		} else {
			return nil, err
		}
	},
	"sort": func(ctx context.Context, tx *gorm.DB, sort string) (*gorm.DB, error) {
		return tx.Order(clause.OrderByColumn{Column: clause.Column{Name: sort}}), nil
	},
	"offset": func(ctx context.Context, tx *gorm.DB, val string) (*gorm.DB, error) {
		if i, err := strconv.Atoi(val); err == nil {
			return tx.Offset(i), nil
		} else {
			return nil, err
		}
	},
}

CommonFields provides built-in query field handlers for common operations

View Source
var DateMapper = func(ctx context.Context, val string) (any, error) {
	if expr, err := datemath.Parse(val); err != nil {
		return nil, fmt.Errorf("invalid date '%s': %s", val, err)
	} else {
		return expr.Time(), nil
	}
}

DateMapper maps date expressions (including datemath like "now-7d") to actual time values

View Source
var ErrMaxSessions = errors.New("max sessions reached")

ErrMaxSessions is returned by Add when the active-session cap is reached.

View Source
var JSONPathMapper = func(ctx context.Context, tx *gorm.DB, column string, op grammar.QueryOperator, path string, val string) *gorm.DB {
	if !slices.Contains([]grammar.QueryOperator{grammar.Eq, grammar.Neq}, op) {
		op = grammar.Eq
	}
	values := strings.Split(val, ",")
	for _, v := range values {
		tx = tx.Where(fmt.Sprintf(`TRIM(BOTH '"' from jsonb_path_query_first(%s, '$.%s')::TEXT) %s ?`, column, path, op), v)
	}
	return tx
}

JSONPathMapper handles JSONPath queries against JSONB columns

Functions

func ClickyColumns added in v0.1.15

func ClickyColumns(columns []ColumnDef) []api.ColumnDef

ClickyColumns maps declared profile columns to the shared Clicky column contract. Schema-less callers may pass nil and let a formatter derive fields.

func DecodeOptions added in v0.1.13

func DecodeOptions[T any](opts map[string]any) (T, error)

DecodeOptions decodes a ProviderRequest.Options map into a provider-specific options struct T via a JSON round-trip (T's json tags drive the mapping). Returns the zero T when opts is empty.

func FlushResourceSelectorCache

func FlushResourceSelectorCache()

FlushResourceSelectorCache flushes all resource selector caches

func OrQueries

func OrQueries(db *gorm.DB, queries ...*gorm.DB) *gorm.DB

OrQueries combines multiple gorm queries with OR logic

func ParseFilteringQuery

func ParseFilteringQuery(query string, decodeURL bool) (grammar.FilteringQuery, error)

ParseFilteringQuery parses a filtering query string

func QueryResourceSelectors

func QueryResourceSelectors[T any](
	ctx context.Context,
	queryModel QueryModel,
	selectColumns []string,
	limit int,
	clauses []clause.Expression,
	resourceSelectors ...types.ResourceSelector,
) ([]T, error)

QueryResourceSelectors queries a table using multiple resource selectors. It returns the combined results from all selectors, respecting the limit.

Example usage:

model := QueryModel{
    Table: "my_resources",
    Columns: []string{"id", "name", "type"},
    HasTags: true,
}
results, err := QueryResourceSelectors[MyResource](ctx, model, []string{"id", "name"}, 100, nil, selectors...)

func RegisterProcessor added in v0.1.13

func RegisterProcessor(p Processor)

RegisterProcessor adds p to the global processor registry, keyed by p.Type().

func RegisterProvider added in v0.1.13

func RegisterProvider(p Provider)

RegisterProvider adds p to the global provider registry, keyed by p.Type(). A later registration for the same type replaces the earlier one.

func RegisteredProcessors added in v0.1.13

func RegisteredProcessors() []string

RegisteredProcessors returns the registered processor types, sorted.

func RegisteredProviders added in v0.1.13

func RegisteredProviders() []string

RegisteredProviders returns the registered provider types, sorted.

func SetResourceSelectorClause

func SetResourceSelectorClause(
	ctx context.Context,
	resourceSelector types.ResourceSelector,
	query *gorm.DB,
	queryModel QueryModel,
) (*gorm.DB, error)

SetResourceSelectorClause applies a ResourceSelector to a GORM query. The caller must provide a QueryModel that defines the table structure and capabilities.

Returns the modified query and any error encountered.

func SupportsStreaming added in v0.1.15

func SupportsStreaming(providerType string) bool

SupportsStreaming reports whether the registered provider can open a row cursor without materializing its complete result.

Types

type ColumnDef added in v0.1.13

type ColumnDef struct {
	// Name is the row key this column reads from and the default header label.
	Name string `json:"name" yaml:"name"`

	// Label overrides the column header. Defaults to a prettified Name.
	Label string `json:"label,omitempty" yaml:"label,omitempty"`

	// Type is the semantic type used for formatting. Defaults to string.
	Type ColumnType `json:"type,omitempty" yaml:"type,omitempty"`

	// Kind enables specialized table behavior. In particular, timestamp marks
	// the column used by the table's date-range control.
	Kind ColumnKind `json:"kind,omitempty" yaml:"kind,omitempty"`

	// Format overrides the clicky format string (e.g. "date", "bytes",
	// "duration", "currency"). When empty it is derived from Type.
	Format string `json:"format,omitempty" yaml:"format,omitempty"`

	// Unit is an optional display unit (e.g. "ms", "MiB").
	Unit string `json:"unit,omitempty" yaml:"unit,omitempty"`

	// Width is an optional max display width in characters.
	Width int `json:"width,omitempty" yaml:"width,omitempty"`

	// CEL is an optional expression computing the cell value from the row.
	// The row is exposed as `row` in the CEL environment.
	CEL string `json:"cel,omitempty" yaml:"cel,omitempty"`

	// Hidden excludes the column from rendered output while keeping it available
	// to CEL and processors.
	Hidden bool `json:"hidden,omitempty" yaml:"hidden,omitempty"`
}

ColumnDef declares one output column of a Profile.

func InferSampleColumns added in v0.1.15

func InferSampleColumns(rows []Row) []ColumnDef

InferSampleColumns infers stable, compact ColumnDefs from top-level row keys.

type ColumnKind added in v0.1.15

type ColumnKind string

ColumnKind enables semantic table behavior beyond value formatting.

const (
	ColumnKindTimestamp ColumnKind = "timestamp"
	ColumnKindTags      ColumnKind = "tags"
	ColumnKindStatus    ColumnKind = "status"
)

type ColumnType added in v0.1.13

type ColumnType string

ColumnType is the semantic type of a column. It drives default formatting in the render layer (see render.go) and the clicky-ui contract.

The set mirrors duty/view.ColumnType so view specs port cleanly; it is expanded with format/filter/badge metadata in Phase 2.

const (
	ColumnTypeString    ColumnType = "string"
	ColumnTypeNumber    ColumnType = "number"
	ColumnTypeBoolean   ColumnType = "boolean"
	ColumnTypeDateTime  ColumnType = "datetime"
	ColumnTypeDuration  ColumnType = "duration"
	ColumnTypeBytes     ColumnType = "bytes"
	ColumnTypeStatus    ColumnType = "status"
	ColumnTypeHealth    ColumnType = "health"
	ColumnTypeKeyValue  ColumnType = "key_value"
	ColumnTypeKeyValues ColumnType = "key_values"
	ColumnTypeJSON      ColumnType = "json"
)

type Event added in v0.1.15

type Event struct {
	SessionID string    `json:"sessionId"`
	Sequence  int64     `json:"sequence"`
	Time      time.Time `json:"time"`
	Row       Row       `json:"row,omitempty"`
	Rows      []Row     `json:"rows,omitempty"`
	Error     string    `json:"error,omitempty"`
}

Event is one emission from a session: a single streamed row (trace) or a full snapshot for one tick (top).

type ParamDef added in v0.1.13

type ParamDef struct {
	// Name is the parameter key, referenced in the query as `{{.params.<Name>}}`.
	Name string `json:"name" yaml:"name"`

	// Label is the human-facing name for the FilterBar. Defaults to Name.
	Label string `json:"label,omitempty" yaml:"label,omitempty"`

	// Type drives validation/coercion. Defaults to string.
	Type ParamType `json:"type,omitempty" yaml:"type,omitempty"`

	// Role maps the parameter to a first-class table control. Empty defaults to
	// filter. A profile can rename the pager parameters by assigning limit and
	// offset roles; time-from/time-to form one server-backed date-range picker.
	Role ParamRole `json:"role,omitempty" yaml:"role,omitempty"`

	// Default is used when no value is supplied.
	Default any `json:"default,omitempty" yaml:"default,omitempty"`

	// Options enumerates the allowed values (an enum). When set, a supplied value
	// must be one of these.
	Options []string `json:"options,omitempty" yaml:"options,omitempty"`

	// Required fails execution when no value (and no Default) is supplied.
	Required bool `json:"required,omitempty" yaml:"required,omitempty"`

	// Description is shown as the FilterBar tooltip.
	Description string `json:"description,omitempty" yaml:"description,omitempty"`

	// Template optionally rewrites the resolved value; "{value}" is replaced with
	// the supplied value (e.g. "{value}-api").
	Template string `json:"template,omitempty" yaml:"template,omitempty"`
}

ParamDef declares one server-side filter parameter of a Profile. Supplied values are validated and coerced against the declaration, then exposed to the query template under `params.<Name>` before the provider runs. This mirrors legacy trace-profile params.

func (ParamDef) DisplayLabel added in v0.1.13

func (d ParamDef) DisplayLabel() string

DisplayLabel returns the Label when set, otherwise the Name.

type ParamRole added in v0.1.15

type ParamRole string

ParamRole assigns a profile parameter to a first-class table control. Filter is the default; limit/offset drive the pager and time-from/time-to are paired into the table's date-range control.

const (
	ParamRoleFilter   ParamRole = "filter"
	ParamRoleLimit    ParamRole = "limit"
	ParamRoleOffset   ParamRole = "offset"
	ParamRoleTimeFrom ParamRole = "time-from"
	ParamRoleTimeTo   ParamRole = "time-to"
)

type ParamType added in v0.1.13

type ParamType string

ParamType is the declared type of a Profile parameter. It drives validation, coercion of incoming (string) values, and the per-profile JSON schema.

const (
	ParamTypeString  ParamType = "string"
	ParamTypeNumber  ParamType = "number"
	ParamTypeBoolean ParamType = "boolean"
	ParamTypeDate    ParamType = "date"
	ParamTypeEnum    ParamType = "enum"
)

type Processor added in v0.1.13

type Processor interface {
	// Type is the registry key (e.g. "sqlite.merge", "sqlite.recon").
	Type() string

	// Process transforms in according to spec and returns the new Result.
	Process(ctx context.Context, spec ProcessorSpec, in *Result) (*Result, error)
}

Processor is a post-query step applied to a Result (e.g. sqlite merge, reconciliation). Implementations self-register via RegisterProcessor and are selected by ProcessorSpec.Type. Like providers, processors live in a subpackage that consumers blank-import.

func GetProcessor added in v0.1.13

func GetProcessor(typ string) (Processor, error)

GetProcessor returns the registered Processor for typ, or an error listing the available types.

type ProcessorSpec added in v0.1.13

type ProcessorSpec struct {
	// Type is the registered processor key (e.g. "sqlite.merge", "sqlite.recon").
	Type string `json:"type" yaml:"type"`

	// Config is the processor-specific configuration.
	Config map[string]any `json:"config,omitempty" yaml:"config,omitempty"`
}

ProcessorSpec names a post-query processor and carries its raw config, which the processor decodes for itself.

type Profile added in v0.1.13

type Profile struct {
	// Name identifies the Profile (e.g. "SQL Server trace").
	Name string `json:"profile" yaml:"profile"`

	// Namespace scopes Kubernetes secret/configmap lookups and workload URLs used
	// by inline provider connections. When empty, the caller's namespace is used.
	Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`

	// Provider selects and configures the backend the Profile reads from.
	Provider ProviderConfig `json:"provider" yaml:"provider"`

	// Query is the provider-native query (SQL, PromQL, HTTP path, etc.). It may
	// reference declared params as `{{.params.<name>}}` (or `$(...)`), which are
	// rendered before the provider runs.
	Query string `json:"query,omitempty" yaml:"query,omitempty"`

	// Params declares the server-side filter parameters the Profile accepts. Their
	// resolved values are templated into Query (and context sub-queries) and drive
	// the per-profile FilterBar schema.
	Params []ParamDef `json:"params,omitempty" yaml:"params,omitempty"`

	// Columns declares the output columns in display order. When empty, the
	// provider's raw row keys are used.
	Columns []ColumnDef `json:"columns,omitempty" yaml:"columns,omitempty"`

	// Processors are post-query steps (e.g. sqlite merge/recon) applied in order.
	Processors []ProcessorSpec `json:"processors,omitempty" yaml:"processors,omitempty"`

	// Context defines secondary queries whose single result becomes a named side
	// object on the Result (e.g. Policy, Plan, Integrations).
	Context map[string]SubQuery `json:"context,omitempty" yaml:"context,omitempty"`

	// Output lists the render targets (e.g. table, html, xlsx, json).
	Output []string `json:"output,omitempty" yaml:"output,omitempty"`

	// Render selects how the frontend presents the result. "table" (the default,
	// when empty) uses the generic data table; "logs" maps the columns onto the
	// canonical LogsTable view (timestamp/level/pod/logger/thread/message, plus an
	// optional duration column) for trace/log profiles. Filtering stays server-side
	// via Params regardless of render mode.
	Render string `json:"render,omitempty" yaml:"render,omitempty"`

	// Trace declares the Profile as a long-running streaming session with
	// explicit setup/teardown; the provider must implement StreamProvider.
	// Mutually exclusive with Top.
	Trace *TraceSpec `json:"trace,omitempty" yaml:"trace,omitempty"`

	// Top declares the Profile as interval-sampled: the engine re-executes the
	// query per tick and each snapshot replaces the last. Mutually exclusive
	// with Trace.
	Top *TopSpec `json:"top,omitempty" yaml:"top,omitempty"`
}

Profile is a declarative, CEL-driven view over a data provider. It names the backend to read from, the provider-native query, the output columns (with optional CEL formatting), post-query processors, and named context objects.

A Profile is the unifying abstraction across legacy "trace profiles", duty View specs, and ad-hoc reports.

func (Profile) HasParamRoleName added in v0.1.15

func (p Profile) HasParamRoleName(role ParamRole, name string) bool

HasParamRoleName reports whether name is a profile-declared transport parameter for role.

func (Profile) Kind added in v0.1.15

func (p Profile) Kind() ProfileKind

Kind derives the Profile's execution kind from its Trace/Top blocks.

func (Profile) ParamNameForRole added in v0.1.15

func (p Profile) ParamNameForRole(role ParamRole, fallback string) string

ParamNameForRole returns the first parameter assigned to role, or fallback when the profile uses the built-in transport parameter.

func (Profile) RenderMode added in v0.1.15

func (p Profile) RenderMode() string

RenderMode returns the effective render value: the explicit Render when set, otherwise the profile kind for trace/top profiles, otherwise empty (generic table).

func (Profile) ValidateKind added in v0.1.15

func (p Profile) ValidateKind() error

ValidateKind rejects a Profile that declares both trace and top.

type ProfileKind added in v0.1.15

type ProfileKind string

ProfileKind classifies how a Profile executes: a single-shot query, a long-running trace session, or an interval-sampled top session.

const (
	KindQuery ProfileKind = "query"
	KindTrace ProfileKind = "trace"
	KindTop   ProfileKind = "top"
)

type Provider added in v0.1.13

type Provider interface {
	// Type is the registry key (e.g. "sql", "http", "prometheus").
	Type() string

	// Execute runs req against the backend and returns the raw rows.
	Execute(ctx context.Context, req ProviderRequest) ([]Row, error)
}

Provider executes a Profile's query against a single backend type and returns the raw rows. Implementations register themselves via RegisterProvider and are selected by ProviderConfig.Type.

func GetProvider added in v0.1.13

func GetProvider(typ string) (Provider, error)

GetProvider returns the registered Provider for typ, or an error listing the available types when none is registered.

type ProviderConfig added in v0.1.13

type ProviderConfig struct {
	// Type is the registered provider key (e.g. "sql", "http", "prometheus").
	Type string `json:"type" yaml:"type"`

	// Connection references a connection (connection://name) or an inline DSN/URL.
	Connection string `json:"connection,omitempty" yaml:"connection,omitempty"`

	// Options carries provider-specific knobs.
	Options map[string]any `json:"options,omitempty" yaml:"options,omitempty"`
}

ProviderConfig selects a registered Provider and supplies the connection and provider-specific options.

type ProviderRequest added in v0.1.13

type ProviderRequest struct {
	// Connection references a connection (connection://name) or an inline DSN/URL.
	Connection string

	// Query is the provider-native query string.
	Query string

	// Options carries provider-specific knobs from ProviderConfig.Options.
	Options map[string]any

	// MaxRows is an execution hint for bounded callers such as an interactive
	// page. Streaming providers may use it to avoid opening a backend cursor
	// when one finite request can satisfy the caller. Zero means unbounded.
	MaxRows int
}

ProviderRequest is the resolved input handed to a Provider by the engine.

type QueryModel

type QueryModel struct {
	// Table name
	Table string

	// Custom functions to map fields to clauses
	// Example: map["custom_field"] = func(ctx, tx, val) { ... custom query logic ... }
	Custom map[string]func(ctx context.Context, tx *gorm.DB, val string) (*gorm.DB, error)

	// List of jsonb columns that store a map.
	// These columns can be addressed using dot notation to access the JSON fields directly
	// Example: tags.cluster or tags.namespace.
	JSONMapColumns []string

	// List of columns that can be addressed on the search query.
	// Any other fields will be treated as a property lookup.
	Columns []string

	// Alias maps fields from the search query to the table columns
	// Example: map["created"] = "created_at"
	Aliases map[string]string

	// True when the table has a "tags" column
	HasTags bool

	// True when the table has a "labels" column
	HasLabels bool

	// True when the table has properties column
	HasProperties bool

	// FieldMapper maps the value of these fields
	// Example: map["created_at"] = DateMapper
	FieldMapper map[string]func(ctx context.Context, id string) (any, error)
}

QueryModel defines the structure and capabilities of a queryable table/resource. Consumers can create their own QueryModel instances for their specific tables.

func (QueryModel) Apply

Apply processes a query field and converts it to GORM clauses. It handles: - Field aliases - Field value mapping (via FieldMapper) - Common field operations (limit, sort, offset) - Custom field handlers - JSON path queries - Property filtering Returns the modified transaction, clauses to add, and any error

type RegistryOptions added in v0.1.15

type RegistryOptions struct {
	// MaxSessions caps concurrently active (starting/running) sessions.
	MaxSessions int // default 5

	// MaxDuration caps any session's run duration.
	MaxDuration time.Duration // default 15m

	// MaxEvents caps any session's ring buffer.
	MaxEvents int // default 10000

	// RetainDone is how many terminal sessions stay in memory before the
	// oldest are pruned.
	RetainDone int // default 50

	// OnEvent/OnTransition are installed on every session started through
	// ExecuteStream — the persistence hooks.
	OnEvent      func(Event)
	OnTransition func(SessionInfo)
}

RegistryOptions bounds a SessionRegistry. Zero values take the defaults; profile-declared limits are clamped to these server caps, never raised.

type Result added in v0.1.13

type Result struct {
	// Profile is the name of the Profile that produced this Result.
	Profile string `json:"profile,omitempty" yaml:"profile,omitempty"`

	// Rows are the primary tabular records.
	Rows []Row `json:"rows" yaml:"rows"`

	// Context holds named side objects keyed by SubQuery name.
	Context map[string]any `json:"context,omitempty" yaml:"context,omitempty"`
}

Result is the output of executing a Profile: the tabular rows plus any named context objects (Policy/Plan/Integrations side panels, each produced by a SubQuery).

func Execute added in v0.1.13

func Execute(ctx context.Context, p Profile, params ...map[string]any) (*Result, error)

Execute runs a Profile end-to-end: resolve the supplied params, render the query, dispatch to the provider, evaluate CEL columns, run any context SubQueries, and apply processors.

params carries the server-side filter values for the Profile's declared Params (omit when there are none). They are validated/coerced against the declarations and exposed to the query template as `params`.

func MaterializeEvents added in v0.1.15

func MaterializeEvents(ctx context.Context, p Profile, events []Event) (*Result, error)

MaterializeEvents turns a session's event log into a Result: the last snapshot for a top profile, or the streamed rows run through the profile's processors for a trace. It also serves persisted events after the live session is gone.

func (*Result) Render added in v0.1.13

func (r *Result) Render(columns []ColumnDef, format string) (string, error)

Render formats the Result in the given clicky format (e.g. "table", "csv", "json", "xlsx", "html").

func (*Result) Table added in v0.1.13

func (r *Result) Table(columns []ColumnDef) api.TextTable

Table builds a clicky TextTable from the Result. When columns is empty, the columns are derived from the union of row keys (sorted for determinism).

type Row added in v0.1.13

type Row = map[string]any

Row is a single result record keyed by column name. It is a type alias for the generic map so provider code (ported from duty/dataquery) and CEL evaluation can treat rows uniformly.

type RowIterator added in v0.1.15

type RowIterator interface {
	Next() bool
	Row() Row
	Err() error
	Close() error
}

RowIterator is the bounded-memory result source implemented by providers that can keep a backend cursor open while callers consume one row at a time.

func ExecuteRows added in v0.1.15

func ExecuteRows(ctx context.Context, p Profile, params ...map[string]any) (RowIterator, error)

ExecuteRows resolves profile parameters and templates exactly like Execute, but opens a provider cursor and applies CEL columns one row at a time.

func ExecuteRowsBounded added in v0.1.15

func ExecuteRowsBounded(ctx context.Context, p Profile, maxRows int, params ...map[string]any) (RowIterator, error)

ExecuteRowsBounded opens a provider row source that will be consumed for at most maxRows rows. Providers can use the hint to avoid expensive cursors.

func SliceRows added in v0.1.15

func SliceRows(rows []Row) RowIterator

SliceRows adapts an already-buffered result to RowIterator. It is useful for processors and providers that require the legacy whole-result pipeline.

type SampleResult added in v0.1.15

type SampleResult struct {
	Rows          []Row       `json:"rows"`
	Columns       []ColumnDef `json:"columns"`
	RenderedQuery string      `json:"renderedQuery"`
	Truncated     bool        `json:"truncated,omitempty"`
	DurationMS    float64     `json:"durationMs"`
}

SampleResult is the raw, pre-column/pre-processor output used by profile authoring tools. Columns are inferred only from top-level row keys.

func Sample added in v0.1.15

func Sample(ctx context.Context, p Profile, params map[string]any, limit int) (*SampleResult, error)

Sample renders and executes a profile through its provider while deliberately bypassing configured columns, context queries and processors. Only providers whose request can be proven read-only are allowed.

type Session added in v0.1.15

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

Session is one running (or finished) trace/top execution: a capped ring buffer of events, live subscribers, and a state machine starting → running → {completed|failed|stopped}.

func ExecuteStream added in v0.1.15

func ExecuteStream(ctx context.Context, reg *SessionRegistry, p Profile, params ...map[string]any) (*Session, error)

ExecuteStream starts a trace or top session and returns immediately with the session in the starting state. ctx must be a long-lived application context; the run is bounded only by the session's clamped MaxDuration or Stop().

func NewSession added in v0.1.15

func NewSession(opts SessionOptions) *Session

NewSession creates a session in the starting state. The caller is expected to have validated the profile and clamped MaxEvents.

func (*Session) Abort added in v0.1.15

func (s *Session) Abort(err error)

Abort forces an active session into the failed state (e.g. when its durable event log cannot be written), cancelling the run and closing subscribers.

func (*Session) Emit added in v0.1.15

func (s *Session) Emit(e Event)

Emit stamps the event with the next sequence, appends it to the ring (evicting the oldest at capacity), and fans it out to subscribers without blocking. Events emitted after the session is terminal are discarded.

func (*Session) Events added in v0.1.15

func (s *Session) Events() []Event

Events returns a copy of the buffered events, oldest first.

func (*Session) ID added in v0.1.15

func (s *Session) ID() string

ID returns the session's identifier.

func (*Session) Latest added in v0.1.15

func (s *Session) Latest() *Result

Latest returns the most recent top snapshot (nil for traces or before the first tick).

func (*Session) Result added in v0.1.15

func (s *Session) Result(ctx context.Context) (*Result, error)

Result materializes the session: the latest snapshot for top, or the buffered rows run through the profile's processors for trace.

func (*Session) Snapshot added in v0.1.15

func (s *Session) Snapshot() SessionInfo

Snapshot returns a JSON-safe copy of the session's current state.

func (*Session) Stop added in v0.1.15

func (s *Session) Stop()

Stop transitions an active session to stopped and cancels its run context. A later markDone never downgrades the stopped state.

func (*Session) Subscribe added in v0.1.15

func (s *Session) Subscribe() (replay []Event, live <-chan Event, cancel func())

Subscribe atomically returns the buffered events and a live channel for subsequent ones — no gap, no duplication. The channel is closed when the session reaches a terminal state; cancel detaches the subscriber.

type SessionInfo added in v0.1.15

type SessionInfo struct {
	ID         string         `json:"id"`
	Profile    string         `json:"profile"`
	Kind       ProfileKind    `json:"kind"`
	State      SessionState   `json:"state"`
	Params     map[string]any `json:"params,omitempty"`
	Error      string         `json:"error,omitempty"`
	EventCount int64          `json:"eventCount"`
	StartedAt  time.Time      `json:"startedAt"`
	StoppedAt  *time.Time     `json:"stoppedAt,omitempty"`
}

SessionInfo is a JSON-safe snapshot of a session's state.

type SessionOptions added in v0.1.15

type SessionOptions struct {
	ID      string
	Profile Profile
	Params  map[string]any

	// MaxEvents caps the in-memory ring buffer (already clamped by the caller).
	MaxEvents int

	// OnEvent is called synchronously for every emitted event (before ring
	// eviction can drop it) — the persistence hook.
	OnEvent func(Event)

	// OnTransition is called synchronously after every state change.
	OnTransition func(SessionInfo)
}

SessionOptions configures NewSession.

type SessionRegistry added in v0.1.15

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

SessionRegistry tracks live and recently finished sessions in memory.

func NewSessionRegistry added in v0.1.15

func NewSessionRegistry(opts RegistryOptions) *SessionRegistry

NewSessionRegistry creates a registry, applying defaults to zero options.

func (*SessionRegistry) Add added in v0.1.15

func (r *SessionRegistry) Add(s *Session) error

Add registers s, failing fast when MaxSessions active sessions already exist, and prunes the oldest terminal sessions beyond RetainDone.

func (*SessionRegistry) ClampDuration added in v0.1.15

func (r *SessionRegistry) ClampDuration(d time.Duration) time.Duration

ClampDuration lowers d to the server cap when it exceeds it.

func (*SessionRegistry) ClampEvents added in v0.1.15

func (r *SessionRegistry) ClampEvents(n int) int

ClampEvents lowers n to the server cap when it exceeds it.

func (*SessionRegistry) Get added in v0.1.15

func (r *SessionRegistry) Get(id string) (*Session, bool)

Get returns the session with the given id.

func (*SessionRegistry) List added in v0.1.15

func (r *SessionRegistry) List() []SessionInfo

List returns snapshots of all tracked sessions, oldest first.

func (*SessionRegistry) StopAll added in v0.1.15

func (r *SessionRegistry) StopAll()

StopAll stops every active session (serve shutdown hook).

type SessionState added in v0.1.15

type SessionState string

SessionState is the lifecycle state of a trace or top session.

const (
	SessionStarting    SessionState = "starting"
	SessionRunning     SessionState = "running"
	SessionCompleted   SessionState = "completed"
	SessionFailed      SessionState = "failed"
	SessionStopped     SessionState = "stopped"
	SessionInterrupted SessionState = "interrupted"
)

func (SessionState) Terminal added in v0.1.15

func (s SessionState) Terminal() bool

Terminal reports whether no further transitions or events can occur.

type StreamProvider added in v0.1.15

type StreamProvider interface {
	Provider

	// Stream runs req, calling emit for each row until ctx is cancelled or the
	// source ends. It blocks; a nil return means the source ended normally.
	Stream(ctx context.Context, req ProviderRequest, emit func(Row)) error
}

StreamProvider is an optional provider capability for continuous sources (log tails, event streams). Trace profiles require it.

type StreamingProvider added in v0.1.15

type StreamingProvider interface {
	Provider
	OpenRows(ctx context.Context, req ProviderRequest) (RowIterator, error)
}

StreamingProvider is an optional Provider capability. Providers that do not implement it continue to work through Execute's buffered compatibility path.

type SubQuery added in v0.1.13

type SubQuery struct {
	Provider ProviderConfig `json:"provider" yaml:"provider"`
	Query    string         `json:"query,omitempty" yaml:"query,omitempty"`
}

SubQuery is a secondary provider query whose result is attached to the Result as a named context object.

type TopSpec added in v0.1.15

type TopSpec struct {
	// Interval is the sampling period (default 5s, floor 1s).
	Interval types.Duration `json:"interval,omitempty" yaml:"interval,omitempty"`

	// MaxDuration bounds the session; the server may clamp it lower.
	MaxDuration types.Duration `json:"maxDuration,omitempty" yaml:"maxDuration,omitempty"`

	// SortBy names the column each snapshot is sorted by (descending).
	SortBy string `json:"sortBy,omitempty" yaml:"sortBy,omitempty"`

	// Limit truncates each snapshot after sorting.
	Limit int `json:"limit,omitempty" yaml:"limit,omitempty"`
}

TopSpec declares a Profile as a top: the engine re-executes the query on an interval and each tick replaces the previous snapshot. Any provider works.

func (TopSpec) DurationLimit added in v0.1.15

func (s TopSpec) DurationLimit() time.Duration

DurationLimit returns MaxDuration, defaulted when unset.

func (TopSpec) TickInterval added in v0.1.15

func (s TopSpec) TickInterval() time.Duration

TickInterval returns Interval, defaulted and floored.

type TraceSpec added in v0.1.15

type TraceSpec struct {
	// MaxDuration bounds the session; the server may clamp it lower.
	MaxDuration types.Duration `json:"maxDuration,omitempty" yaml:"maxDuration,omitempty"`

	// MaxEvents caps the in-memory event ring buffer.
	MaxEvents int `json:"maxEvents,omitempty" yaml:"maxEvents,omitempty"`
}

TraceSpec declares a Profile as a trace: a long-running streaming session with explicit setup (start) and teardown (stop). The provider must implement StreamProvider.

func (TraceSpec) DurationLimit added in v0.1.15

func (s TraceSpec) DurationLimit() time.Duration

DurationLimit returns MaxDuration, defaulted when unset.

func (TraceSpec) EventLimit added in v0.1.15

func (s TraceSpec) EventLimit() int

EventLimit returns MaxEvents, defaulted when unset.

Directories

Path Synopsis
Package processor contains built-in post-query processors for the query engine: sqlite-backed merge and key-based reconciliation.
Package processor contains built-in post-query processors for the query engine: sqlite-backed merge and key-based reconciliation.
Package providers contains the built-in data providers for the query engine.
Package providers contains the built-in data providers for the query engine.
Package schema generates JSON Schema (Draft 2020-12) documents that drive the clicky-ui forms and tables of the query app:
Package schema generates JSON Schema (Draft 2020-12) documents that drive the clicky-ui forms and tables of the query app:

Jump to

Keyboard shortcuts

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