# Promtail — сбор логов контейнеров deal-стека для Loki (Ruling 7/9, план Task 14). # # Источник — docker-логи ВСЕХ контейнеров хоста через docker_sd (нужен доступ к docker.sock, см. # compose.prod.yml). Контейнеры deal-процессов пишут в stdout одну JSON-строку на событие # (Serilog CompactJsonFormatter, Ruling 7) — лог можно парсить в Loki через «| json» без доп. шаблонов. # relabel добавляет метки: container (имя контейнера) и service (имя compose-сервиса из стандартной # метки com.docker.compose.service) — по ним строятся дашборды Grafana (Deal-Health, Deal-Auth, # Deal-Errors, Deal-Rps, Deal-Logs). Pipeline дополнительно поднимает поле Serilog "@l" в метку # level (Information/Warning/Error/Fatal) — по ней фильтруют панели Deal-Logs. server: http_listen_port: 9080 grpc_listen_port: 0 # Позиции чтения — на volume deal_promtail_data (переживают рестарт контейнера). positions: filename: /var/lib/promtail/positions.yaml clients: - url: http://loki:3100/loki/api/v1/push scrape_configs: - job_name: docker docker_sd_configs: - host: unix:///var/run/docker.sock refresh_interval: 5s relabel_configs: # Имя контейнера (docker присваивает <проект>-<сервис>- или container_name). - source_labels: ["__meta_docker_container_name"] regex: "/(.*)" target_label: container # Имя compose-сервиса (core/telegram-service/ai-service/ml-service/...) из метки compose. - source_labels: ["__meta_docker_container_label_com_docker_compose_service"] target_label: service # Поток stdout/stderr — отдельной меткой (у Serilog весь вывод — stdout). - source_labels: ["__meta_docker_container_log_stream"] target_label: stream pipeline_stages: # Пайплайн применяется ТОЛЬКО к deal-процессам (match по метке service из relabel выше): # их логи — одна JSON-строка Serilog CompactJsonFormatter на событие. Прочие контейнеры # хоста (postgres/minio/caddy/loki/...) пишут не-JSON — их пайплайн не трогает. - match: selector: '{service=~"core|telegram-service|ai-service|ml-service"}' stages: # Поле Serilog "@l" (ключ со спецсимволом @ — литерал JMESPath в одинарных кавычках). - json: expressions: level: '"@l"' # drop_malformed не задан (false) — строка без валидного JSON не роняется, а проходит # без метки level (деградация мягкая). - labels: level: