In traditional logging architectures (like Elasticsearch / ELK), log aggregators index every single word of every log payload into an inverted index. This requires massive memory, huge NVMe storage, and expensive CPU clusters.
Grafana Loki takes a fundamentally different approach: it only indexes metadata labels (like app="nginx", env="production"), and stores the raw compressed log stream chunks in cheap object storage (like AWS S3 or MinIO).
100%
Rendering interactive visual diagram...
LogQL: The Log Query Language
LogQL allows you to filter and transform log streams in real time:
1. Stream Selectors (Targeting Specific Logs)
logql
# Get all logs from the production checkout microservice
{app="checkout-service", environment="production"}
2. Line Filter Expressions
logql
# Filter logs containing "error" (case-insensitive)
{app="checkout-service"} |= "error"
# Filter logs containing "database connection" but NOT containing "ping"
{app="checkout-service"} |= "database connection" != "ping"
# Regex match for 400 or 500 HTTP status codes
{app="checkout-service"} |~ "HTTP/1.1 (4|5)[0-9]{2}"
3. Parsing JSON Logs & Formatting
logql
# Automatically parse JSON fields and filter where duration > 5000ms
{app="checkout-service"} | json | response_time_ms > 5000 | line_format "{{.timestamp}} [{{.level}}] user={{.user_id}} took {{.response_time_ms}}ms"
4. Metrics from Logs (Converting Logs to Graphs!)
logql
# Calculate error frequency rate per second over the last 5 minutes:
sum(rate({app="checkout-service"} |= "ERROR" [5m])) by (service)
Complete Promtail Configuration
Create promtail-config.yml:
yaml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: docker_containers
static_configs:
- targets:
- localhost
labels:
job: docker
__path__: /var/lib/docker/containers/*/*-json.log
# Extract container name and image from Docker metadata
pipeline_stages:
- json:
expressions:
log: log
stream: stream
time: time
- output:
source: log