Skip to main content
In this lesson you’ll learn how to filter and query application logs using LogQL (the query language used by Grafana Loki). We’ll progress from basic label selectors to text and regex filters, then show how to parse structured JSON log lines and filter by the extracted fields. These building blocks will help you craft precise, efficient queries to find the events you care about. For more details, see the official LogQL docs: LogQL — Grafana Loki.

Basic label selector

A LogQL query starts with a label matcher in braces to select a stream of logs. For example, to select logs from the stream where the label app equals api:
This returns all log lines whose stream has the label app="api".
Label selectors are the cheapest and most selective filters you can apply. Always start by narrowing streams with label matchers before adding pipeline filters.

Filtering by text (contains)

After selecting a stream, use pipeline operators to filter the content of log lines. Use |= to include only lines that contain a substring. Example: show only log lines that contain the word DELETE:
Sample output (truncated):

Filtering by route or other substrings

You can filter any substring in the line. For example, to find requests to the /users route:

Negation (exclude matches)

To exclude lines that contain a substring use the not-equals pipeline operator !=:
For regex negation (exclude lines matching a regex) use !~:

Regular expression matching

To filter lines that match a regex, use the match operator |~. For example, to keep only GET or POST entries:
To invert that (everything that is not GET or POST):

Quick reference: common pipeline operators

Parsing JSON log lines and filtering extracted fields

When your logs are structured JSON, parse them with the | json pipeline stage. This extracts top-level JSON fields and makes them available for direct comparisons. For example, to find entries whose parsed code field equals 500 while excluding GET/POST methods:
Example JSON log entries (parsed by | json):
Avoid parsing every log line with | json if you only need a subset — parse after applying text/regex filters to reduce processing. Also be cautious with broad regexes; they can be expensive and slow queries.

Putting it all together

The general pattern is:
  1. Use label matchers to narrow to the relevant stream(s).
  2. Apply pipeline operators (|=, !=, |~, !~) to include/exclude by text or regex.
  3. Use | json to parse structured logs, then filter on extracted fields.
Common query examples:
These building blocks let you compose precise LogQL queries to quickly locate relevant events.

Watch Video

Practice Lab