processor

package
v0.1.30 Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package processor contains built-in post-query processors for the query engine: sqlite-backed merge, key-based reconciliation, and CEL batch transforms that fold runs of adjacent rows together. It also holds the library of named presets those processors ship with, such as "java.stacktrace".

Each processor and preset self-registers via init(); consumers enable them with a blank import:

import _ "github.com/flanksource/commons-db/query/processor"

Index

Constants

View Source
const (
	// DefaultBatchMax caps how many adjacent rows one batch may absorb, so a
	// runaway continuation predicate folds a page of logs, not a million rows.
	DefaultBatchMax = 1000

	// OrderAscending means the rows arrive oldest first and are batched as they
	// come.
	OrderAscending = "asc"

	// OrderDescending means the rows arrive newest first — the normal shape of a
	// log query. Batches are formed in reverse so a merged message reads
	// chronologically, and the output keeps the input's ordering.
	OrderDescending = "desc"

	// KeepFirst builds the merged row from the earliest row in the batch.
	KeepFirst = query.KeepFirst

	// KeepLast builds it from the latest.
	KeepLast = query.KeepLast
)

Batch grouping and transform defaults.

View Source
const (
	ReconAdded     = "added"
	ReconRemoved   = "removed"
	ReconChanged   = "changed"
	ReconUnchanged = "unchanged"

	// ReconStatusColumn holds the per-row reconciliation status.
	ReconStatusColumn = "_recon_status"

	// ReconChangesColumn holds a map of changed columns -> {from,to} for
	// rows with status "changed".
	ReconChangesColumn = "_recon_changes"
)

Reconciliation status values written to the ReconStatusColumn.

Variables

This section is empty.

Functions

func ApplyBatch added in v0.1.29

func ApplyBatch(ctx context.Context, rows []query.Row, cfg BatchConfig) ([]query.Row, error)

ApplyBatch groups rows into batches and collapses each one per cfg. Pure logic — no database, no provider.

func ApplyDedupe added in v0.1.29

func ApplyDedupe(ctx context.Context, rows []query.Row, cfg DedupeConfig) ([]query.Row, error)

ApplyDedupe groups rows by their partition key and collapses each group per cfg. Pure logic — no database, no provider.

func ApplyLogParse added in v0.1.29

func ApplyLogParse(rows []query.Row, config LogParseConfig) ([]query.Row, error)

ApplyLogParse turns structured bodies into canonical log columns, promotes their remaining fields without replacing provider metadata, and recomputes hash from the parsed message for downstream logs.dedupe.

func Merge

func Merge(ctx context.Context, mergeSQL string, sets ...ResultSet) ([]query.Row, error)

Merge loads each ResultSet into an in-memory SQLite database as a table, then runs mergeSQL (an arbitrary join/aggregation across those tables) and returns the resulting rows. Ported from duty/dataquery/sqlite.go.

func Recon

func Recon(ctx context.Context, baseline, target []query.Row, opts ReconOptions) ([]query.Row, error)

Recon reconciles a target result set against a baseline, keyed by opts.Key. Each returned row is the target row (or the baseline row, for removals) plus a ReconStatusColumn of added/removed/changed/unchanged. Changed rows also carry a ReconChangesColumn mapping each differing column to {from, to}.

This is a snapshot diff of one schema against itself. To join two *different* profiles on a shared identity and report presence and latency, use query.Reconcile instead.

Pure logic — no database required.

Types

type BatchConfig added in v0.1.29

type BatchConfig struct {
	// Partition never merges rows whose values differ here, whatever the
	// timestamps say. Naming a column no row has is not an error: every row
	// reads empty, so the partition simply never splits.
	Partition []string `json:"partition,omitempty" yaml:"partition,omitempty"`

	// Column is the timestamp read by the default grouping rule. When empty the
	// first of timestamp/@timestamp/time/firstObserved/startTime present on the
	// first row is used.
	Column string `json:"column,omitempty" yaml:"column,omitempty"`

	// Window buckets the timestamp before comparing it. Zero compares exact
	// values, which is what groups the lines of one log flush together.
	Window types.Duration `json:"window,omitempty" yaml:"window,omitempty"`

	// Order declares how the rows are sorted on the way in: "asc" (default) or
	// "desc".
	Order string `json:"order,omitempty" yaml:"order,omitempty"`

	// Boundary is a CEL predicate over `row`, `prev` and `index` that returns
	// true when row starts a new batch. Setting it replaces the timestamp rule
	// entirely, for sources whose timestamps cannot group anything.
	Boundary string `json:"boundary,omitempty" yaml:"boundary,omitempty"`

	// Continuation is a CEL predicate over the same bindings that returns true
	// when row continues the batch above it. It vetoes the timestamp rule, so a
	// stack frame still folds in when the shipper stamped it a millisecond late.
	Continuation string `json:"continuation,omitempty" yaml:"continuation,omitempty"`

	// Max caps the rows in one batch (default 1000); the batch is closed at the
	// cap.
	Max int `json:"max,omitempty" yaml:"max,omitempty"`

	// When gates the transform: batches it rejects pass through untouched. Its
	// bindings are the batch scope below.
	When string `json:"when,omitempty" yaml:"when,omitempty"`

	// Keep chooses the row the merged row is built from: "first" (default) or
	// "last".
	Keep string `json:"keep,omitempty" yaml:"keep,omitempty"`

	// Set overrides columns on the merged row. Each value is a CEL expression
	// over the batch scope: `batch` (the rows, oldest first), `first`, `last`,
	// `count` and `row` (the kept row, unmodified while Set is evaluated, so the
	// result does not depend on map ordering).
	//
	// Iterating the batch needs `dyn(batch).map(...)` rather than
	// `batch.map(...)`: gomplate declares every expression variable as
	// cel.AnyType, and the CEL checker refuses a `google.protobuf.Any` as the
	// range of a comprehension. Indexing, `size()` and field selection need no
	// such conversion.
	Set map[string]string `json:"set,omitempty" yaml:"set,omitempty"`

	// Emit replaces Set for transforms that fan a batch out to several rows: a
	// CEL expression over the same scope returning a list of rows.
	Emit string `json:"emit,omitempty" yaml:"emit,omitempty"`
}

