Skip to main content

Loki Compatibility

This track measures how closely the proxy behaves like Loki on Loki-facing APIs and LogQL behavior.

Scope

  • /labels, /label/<name>/values, /series, /query, /query_range
  • LogQL parser, filter, metric, and OTel label compatibility
  • Synthetic compatibility labels the proxy must expose to Loki clients, such as service_name
  • Manifest-driven query semantics parity against real Loki in query-semantics-matrix.json
  • Tracked operation inventory in query-semantics-operations.json

CI And Score

  • Workflow: compat-loki.yaml
  • Score test: TestLokiTrackScore
  • Required PR gate: loki-pinned, which runs the TestQuerySemantics* inventory + matrix suite
  • Runtime matrix: real Loki images
  • Support window: current Loki minor family plus one minor family behind

The Loki matrix is a moving window. When a new Loki minor becomes current, the matrix advances to that family and the immediately previous minor family. Older minors drop out of support.

Version Matrix

Loki versionCoverage pathVersion-specific focus
3.7.1PR and main CI pinned runtimePrimary supported reference
3.7.0Scheduled and manual matrixdetected_level metric grouping, OTel label parity
3.6.10Scheduled and manual matrixRange query matrix shape, detected fields stability
3.6.9Scheduled and manual matrixRange query matrix shape, detected fields stability
3.6.8Scheduled and manual matrixRange query matrix shape, detected fields stability
3.6.7Scheduled and manual matrixRange query matrix shape, detected fields stability
3.6.6Scheduled and manual matrixRange query matrix shape, detected fields stability
3.6.5Scheduled and manual matrixRange query matrix shape, detected fields stability
3.6.4Scheduled and manual matrixRange query matrix shape, detected fields stability
3.6.3Scheduled and manual matrixRange query matrix shape, detected fields stability
3.6.2Scheduled and manual matrixRange query matrix shape, detected fields stability
3.6.1Scheduled and manual matrixRange query matrix shape, detected fields stability
3.6.0Scheduled and manual matrixRange query matrix shape, detected fields stability

Edge Cases Covered

  • JSON and logfmt parser chains followed by field filters
  • detected_level grouped metric queries used by Grafana log volume panels
  • OTel dotted and underscore label parity through the underscore proxy
  • Series and label-value parity for labels synthesized by the proxy

Query Families In The Loki Semantics Matrix

The Loki semantics matrix focuses on query combinations where the proxy should match Loki as closely as possible on:

  • HTTP status
  • payload status
  • errorType
  • resultType
  • line-count parity for log streams
  • series-count parity for vectors and matrices
  • exact metric-label-set parity for label-sensitive metric families such as bare parser metrics

The tracked operation inventory in query-semantics-operations.json is machine-checked in CI. Every matrix case must belong to at least one inventory operation, and every inventory operation must reference live matrix cases.

Covered valid families:

FamilyRepresentative cases
Stream selectorsexact match, multi-label match, regex, negative match
Line filters`
Parser pipelinesjson, logfmt, regexp, pattern, parser plus exact/regex/numeric field filter, label_format
Metric range queriescount_over_time, rate, bytes_over_time, bytes_rate, absent_over_time, grouped range aggregations, parser-inside-range filters, bare unwrap range functions
Aggregationssum by(...), without(...), topk(...), bottomk(...), sort(...), sort_desc(...)
Binary operationsscalar comparisons/math, bool comparisons, and vector-to-vector operations such as /, and, or, and unless over valid metric expressions

Detailed operation inventory:

CategoryOperations currently enforced in CI
Selectorsexact selectors, multi-label regex selectors, negative-regex selectors
Line filters`
Parsersjson, logfmt, regexp, pattern plus parsed/extracted field filters
Formattingline_format, label_format, keep, drop
Metric functionscount_over_time, rate, bytes_over_time, bytes_rate, absent_over_time, sum/avg/max/min/first/last/stddev/stdvar_over_time with unwrap, quantile_over_time with unwrap
Aggregationssum by(...), sum without(...), topk, bottomk, sort, sort_desc
Binary operatorsscalar math/comparison, scalar bool comparison, vector arithmetic, on(...), group_left(...), logical and, or, unless
Invalid shapeslog-query aggregation misuse, missing metric range, malformed selector/parser syntax, invalid log-query binary ops

Explicit invalid families:

FamilyRepresentative cases
Metric aggregation over a log querysum by(job) ({selector})
Post-aggregation over a log querytopk(2, {selector}), sort({selector})
Missing range on a metric functionrate({selector})
Malformed selector / syntaxbroken braces, parser syntax errors
Invalid binary shapelog-query to scalar/vector binary expressions

These are intentionally called out because they are easy to regress while changing translation, shaping, or query planning.

What Stays Outside Loki Parity

Some important compatibility behavior is still tested, but it is not part of the strict Loki parity matrix:

  • synthetic service_name recovery when the backend only has structured metadata
  • Drilldown helper endpoints like detected labels, detected fields, field values, volume, and patterns
  • stale-on-error helper behavior under VictoriaLogs failures

Those cases live in the proxy contract suite because Loki itself is not the source of truth for them.

Parity Rule

Valid Loki behavior is not an allowed exclusion category.

If a query shape works in real Loki and the proxy does not match it, that is treated as a parity bug and should be fixed or tracked with an explicit regression case. The bare parser-metric and bare unwrap metric shapes now live inside the required matrix for that reason.

Detailed Edge Cases Now Gated

The required matrix is intentionally not limited to happy-path selectors. It now includes:

  • parser-derived metric labelsets, not just result counts
  • bare unwrap range functions where Loki keeps parsed labels but not the unwrap target field itself
  • pattern parser extraction semantics
  • set-style binary operators such as or and unless
  • bool comparison semantics on metric expressions
  • invalid log/metric shape rejections that must fail with the same class of error as Loki

When a new LogQL family is implemented or fixed in the proxy, the expectation is to add:

  1. a runtime matrix case in query-semantics-matrix.json
  2. an inventory entry in query-semantics-operations.json
  3. a local or unit regression if the fix needed proxy-side translation or shaping changes