All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 9s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
Метрик в проекте не было ни одной: ни экспортеров, ни /metrics в бэкендах, единственный канал наблюдения — journald, единственный сигнал об аварии — исключение в GlitchTip. Из-за этого целый класс отказов невидим в принципе: задача рапортует done, строк ноль, исключения нет. Так протухли данные на семь месяцев (#2998), 34 дня был мёртв house_imv_backfill (#2698), 8 суток писал ноль newbuilding_enrich (#2767), 91 день копилось раздутие listings (#2992). Grafana не заменяет GlitchTip: ошибки остаются там. Grafana OSS не принимает Sentry DSN ни одним компонентом, а скрубберы в before_send — требование 152-ФЗ. Здесь появляется другой класс данных: ряды и алерты по трендам. Наблюдатель поставлен у ДРУГОГО провайдера, чем наблюдаемое: серверная сторона на Beget, рядом с GlitchTip. Если ляжет Poincare, мониторинг должен об этом сказать, а не лечь вместе с ним. Транспорт push, а не pull: агент на Poincare шлёт remote_write и логи исходящим HTTPS, поэтому там не открывается ни одного входящего порта сверх 22/80/443. При обрыве канала Alloy копит в WAL и досылает — pull-скрейп в той же ситуации терял бы точки именно в аварии, ради которой мониторинг и нужен. Два контура доступа с разными учётками. Пароль приёмника по построению лежит открытым на продуктовом хосте, значит его компрометация неизбежна вместе с хостом; будь это учётка витрины, утёк бы и доступ к дашбордам. GlitchTip читается прямым SQL, а не Sentry-плагином: у плагина на 6.1.6 stats_v2 отдаёт 500 (баг GlitchTip #381), Events/Discover — 404 (#416), а в grafana/sentry-datasource слово glitchtip не встречается ни разу. Схема сверена на живой базе: колонка времени называется timestamp, а не received, и отдельной таблицы IssueIndex не существует — агрегаты лежат на самой issue_events_issue. Алерты за профилем alerts: канал доставки — открытый вопрос #3078, и стек не должен на нём стоять. Деплой предупреждает, что уведомлять пока некому. Каждая настройка, способная отказать молча, закрыта явно: ретенция Prometheus задана и по времени и по размеру, retention_enabled у компактора Loki (без него retention_period не работает вовсе), путь к журналу и запуск Alloy от root (иначе агент читает ноль записей без ошибки), проверка Caddy до перезагрузки (на этом хосте тот же Caddy держит git, errors и obsidian). Refs #3078
78 lines
2.9 KiB
YAML
78 lines
2.9 KiB
YAML
# Loki — monolithic (all-in-one). Рекомендованный режим до ~20 ГБ/сутки.
|
||
# Наш объём — ~39 МБ/сутки (замер 24.08), то есть запас в 500 раз. Микросервисная
|
||
# раскладка здесь была бы сложностью без единого выигрыша.
|
||
|
||
auth_enabled: false # один арендатор; разграничение снаружи, на Caddy basic_auth
|
||
|
||
server:
|
||
http_listen_port: 3100
|
||
grpc_listen_port: 9096
|
||
log_level: warn
|
||
# Логи Alloy шлёт пачками; дефолтные 4 МБ на gRPC-сообщение при всплеске
|
||
# (например, рестарт с досылом из WAL) дают 'grpc: received message larger than max'.
|
||
grpc_server_max_recv_msg_size: 16777216
|
||
grpc_server_max_send_msg_size: 16777216
|
||
|
||
common:
|
||
instance_addr: 127.0.0.1
|
||
path_prefix: /loki
|
||
storage:
|
||
filesystem:
|
||
chunks_directory: /loki/chunks
|
||
rules_directory: /loki/rules
|
||
replication_factor: 1
|
||
ring:
|
||
kvstore:
|
||
store: inmemory
|
||
|
||
schema_config:
|
||
configs:
|
||
- from: 2026-08-01
|
||
store: tsdb
|
||
object_store: filesystem
|
||
schema: v13
|
||
index:
|
||
prefix: index_
|
||
period: 24h
|
||
|
||
storage_config:
|
||
tsdb_shipper:
|
||
active_index_directory: /loki/tsdb-index
|
||
cache_location: /loki/tsdb-cache
|
||
filesystem:
|
||
directory: /loki/chunks
|
||
|
||
limits_config:
|
||
# Приём «из прошлого». Агент после обрыва досылает накопленное из WAL —
|
||
# с дефолтным окном (1 неделя приёма, но reject_old_samples_max_age) часть
|
||
# догоняемых строк молча отбрасывается с 'entry too far behind'.
|
||
reject_old_samples: true
|
||
reject_old_samples_max_age: 168h
|
||
# Потолок на арендатора. 39 МБ/сутки = ~0.5 МБ/с в пике; 8 МБ/с — щедрый запас,
|
||
# но не «безлимит», чтобы взбесившийся источник не съел диск за ночь.
|
||
ingestion_rate_mb: 8
|
||
ingestion_burst_size_mb: 16
|
||
max_streams_per_user: 5000
|
||
max_label_names_per_series: 20
|
||
# Ретенция. Journald на хостах держит ~13 дней при потолке 500 МБ; в Loki
|
||
# смысл хранить дольше — ради разбора инцидентов постфактум.
|
||
retention_period: 720h
|
||
volume_enabled: true
|
||
|
||
compactor:
|
||
working_directory: /loki/compactor
|
||
delete_request_store: filesystem
|
||
# Без retention_enabled параметр retention_period выше НЕ работает: Loki
|
||
# примет его в конфиг и будет копить вечно. Классическая тихая настройка.
|
||
retention_enabled: true
|
||
retention_delete_delay: 2h
|
||
compaction_interval: 10m
|
||
|
||
ruler:
|
||
storage:
|
||
type: local
|
||
local:
|
||
directory: /loki/rules
|
||
|
||
analytics:
|
||
reporting_enabled: false
|