BlogDetection

Log aggregation with Loki and structured logging

Ship JSON logs, label them well, and query with LogQL — centralized logs without a heavyweight indexing bill.

Apr 22, 2025·9 min readIntermediate

Loki treats logs like Prometheus treats metrics: it indexes a small set of labels, not the full text, so it stays cheap at scale. The tradeoff is that your labels and log structure have to be deliberate — get that right and centralized logging costs a fraction of a full-text stack.

Ship with good labels

alloy.river
loki.source.kubernetes "pods" {
targets = discovery.kubernetes.pods.targets
forward_to = [loki.write.default.receiver]
}
// labels: namespace, app, level — low cardinality only

Log structured, not prose

JSON logs let Loki (and you) filter on fields at query time without regex archaeology.

app log line
{"level":"error","route":"/checkout","status":500,"trace":"a1b2","msg":"payment declined"}

Query with LogQL

bash — find the errorslive
logcli query '{app="checkout"} | json | status>=500'
12 lines route=/checkout status=500 trace=a1b2 ...
filtered on a JSON field, no index bloat
High-cardinality labels kill Loki
Never put user id, request id, or trace id in a label — that explodes the index. Keep them in the log body and extract with | json at query time.
Go deeper in a courseAdvanced Linux securityLog pipelines, detection, and incident-ready observability.View course

Related posts