Loki Log Labels & LogQL Reference

LogQL stream selectors, filter expressions and metric query functions.

Searchable LogQL reference covering label matchers, line filters, label parsers, format expressions and metric queries for Grafana Loki. Build correct log queries fast.

What is a stream selector in LogQL?

A stream selector is the required first part of every LogQL query, written in braces, that picks which log streams to read by matching labels, e.g. {app="api", env="prod"}. At least one label matcher with the = operator is required so Loki can locate the streams.

LogQL reference for Grafana Loki

LogQL is the query language for Grafana Loki. Every query starts with a stream selector (label matchers in braces), optionally followed by line filters, parsers that extract structured fields, label filters, and format stages. Wrapping a log query in a range function turns it into a metric query. This reference lists the operators and functions for each stage.

Filter the entries below by keyword or stage to find the right syntax.

How it works

Loki indexes only labels, not log content. A query first uses the brace selector to locate matching streams — combinations of label values — using the inverted index; this is the cheap, indexed step and at least one = matcher is required. The selected log lines then flow through a pipeline of stages.

Line filters (|=, !=, |~, !~) match against the raw line. Parsers (| json, | logfmt, | regexp, | pattern) extract fields into temporary labels you can then filter (| status="500") or reformat (| line_format, | label_format). For metrics, range aggregations such as rate(...[5m]) and count_over_time(...[1h]) convert matched lines into a time series, which you then aggregate with sum, avg, or topk exactly as in PromQL. Keeping label cardinality low is essential because each label-value combination is a separate stream.

Tips and examples

Find errors in a service and count them per minute:

{app="checkout", env="prod"} |= "error"
sum by (level) (
  rate({app="checkout"} | json | __error__="" [1m])
)

Extract a latency field and chart its 95th percentile:

quantile_over_time(0.95,
  {app="api"} | json | unwrap duration_ms [5m]) by (route)

Put line filters before parsers so cheap text matching reduces the lines a parser must process. Avoid high-cardinality labels in the selector; extract IDs at query time with a parser instead.