# ── 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 }
}
