forked from Rockachopa/Timmy-time-dashboard
79 lines
2.6 KiB
Plaintext
79 lines
2.6 KiB
Plaintext
# ── Logstash Pipeline — Timmy Time log aggregation ──────────────────────────
|
|
#
|
|
# Collects Docker container logs via the GELF input, parses them,
|
|
# and ships structured events to Elasticsearch.
|
|
#
|
|
# Flow: Docker (GELF driver) → Logstash :12201/udp → Elasticsearch
|
|
|
|
input {
|
|
# GELF (Graylog Extended Log Format) — Docker's native structured log driver.
|
|
# Each container sends logs here automatically via the logging driver config
|
|
# in docker-compose.logging.yml.
|
|
gelf {
|
|
port => 12201
|
|
type => "docker"
|
|
}
|
|
}
|
|
|
|
filter {
|
|
# ── Tag by container name ──────────────────────────────────────────────────
|
|
# Docker GELF driver populates these fields automatically:
|
|
# container_name, container_id, image_name, tag, command, created
|
|
|
|
# Strip leading "/" from container_name (Docker convention)
|
|
if [container_name] {
|
|
mutate {
|
|
gsub => ["container_name", "^/", ""]
|
|
}
|
|
}
|
|
|
|
# ── Parse JSON log lines (FastAPI/uvicorn emit JSON when configured) ──────
|
|
if [message] =~ /^\{/ {
|
|
json {
|
|
source => "message"
|
|
target => "log"
|
|
skip_on_invalid_json => true
|
|
}
|
|
}
|
|
|
|
# ── Extract log level ─────────────────────────────────────────────────────
|
|
# Try structured field first, fall back to regex on raw message
|
|
if [log][level] {
|
|
mutate { add_field => { "log_level" => "%{[log][level]}" } }
|
|
} else if [level] {
|
|
mutate { add_field => { "log_level" => "%{level}" } }
|
|
} else {
|
|
grok {
|
|
match => { "message" => "(?i)(?<log_level>DEBUG|INFO|WARNING|ERROR|CRITICAL)" }
|
|
tag_on_failure => []
|
|
}
|
|
}
|
|
|
|
# Normalise to uppercase
|
|
if [log_level] {
|
|
mutate { uppercase => ["log_level"] }
|
|
}
|
|
|
|
# ── Add service metadata ──────────────────────────────────────────────────
|
|
mutate {
|
|
add_field => { "environment" => "production" }
|
|
add_field => { "project" => "timmy-time" }
|
|
}
|
|
}
|
|
|
|
output {
|
|
elasticsearch {
|
|
hosts => ["http://elasticsearch:9200"]
|
|
index => "timmy-logs-%{+YYYY.MM.dd}"
|
|
|
|
# ILM policy: auto-rollover + delete after 30 days
|
|
ilm_enabled => true
|
|
ilm_rollover_alias => "timmy-logs"
|
|
ilm_pattern => "{now/d}-000001"
|
|
ilm_policy => "timmy-logs-policy"
|
|
}
|
|
|
|
# Also print to stdout for debugging (disable in production)
|
|
# stdout { codec => rubydebug }
|
|
}
|