Agents now send an independent "still alive" record on a configurable
schedule (seconds/minutes/hours, [heartbeat] in agent.toml), separate
from real log traffic and tagged with a sentry.heartbeat attribute.
No new wire protocol -- it's an ordinary record through the same
PushBatch RPC/mTLS identity every log line already uses. Unavailability
alerting reuses the existing absence-condition alert rule type
unchanged; no new alerting code was needed. See
/docs/agent-heartbeat-monitoring.md for the design and how to build the
alert rule.
While verifying the alert rule live, found that the query language's
lexer never treated '-' as part of an identifier, so any unquoted
hyphenated filter value -- including the reference doc's own canonical
example, `host!=host-03` -- failed to parse at all. Fixed in
api/internal/querylang/lexer/lexer.go with regression tests; a leading
'-' still lexes as its own token so earliest=-1h/sort -count are
unaffected.
Replaces the separate SQL-only /query and text-only /search endpoints
with one pipe-syntax query language (plus raw SQL escape hatch) that
compiles to a single IR and execution plan across both backends, so a
query like `message:"connection refused" | stats count by host` runs
as one request instead of two disjoint tools.
- api/internal/querylang: lexer -> ast -> parser -> ir -> planner ->
executor, each layer independently tested.
- Execution generalizes Phase 1's proven Tantivy-prefilter pattern
into a 4-way routing table (pure ClickHouse / text-only / text +
aggregation / raw SQL passthrough).
- Unified web query page and `sentryctl query`, both hitting the same
POST /query endpoint.
- Benchmarked against a real 1,022,000-row dataset
(hack/benchmark-fixture); caught and fixed a real bug where the
Tantivy prefilter cap (10,000) produced an IN-clause exceeding
ClickHouse's default max_query_size -- lowered to 5,000, documented
in docs/query-language-design.md and docs/phase-2-runbook.md.
- docs/query-language-reference.md: customer-facing syntax reference.