BatchConfig declares how adjacent rows are grouped into batches and what the batch collapses to. It is the configuration of the "cel.batch" processor.

Grouping is sequential — runs of adjacent rows — not a hash group-by. That is what a multiline merge needs (a stack frame belongs to the line above it, not to every line that shares its timestamp), it is O(n), and it stays incremental so the same batcher can later drive a streaming session.

func (BatchConfig) Validate added in v0.1.29

func (c BatchConfig) Validate() error

Validate rejects a configuration that cannot mean one thing.

type DedupeConfig added in v0.1.29

type DedupeConfig struct {
	// Partition is the dedup key: rows agreeing on every one of these columns
	// are one group. Required — an empty key would collapse the entire result
	// to a single row, which is never what an author means.
	Partition []string `json:"partition,omitempty" yaml:"partition,omitempty"`

	// Keep chooses which row of a group survives as the merged row: "first"
	// (default) or "last". Groups preserve arrival order, so with a newest-first
	// query "first" is the most recent occurrence.
	Keep string `json:"keep,omitempty" yaml:"keep,omitempty"`

	// When is a CEL predicate over `batch`, `first`, `last`, `count` and `row`
	// that gates the merge. A group it rejects passes through as separate rows,
	// so `count > 1` leaves non-duplicates exactly as they arrived.
	When string `json:"when,omitempty" yaml:"when,omitempty"`

	// Set assigns columns on the merged row from CEL over the same bindings —
	// `count` for how many rows collapsed, `dyn(batch)…` to reach across them.
	// Leaving it empty keeps the surviving row unchanged, which is the plain
	// "drop duplicates" behaviour.
	Set map[string]string `json:"set,omitempty" yaml:"set,omitempty"`

	// Emit replaces Set, returning the merged rows from one CEL expression.
	Emit string `json:"emit,omitempty" yaml:"emit,omitempty"`

	// Max caps how many rows one group may absorb. Rows past the cap start a
	// new group rather than being dropped.
	Max int `json:"max,omitempty" yaml:"max,omitempty"`
}

DedupeConfig declares how rows are grouped by key and what each group collapses to. It is the configuration of the "cel.dedupe" processor.

Grouping is a hash group-by over the whole result, which is the difference that matters against "cel.batch": batch groups runs of *adjacent* rows, so it folds a stack trace into the line that threw but never notices the same error recurring an hour later. Repeated log lines are scattered through a time-ordered result, so collapsing them needs every row in hand at once.

It runs page by page too, but under a stated weaker reading: a group surfaces on the page it first appears on, carrying the count from that page alone, and the cursor remembers it so no later page repeats it. Revising an already-sent row is not something a walk can do — see ProcessPage.

func (DedupeConfig) Validate added in v0.1.29

func (c DedupeConfig) Validate() error

Validate rejects a configuration that cannot mean one thing.

type LogParseConfig added in v0.1.29

type LogParseConfig struct {
	// Format is json, logfmt, klogfmt, syslog or autodetect. Empty means
	// autodetect.
	Format string `json:"format,omitempty" yaml:"format,omitempty"`

	// Column carries the raw log body. Empty reads message.
	Column string `json:"column,omitempty" yaml:"column,omitempty"`
}

LogParseConfig selects the structured format and source column used by the logs.parse processor.

func (LogParseConfig) Validate added in v0.1.29

func (c LogParseConfig) Validate() error

type ReconOptions

type ReconOptions struct {
	// Key is the set of columns that uniquely identify a row across both sets.
	// Mutually exclusive with KeyCEL.
	Key []string

	// KeyCEL derives the identity from an expression instead of column values,
	// for the cases where the identity is nested or computed. Mutually exclusive
	// with Key.
	KeyCEL string

	// Compare restricts which columns are compared for the "changed" status.
	// When empty, all non-key columns present in either row are compared.
	Compare []string
}

ReconOptions configures a reconciliation.

type ResultSet

type ResultSet struct {
	Name string
	Rows []query.Row
}

ResultSet pairs a table name with the rows to load into the merge database.

Jump to

Keyboard shortcuts

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