Portal | Level: L2: Operations | Topics: Loki | Domain: Observability
LogQL Drills¶
20 drills for Loki query language muscle memory. Each should take 1-5 minutes.
Difficulty: [E] Easy = stream selector + filter | [I] Intermediate = parsers or metric queries | [H] Hard = complex aggregations
Remember: LogQL has two query types: log queries (return log lines) and metric queries (return numeric values). Log queries use stream selectors + filters. Metric queries wrap log queries in functions like
count_over_time(),rate(),bytes_rate(). Mnemonic: "Streams for reading, Metrics for graphing."Gotcha: LogQL filter operators:
|=(contains),!=(not contains),|~(regex match),!~(regex not match). The|=operator is case-sensitive by default. For case-insensitive matching, use the regex form:|~ "(?i)error".Debug clue: If a Loki query returns no results, check: (1) Is the stream selector correct?
{namespace="x"}must match an actual label. (2) Is the time range long enough? Loki defaults to the last hour. (3) Is Promtail/the agent actually shipping logs from that source?
Drill 1: All logs from a namespace [E]¶
Question: Show all logs from the grokdevops namespace.
Answer
`{namespace="grokdevops"}`Drill 2: Filter for errors [E]¶
Question: Show only log lines containing "error".
Answer
`{namespace="grokdevops"} |= "error"` > **One-liner:** `|=` is a line filter — it scans each log line for the substring. It is much faster than regex (`|~`) because Loki can use bloom filters for exact substring matches.Drill 3: Exclude health checks [E]¶
Question: Show logs but exclude lines mentioning "/health".
Answer
`{namespace="grokdevops"} != "/health"`Drill 4: Regex match [E]¶
Question: Find log lines containing any 5xx status code.
Answer
`{namespace="grokdevops"} |~ "status[=: ]+5[0-9]{2}"`Drill 5: Multiple filters [I]¶
Question: Find error logs that are NOT related to health checks.
Answer
`{namespace="grokdevops"} |= "error" != "/health" != "healthcheck"`Drill 6: Parse JSON logs [I]¶
Question: Parse JSON-formatted logs and filter for status >= 500.
Answer
`{namespace="grokdevops"} | json | status >= 500` > **Under the hood:** The `| json` stage parses each log line as JSON and extracts all fields as labels. After this, you can filter on any JSON key. If your logs are not JSON, use `| logfmt` for key=value format or `| pattern` for custom formats. > > **Default trap:** `| json` fails silently on non-JSON lines — they are dropped from results. If you see fewer results than expected, some log lines may not be valid JSON.Drill 7: Parse and filter by level [I]¶
Question: Show only ERROR level logs from JSON output.
Answer
`{namespace="grokdevops"} | json | level = "error"`Drill 8: Count errors per minute [I]¶
Question: How many error logs per minute in the grokdevops namespace?
Answer
`sum(count_over_time({namespace="grokdevops"} |= "error" [1m]))` > **Remember:** `count_over_time()` counts log lines, `rate()` gives per-second rate, `bytes_over_time()` gives total bytes, `bytes_rate()` gives bytes/s. Mnemonic: "**Count for totals, Rate for speed**" — same pattern as PromQL's `increase()` vs `rate()`.Drill 9: Error rate from logs [I]¶
Question: What is the rate of error log lines per second?
Answer
`sum(rate({namespace="grokdevops"} |= "error" [5m]))`Drill 10: Log volume in bytes [I]¶
Question: How many bytes of logs per second is grokdevops producing?
Answer
`sum(bytes_rate({namespace="grokdevops"}[5m]))`Drill 11: Log volume by container [I]¶
Question: Break down log volume by container.
Answer
`sum by (container) (bytes_rate({namespace="grokdevops"}[5m]))`Drill 12: Top 5 noisiest pods [I]¶
Question: Which pods produce the most log lines per second?
Answer
`topk(5, sum by (pod) (rate({namespace="grokdevops"}[5m])))`Drill 13: Extract request path from JSON [I]¶
Question: Show only the request path and status from JSON logs with status >= 400.
Answer
`{namespace="grokdevops"} | json | status >= 400 | line_format "{{.path}} {{.status}}"`Drill 14: Unique error messages [H]¶
Question: Count unique error messages in the last hour.
Answer
`count(sum by (msg) (count_over_time({namespace="grokdevops"} | json | level="error" [1h])))`Drill 15: Duration percentile from logs [H]¶
Question: Calculate p99 request duration from JSON logs that include a "duration" field.
Answer
`quantile_over_time(0.99, {namespace="grokdevops"} | json | unwrap duration [5m]) by (path)` > **Gotcha:** `unwrap` converts a label value to a numeric sample for aggregation. The field must be a number. If the field is a string like `"0.5s"`, you need to strip the unit first with `| label_format duration=...` or ensure your app logs numeric-only values. Non-numeric values are silently dropped.Drill 16: Pattern parser [I]¶
Question: Parse Apache-style access logs using pattern parser and filter for 5xx.
Answer
`{namespace="grokdevops"} | pattern "Drill 17: Count by label value [I]¶
Question: Count log lines per HTTP method in the last 5 minutes.
Answer
`sum by (method) (count_over_time({namespace="grokdevops"} | json [5m]))`Drill 18: Detect panics [E]¶
Question: Find any log lines containing "panic" or "PANIC".
Answer
`{namespace="grokdevops"} |~ "(?i)panic"`Drill 19: Compare log volume over time [H]¶
Question: Compare current log volume to 1 hour ago.
Answer
`sum(rate({namespace="grokdevops"}[5m])) / sum(rate({namespace="grokdevops"}[5m] offset 1h))`Drill 20: Logs from a specific pod [E]¶
Question: Show logs from pod "grokdevops-abc123" in the grokdevops namespace.
Answer
`{namespace="grokdevops", pod="grokdevops-abc123"}`Wiki Navigation¶
Prerequisites¶
- Observability Deep Dive (Topic Pack, L2)
Related Content¶
- Incident Simulator (18 scenarios) (CLI) (Exercise Set, L2) — Loki
- Interview: Loki Logs Disappeared (Scenario, L2) — Loki
- Lab: Loki No Logs (CLI) (Lab, L2) — Loki
- Log Pipelines (Topic Pack, L2) — Loki
- Loki Flashcards (CLI) (flashcard_deck, L1) — Loki
- Observability Architecture (Reference, L2) — Loki
- Observability Deep Dive (Topic Pack, L2) — Loki
- Observability Drills (Drill, L2) — Loki
- Runbook: Log Pipeline Backpressure / Logs Not Appearing (Runbook, L2) — Loki
- Runbook: Loki No Logs (Runbook, L2) — Loki
Pages that link here¶
- Drills
- Level 7: SRE & Cloud Operations
- Log Pipelines
- Log Pipelines - Primer
- Observability Architecture
- Observability Drills
- Primer
- Runbook: Log Pipeline Backpressure / Logs Not Appearing
- Runbook: Loki Not Receiving Logs
- Scenario: Logs Disappeared from Grafana Loki
- Track: SRE & Reliability Engineering