3.23 Event Queries

EVENTS [type_pattern] [clauses…]

3.23.1 The type pattern #

The primary selector is an optional event type pattern, placed immediately after EVENTS.

EVENTS kacs.access_denied      -- exactly that type
EVENTS kacs.*                  -- every type beginning "kacs."
EVENTS *.denied                -- every type ending ".denied"
EVENTS kacs.*.denied           -- kacs.access.denied, kacs.token.denied, …
EVENTS                         -- every type

* is the only metacharacter, and matches zero or more of any character, dots included. ?, [ and { have no special meaning and a collector MUST NOT treat them as any. Matching folds case, like every string comparison (§3.20).

A pattern with no * is exactly WHERE event_type == "…". A pattern whose only * is trailing is exactly WHERE event_type STARTS_WITH "…". Anything else is a glob.

3.23.2 Origin class aliases #

origin_class accepts named aliases as well as its integer values:

AliasValue
userspace0
kmes1
kacs2
lcs3
EVENTS WHERE origin_class == kacs SINCE 1h ago

These are the only aliased values in the language. A collector MUST accept both forms and MUST treat them as identical.

3.23.3 Aggregation #

Grouping equality, canonical representatives and tie ordering are defined in §3.21. Every aggregation below has a fixed output schema, and rejects SELECT (§3.22).

3.23.3.1 COUNT BY #

Counts records grouped by one field, ordered by count descending.

EVENTS SINCE 24h ago COUNT BY event_type

Output: {<field>: representative, count: <unsigned integer>}.

3.23.3.2 TOP N BY #

COUNT BY with a limit — the N most frequent values.

EVENTS SINCE 1h ago TOP 10 BY process_guid

Output: the COUNT BY schema.

3.23.3.3 DISTINCT #

The distinct values of one field.

EVENTS SINCE 24h ago DISTINCT event_type

Output: {<field>: representative}.

3.23.3.4 GROUP #

Groups by one or more fields, followed by an aggregation function: COUNT, or SUM, AVG, MIN, MAX with a field argument.

EVENTS SINCE 1h ago GROUP origin_class COUNT
EVENTS SINCE 1h ago GROUP origin_class, event_type COUNT
EVENTS SINCE 1h ago GROUP event_type AVG queue_depth

Output, for GROUP a, b:

QueryRecord
COUNT{a, b, count}
SUM x{a, b, sum}
AVG x{a, b, avg}
MIN x{a, b, min}
MAX x{a, b, max}

Group-key fields carry canonical representatives (§3.21).

3.23.3.5 What is aggregated #

For SUM, AVG, MIN and MAX, records whose field is null or non-numeric are excluded from the aggregate — not treated as zero. COUNT counts every record regardless. If no record in a group contributes a numeric value, the group's aggregate is null and the group is still present, because COUNT of it is still meaningful.

3.23.3.6 Result types #

  • COUNT returns an unsigned integer.
  • SUM over integers returns an integer when the exact mathematical sum fits in signed or unsigned 64 bits. If it does not, or if any input was a float, it returns a float64. If that would be non-finite, the query MUST fail with an error rather than returning an infinity.
  • AVG returns a float64 whenever at least one numeric value contributed.
  • MIN and MAX return the winning value itself, under exact numeric comparison. When an integer and a float tie, the integer wins.

3.23.4 Ordering #

Without SORT, results are ordered by timestamp descending, ties broken as §3.21 requires.

3.23.5 INDEX #

EVENTS INDEX target_sid

INDEX asks the collector to prioritise a field for query acceleration immediately, rather than waiting for it to be observed often enough to be prioritised automatically. It exists for incident response, where the field that suddenly matters has never been queried before.

INDEX is an administrative operation, not a query. It returns no records. A collector MUST check the caller's token against a Security Descriptor governing administration of the collector — one distinct from the read-path descriptors of §3.28 — and MUST refuse a caller that does not hold it. A collector without such a descriptor MUST refuse INDEX outright.

A collector MAY treat INDEX as advisory and MAY decline the request, shed the acceleration later, or do nothing at all. It is a hint about priority; the accelerations a collector maintains are its own business, and a conforming collector that maintains none accepts INDEX and has nothing to do.

There is no command to undo it, because there is nothing to undo: a collector reconsiders its own accelerations continuously and the hint decays with disuse.

Edit this page