source

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package source defines the internal interface of log sources: the byte plan of a range, the scan of one plan chunk, and the re-read of one record by its raw position.

Everything a Source returns (records, names, errors) is raw log content or derived from it: it is consumed only by internal/engine and internal/mask, which mask it before anything leaves the console.

Index

Constants

View Source
const (
	MaxNumberLen      = 400
	MaxNumberExponent = 400
)

Number literal bounds: big.Rat's cost grows with the exponent (1e999999 takes milliseconds), and log content chooses it.

View Source
const GranuleBytes = 1 << 20

GranuleBytes is the size of a plan granule of a byte stream: streams are cut into fixed, query-independent sections of GranuleBytes bytes, aligned to stream offsets (the last one of a stream is shorter). A record belongs to the granule its first line starts in, and records never cross a granule boundary (see parse.NewSectionReader). Plans, charges, cursors and stopping points are counted in granules, so they never reveal the length of one record.

Variables

View Source
var (
	ErrStale    = errors.New("source: the stream changed since the plan or reference was made")
	ErrNotFound = errors.New("source: no such stream")
)

Errors of sources. Their text never holds log content.

View Source
var ErrByteLimit = errors.New("source: past the byte limit of the call")

ErrByteLimit is returned by a scan (or a source's bounded read) that would process more than its byte limit.

View Source
var ErrMountLost = errors.New("source: a log mount root is gone or was replaced")

ErrMountLost is returned (wrapped) by a source whose mount root is gone or is no longer the directory it first read (a stale handle, a root unmounted or swapped under the console): its logs can no longer be trusted to be the approved ones. The engine answers it as a lost session (logconsole.ErrConnLost), never as a refusal: the console drops the session and the next call reconnects, checking every mount again.

View Source
var ErrNotIndexable = errors.New("source: the count needs fields the index (or the server) does not hold")

ErrNotIndexable is returned by IndexCounts when a selector or group field is not in the index of every stream.

Functions

func AsLogFetch added in v0.2.0

func AsLogFetch(ctx context.Context) context.Context

AsLogFetch marks the requests sent under ctx as log fetches made to answer a count (Loki's entries at bucket boundaries): a limiter that charges a count's requests as server-side metric queries charges these as requests only.

func ByteLimitFrom

func ByteLimitFrom(ctx context.Context) int64

ByteLimitFrom returns the byte limit of ctx, or 0 (none).

func IsLogFetch added in v0.2.0

func IsLogFetch(ctx context.Context) bool

IsLogFetch reports a request marked by AsLogFetch.

func MountLost added in v0.2.0

func MountLost(err error) error

MountLost wraps err in ErrMountLost when it says the mount under a read is gone (a stale file handle, ESTALE); any other error is returned as is.

func ParseNumber added in v0.2.0

func ParseNumber(s string) (*big.Rat, bool)

ParseNumber returns the exact value of a JSON number literal within the bounds; a literal beyond them is not a number to compare (equality falls back to its text). It is the engine's reading of a number.

func WithByteLimit

func WithByteLimit(ctx context.Context, n int64) context.Context

WithByteLimit attaches to ctx the bytes a scan may process (Iterator's Processed). The engine checks Processed after every record; a source that buffers before it yields (a remote slice, fetched page by page, sorted whole) checks the limit itself as it fetches, and fails with ErrByteLimit instead of buffering past it.

func WithLimiter

func WithLimiter(ctx context.Context, l Limiter) context.Context

WithLimiter attaches the call's request limiter to ctx.

Types

type AroundMeter

type AroundMeter interface {
	AroundMeasured(ctx context.Context, ref RawRef, before, after int) ([]RawRecord, int64, error)
}

AroundMeter is implemented by a source whose Around may process more than the records it returns (reading back granules, decompressing a stream from its start): AroundMeasured also returns the bytes processed, which the engine reports and charges.

type Byteplan

type Byteplan struct {
	Chunks []Chunk
}

Byteplan is the plan of a range: chunks in the order they are scanned (newest stream first, stream order within a stream).

func (Byteplan) Bytes

func (p Byteplan) Bytes() int64

Bytes returns the plan's total cost in bytes.

func (Byteplan) Granules

func (p Byteplan) Granules() int

Granules returns the plan's number of granules.

type Chunk

type Chunk struct {
	Source string
	// Stream identifies the stream (a file identity, a remote stream).
	Stream string
	// Granules are consecutive and in stream order (the engine's split of
	// a descending remote slice holds its parts newest first: remote
	// granules are read one at a time).
	Granules []Granule
	// Bytes is the number of bytes processing the chunk costs: the
	// granules' bytes, plus for a compressed stream the decompressed bytes
	// before the first granule that must be read and discarded.
	Bytes int64
	// Version is the stream's state the plan was made on (e.g. its size at
	// open); a scan of a chunk whose stream changed incompatibly fails
	// with ErrStale.
	Version string
}

Chunk is a unit of a byte plan: consecutive granules of one stream.

func (Chunk) End

func (c Chunk) End() int64

End returns the stream offset after the chunk's last granule.

func (Chunk) Start

func (c Chunk) Start() int64

Start returns the stream offset of the chunk's first granule.

type CountQuery

type CountQuery struct {
	Range    Range
	Selector Selector
	// By are line fields, ByLabels labels; a row's Vals are the By values
	// then the ByLabels values.
	By       []string
	ByLabels []string
	// Bucket is a whole number of minutes (0: one bucket for the range).
	Bucket time.Duration
}

CountQuery is a count of records by trusted fields per time bucket.

type CountResult

type CountResult struct {
	Rows []CountRow
	// Untimed counts indexed records without a time in matching
	// granules (not in any bucket).
	Untimed int64
	// Residual is the plan of the granules the index does not hold: the
	// caller scans them and adds their counts.
	Residual Byteplan
	// IndexedFrom, IndexedUntil: see Schema.
	IndexedFrom, IndexedUntil time.Time
}

CountResult is what an index (or a server-side metric query) answers, and the plan of what it cannot.

type CountRow

type CountRow struct {
	Bucket time.Time
	Vals   []string
	N      int64
}

CountRow is the count of one bucket and one tuple of By values (raw: index.Absent, index.Redacted and index.Other stand for themselves).

type Counter

type Counter interface {
	IndexCounts(ctx context.Context, q CountQuery) (CountResult, error)
}

Counter is a source that answers trusted-field counts without a scan (the local index, Loki metric queries), returning the plan of what it cannot.

type FieldInfo

type FieldInfo struct {
	Name string
	// Label is set for a label of the source's frame (a Loki stream
	// label, a docker container or stream), unset for a line field.
	Label   bool
	Trusted bool
	// Values are the trusted field's distinct values (raw, masked by the
	// caller), when the source knows them and they are few.
	Values []string
}

FieldInfo describes one field name a source has seen.

type Granule

type Granule struct {
	// Start and End are stream offsets [Start, End): records whose first
	// line starts there.
	Start, End int64
	// Indexed is set when the local index holds this granule; From, To
	// and Records are then exact (From/To zero when it holds no timed
	// record). For a granule that is not indexed they are unknown.
	Indexed  bool
	From, To time.Time
	Records  int64
	// Bytes is the planned cost of the granule (its length for a byte
	// stream); 0 when unknown before the fetch (a remote time slice,
	// charged by the bytes actually fetched).
	Bytes int64
}

Granule is one plan granule of a stream.

type Iterator

type Iterator interface {
	// Next returns the next record, or io.EOF after the last one.
	Next() (RawRecord, error)
	// Processed returns the bytes processed so far (read, decompressed,
	// discarded).
	Processed() int64
	Close() error
}

Iterator yields the records of a chunk in stream order.

type Limiter

type Limiter interface {
	Wait(ctx context.Context) error
}

Limiter paces the requests of a call to a backend (the rolling request budget of free calls, an approved scan's own plan-based rate).

func LimiterFrom

func LimiterFrom(ctx context.Context) Limiter

LimiterFrom returns the call's limiter, or nil.

type NumericSelector added in v0.2.0

type NumericSelector interface {
	NumericTerms()
}

NumericSelector is implemented by a source that honors Term.Numbers (it treats Ambiguous values as unknown): the engine pushes numeric terms only to such a source and evaluates them on the records for the others.

type Range

type Range struct {
	From, To time.Time
}

Range is the absolute time range [From, To).

func (Range) Contains

func (r Range) Contains(t time.Time) bool

Contains reports whether t is in r.

func (Range) Overlaps

func (r Range) Overlaps(from, to time.Time) bool

Overlaps reports whether [from, to] (inclusive) overlaps r.

type RawRecord

type RawRecord struct {
	Ref   RawRef
	Event parse.Event
	// Granule identifies the granule the record belongs to, as the source
	// numbers them (file: the absolute granule number of the stream; other
	// sources document theirs).
	Granule int
}

RawRecord is one record read from a source: raw, unmasked.

type RawRef

type RawRef struct {
	Source string
	Stream string
	Offset int64
	Length int64
}

RawRef locates one record: its source, stream, granule and raw position.

type RootGuard added in v0.2.0

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

RootGuard pins the mount roots of a source: the first time a root is seen its device and inode are recorded, and every later Check compares them. It is safe for concurrent use; the zero value is ready.

func (*RootGuard) Check added in v0.2.0

func (g *RootGuard) Check(root string) error

Check reports ErrMountLost (wrapped) when root, seen before, is gone, stale, no longer a directory or another directory. A root never seen that is absent is not an error (a journal directory the host does not have): it is pinned the first time it is found.

type Schema

type Schema struct {
	Kind    string
	Format  string
	Fields  []FieldInfo
	Streams int
	// Bytes is the estimated size of the source's data.
	Bytes int64
	// Oldest and Newest bound the source's records, when known.
	Oldest, Newest time.Time
	// IndexedFrom is the start of the newest contiguous indexed span:
	// every record from IndexedFrom on (before IndexedUntil when set: a
	// growing file's newest lines are being indexed) is in the local
	// index, allowing a minute of timestamp disorder. Zero when nothing can
	// be claimed. It describes what the index holds: counts may still scan
	// part of that range (a grown granule goes to the residual whole).
	IndexedFrom, IndexedUntil time.Time
	// FullyIndexed is set when every granule is indexed.
	FullyIndexed bool
}

Schema is a source's description. Names, values and paths are raw.

type Selector

type Selector struct {
	Terms []Term
}

Selector is the conjunction of trusted-field terms of a query: the part a source may use to narrow its plan (index, server-side labels).

func (Selector) Match

func (s Selector) Match(fields, labels map[string]string) bool

Match reports whether a record whose trusted line fields have values fields and whose labels have values labels (missing ones absent) satisfies every term.

type Source

type Source interface {
	Name() string
	Kind() string
	Describe(ctx context.Context) (Schema, error)
	// Plan returns the chunks that may hold records of r matching sel.
	// It reads no record content beyond what identifying a stream needs.
	Plan(ctx context.Context, r Range, sel Selector) (Byteplan, error)
	Scan(ctx context.Context, c Chunk) (Iterator, error)
	// Reread returns the record at ref, or ErrStale when the stream no
	// longer holds it.
	Reread(ctx context.Context, ref RawRef) (RawRecord, error)
	// Around returns up to before records before ref, the record itself
	// and up to after records after it, from ref's stream.
	Around(ctx context.Context, ref RawRef, before, after int) ([]RawRecord, error)
}

Source is a log source.

type Splitter

type Splitter interface {
	// Split returns the granules g is cut into, in stream order, covering
	// exactly [g.Start, g.End) (their bounds a function of g only), or nil
	// when g is at the narrowest width the source pages.
	Split(g Granule) []Granule
}

Splitter is implemented by a source whose granules of unknown bytes (remote time slices, Granule.Bytes 0) can be cut into narrower ones: the engine splits a slice holding more than one call's byte budget, so that it can be paged with a cursor on sub-slice boundaries.

type Term

type Term struct {
	Field string
	// Label is set for a term on a label of the source's frame (Loki
	// stream labels, journald and docker attributes: parse.Event.Attrs),
	// unset for a line field. They are separate namespaces: a source
	// applies a term only in its own one.
	Label  bool
	Op     string // "=", "!=", "in"
	Values []string
	// Numbers are the values given as JSON numbers (a subset of
	// Values). The engine compares a number leaf with them by exact
	// value (200 = 200.0 = 2e2) and any other leaf by text; a source
	// sees values as text, without their kind: see Ambiguous. Only a
	// NumericSelector is given a term with Numbers.
	Numbers []string
}

Term is a predicate on a trusted field, used for planning: = and != on one value, "in" on a set. Values are the field's clear values (trusted fields are shown to the agent in clear after the detectors).

func (Term) Ambiguous added in v0.2.0

func (t Term) Ambiguous(v string) bool

Ambiguous reports whether the raw value v of t's field satisfies t or not depending on the kind of the leaf it was read from, which a source's index does not keep: a number equal to one of t's Numbers but written otherwise (2e2 for 200) matches as a JSON number, not as a string. Every other value matches t exactly as Match says. A source treats an ambiguous value as unknown, as a redacted one: it may match, and it is never counted by t.

Directories

Path Synopsis
Package docker is the Docker log source: the json-file logs of the containers whose names the human approved, read from the containers root (`docker info .DockerRootDir` + /containers, bound read-only and non-recursive by the launcher), through a name -> id map the launcher keeps current.
Package docker is the Docker log source: the json-file logs of the containers whose names the human approved, read from the containers root (`docker info .DockerRootDir` + /containers, bound read-only and non-recursive by the launcher), through a name -> id map the launcher keeps current.
Package elastic is the Elasticsearch (8.x) and OpenSearch (2.x) log source.
Package elastic is the Elasticsearch (8.x) and OpenSearch (2.x) log source.
elastictest
Package elastictest is a fake Elasticsearch 8 / OpenSearch 2 for the tests of the packages that open an Elasticsearch source (the session, the engine through it): an http.Handler over in-memory documents that answers the requests locklog sends (the root, the privilege checks, _resolve/index, _field_caps, _mapping, _settings, _count and _search with bool filters, sort, search_after and the two aggregation kinds), behind basic or API-key authentication unless Open.
Package elastictest is a fake Elasticsearch 8 / OpenSearch 2 for the tests of the packages that open an Elasticsearch source (the session, the engine through it): an http.Handler over in-memory documents that answers the requests locklog sends (the root, the privilege checks, _resolve/index, _field_caps, _mapping, _settings, _count and _search with bool filters, sort, search_after and the two aggregation kinds), behind basic or API-key authentication unless Open.
Package file is the file log source: globs of plain, gzip and zstd files under the console's read-only mount roots, read beneath their root without following symbolic links, planned in fixed granules, and indexed locally.
Package file is the file log source: globs of plain, gzip and zstd files under the console's read-only mount roots, read beneath their root without following symbolic links, planned in fixed granules, and indexed locally.
Package journald is the journald log source: systemd journal files under the console's read-only journal roots, read by the pure-Go reader in ./journal, with a field allowlist applied before any value is read.
Package journald is the journald log source: systemd journal files under the console's read-only journal roots, read by the pure-Go reader in ./journal, with a field allowlist applied before any value is read.
journal
Package journal reads systemd journal files (the format of systemd's JOURNAL_FILE_FORMAT.md): regular and compact layouts, XZ, LZ4 and ZSTD compressed data objects, keyed or Jenkins hashes.
Package journal reads systemd journal files (the format of systemd's JOURNAL_FILE_FORMAT.md): regular and compact layouts, XZ, LZ4 and ZSTD compressed data objects, keyed or Jenkins hashes.
journal/journaltest
Package journaltest builds small journal files in memory for tests and fuzz seeds: header, DATA, ENTRY and chained ENTRY_ARRAY objects, regular or compact, plain or ZSTD/LZ4/XZ compressed (no hash tables: the reader does not use them).
Package journaltest builds small journal files in memory for tests and fuzz seeds: header, DATA, ENTRY and chained ENTRY_ARRAY objects, regular or compact, plain or ZSTD/LZ4/XZ compressed (no hash tables: the reader does not use them).
Package loki is the Loki log source.
Package loki is the Loki log source.
lokitest
Package lokitest is a fake Loki 3 for the tests of the packages that open a Loki source (the session, the engine through it): an http.Handler over in-memory entries that answers the requests locklog sends (labels, label values, query_range for streams and for the metric form, the instant metric query), with Loki's paging (limit over all streams, forward, end excluded) and categorized labels, behind basic authentication unless Open.
Package lokitest is a fake Loki 3 for the tests of the packages that open a Loki source (the session, the engine through it): an http.Handler over in-memory entries that answers the requests locklog sends (labels, label values, query_range for streams and for the metric form, the instant metric query), with Loki's paging (limit over all streams, forward, end excluded) and categorized labels, behind basic authentication unless Open.

Jump to

Keyboard shortcuts

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