Files
homelab/kubernetes/apps/monitoring-rules/prometheusrule-loki.yaml
k.renner 98dbf2dc4a monitoring: add Loki ServiceMonitor + self-alerts
Loki had no Prometheus scrape config — no loki_* metrics, no way to
alert on the log stack itself going sideways. ServiceMonitor covers
the single-binary + canary services, alerts cover Down / 5xx /
panics / canary-detected log loss.
2026-05-20 12:54:11 +02:00

57 lines
2.4 KiB
YAML

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: loki
namespace: monitoring
labels:
# kube-prometheus-stack's Prometheus resource selects on this label;
# without it the rule is created but never loaded into Prometheus.
release: kube-prometheus-stack
spec:
groups:
- name: loki.rules
rules:
- alert: LokiDown
expr: up{job=~"loki|loki-canary"} == 0
for: 5m
labels:
severity: critical
annotations:
summary: "Loki target {{ $labels.job }} is down"
description: "Prometheus has been unable to scrape {{ $labels.job }} ({{ $labels.instance }}) for 5 minutes. Log ingest and queries are likely affected."
- alert: LokiRequestErrors
# 5xx ratio on Loki's HTTP routes. Excludes health/debug routes
# which can be noisy without indicating a real problem.
expr: |
sum by (route) (rate(loki_request_duration_seconds_count{job="loki",status_code=~"5..",route!~"debug.*|.*ready.*|.*health.*"}[5m]))
/
sum by (route) (rate(loki_request_duration_seconds_count{job="loki",route!~"debug.*|.*ready.*|.*health.*"}[5m]))
> 0.10
for: 15m
labels:
severity: warning
annotations:
summary: "Loki {{ $labels.route }} >10% 5xx errors"
description: "Loki route {{ $labels.route }} has returned 5xx responses for more than 10% of requests over the last 15m."
- alert: LokiPanics
expr: sum(increase(loki_panic_total{job="loki"}[10m])) > 0
for: 0m
labels:
severity: critical
annotations:
summary: "Loki panicked"
description: "loki_panic_total increased in the last 10m — Loki encountered an internal panic. Check pod logs."
- alert: LokiCanaryMissingEntries
# loki-canary writes test logs and reads them back. Missing
# entries mean the ingest → store → query path lost data.
expr: sum(increase(loki_canary_missing_entries_total[10m])) > 0
for: 10m
labels:
severity: warning
annotations:
summary: "Loki canary detected missing log entries"
description: "loki-canary reported entries it wrote were not returned by the read path in the last 10m — log data loss."