Grafana Loki на Ubuntu 24.04: пошаговая установка
Логи сервера обычно живут в трёх местах одновременно: journalctl, файлы в /var/log и вывод docker logs, который исчезает при перезапуске контейнера. Когда что-то падает в три ночи, вы либо помните точный синтаксис journalctl -u myapp --since для каждого юнита, либо теряете десять минут на поиск нужного файла. Loki решает это без лишней сложности: он не индексирует содержимое строк, как Elasticsearch, а только метки — и благодаря этому требует в разы меньше памяти и диска. Ниже — установка Loki и Promtail на Ubuntu 24.04, подключение к Grafana и рабочие запросы LogQL, с которых стоит начать.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Почему Loki, а не ELK
Loki спроектирован Grafana Labs с явной оглядкой на Prometheus: та же модель меток, тот же принцип "индексируем только то, что нужно для поиска, а не весь текст". Это даёт заметно более скромные требования к ресурсам по сравнению с Elasticsearch — Loki хранит сырые логи сжатыми блоками и строит индекс только по меткам (job, host, container и так далее), а не по каждому слову в каждой строке.
Плата за экономию — полнотекстовый поиск внутри Loki работает медленнее, чем в Elasticsearch, особенно на больших объёмах без узких меток. Для сложной full-text аналитики по миллионам строк ELK или OpenSearch справятся лучше. Если же задача — "видеть логи всех сервисов в одном месте, коррелировать их с метриками Prometheus по времени, не тратя на это половину сервера" — Loki для типичного проекта на VPS ощутимо экономнее.
Разница в подходе:
| Loki | Elasticsearch/ELK | |
|---|---|---|
| Индексация | только метки | полный текст |
| Потребление RAM | низкое | высокое |
| Порог входа | синтаксис похож на PromQL | свой DSL, нужен Kibana |
| Интеграция с Grafana | нативная | через плагин |
| Подходит для | логи + метрики в одном стеке | сложный полнотекстовый поиск |
Если Grafana и Prometheus у вас уже стоят — Loki логически продолжает эту связку, и настроить его быстрее, чем поднимать отдельный ELK-стек.
Требования к серверу
Для небольшого проекта (2–5 сервисов, разумный объём логов) достаточно 2 vCPU и 2–4 ГБ RAM — Loki и Promtail вместе съедают немного, но Grafana и кэш запросов тоже просят память. Для продакшена с десятками сервисов берите 4 ГБ RAM и следите за диском отдельно: логи растут быстрее, чем кажется, особенно в debug-режиме.
Диск — отдельный разговор. Loki хранит сжатые чанки логов локально (или в S3-совместимом хранилище), и без настроенного retention они будут копиться бесконечно. Закладывайте SSD от 40 ГБ на старте и обязательно настройте retention_period, об этом ниже.
Понадобится:
- Ubuntu 24.04 LTS, root или sudo
- Docker и Docker Compose (проще всего поднять весь стек контейнерами)
- Открытые порты: 3000 (Grafana) наружу, 3100 (Loki) — только внутри docker-сети
Если Docker ещё не стоит, сначала разверните его по пошаговой установке для Ubuntu 24.04 — Loki удобнее всего запускать именно в контейнерах, конфиги проще версионировать в git.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверУстановка Loki и Grafana через Docker Compose
Создаём рабочую директорию и структуру:
mkdir -p /opt/loki-stack/{loki,promtail,grafana}
cd /opt/loki-stack
Конфиг Loki, loki/loki-config.yml — минимальный рабочий вариант для одного сервера (single-binary mode, без кластеризации):
auth_enabled: false
server:
http_listen_port: 3100
common:
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
schema_config:
configs:
- from: 2024-01-01
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
limits_config:
retention_period: 336h
ingestion_rate_mb: 8
ingestion_burst_size_mb: 16
compactor:
working_directory: /loki/compactor
retention_enabled: true
delete_request_store: filesystem
retention_period: 336h — это 14 дней. Для продакшена подберите под ваши требования: держать логи месяцами локально на VPS обычно бессмысленно и дорого по месту, если только это не требование комплаенса.
Теперь docker-compose.yml:
services:
loki:
image: grafana/loki:3.2.0
container_name: loki
restart: unless-stopped
volumes:
- ./loki/loki-config.yml:/etc/loki/local-config.yaml
- loki-data:/loki
command: -config.file=/etc/loki/local-config.yaml
networks:
- monitoring
promtail:
image: grafana/promtail:3.2.0
container_name: promtail
restart: unless-stopped
volumes:
- ./promtail/promtail-config.yml:/etc/promtail/config.yml
- /var/log:/var/log:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /run/log/journal:/run/log/journal:ro
- /var/log/journal:/var/log/journal:ro
command: -config.file=/etc/promtail/config.yml
networks:
- monitoring
depends_on:
- loki
grafana:
image: grafana/grafana:11.2.0
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=change-me-now
networks:
- monitoring
depends_on:
- loki
volumes:
loki-data:
grafana-data:
networks:
monitoring:
driver: bridge
Версии образов зафиксированы явно — обновляйте их сознательно, а не через latest, чтобы не поймать breaking change в схеме хранения посреди ночи. Пароль Grafana обязательно смените на реальный перед стартом.
Обратите внимание на монтирование /var/lib/docker/containers и путей journal — они нужны Promtail, чтобы читать логи контейнеров и systemd-юнитов напрямую с хоста. Конфиг Promtail собираем следующим шагом.
Сбор логов systemd и Docker через Promtail
Promtail — агент, который читает логи и пушит их в Loki с нужными метками. promtail/promtail-config.yml:
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:
# systemd journal
- job_name: journal
journal:
max_age: 12h
labels:
job: systemd-journal
relabel_configs:
- source_labels: ['__journal__systemd_unit']
target_label: unit
- source_labels: ['__journal_priority_keyword']
target_label: level
# логи Docker-контейнеров
- job_name: docker
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
relabel_configs:
- source_labels: ['__meta_docker_container_name']
regex: '/(.*)'
target_label: container
# обычные текстовые логи из /var/log
- job_name: syslog
static_configs:
- targets:
- localhost
labels:
job: syslog
__path__: /var/log/syslog
Для job docker нужен доступ к сокету Docker — добавьте в сервис promtail в compose-файле:
volumes:
# ...предыдущие volumes...
- /var/run/docker.sock:/var/run/docker.sock
Ключевой момент по меткам: не создавайте label с высокой кардинальностью — например, не делайте label из user_id или request_id. Loki строит индекс по меткам, и тысячи уникальных значений одной метки распухнут индекс так, что запросы начнут тормозить. Правило простое: метки — для ЧТО и ГДЕ (сервис, хост, уровень), детали события ищите фильтрацией текста внутри самого запроса.
Запускаем стек:
docker compose up -d
docker compose logs -f promtail
В логах Promtail должны появиться записи об успешном подключении к http://loki:3100 и начале tailing файлов — если видите ошибки permission denied на /var/log/journal, добавьте пользователя контейнера в группу systemd-journal или временно смонтируйте с более широкими правами для теста.
Подключение Loki как источника данных в Grafana
Открываем http://<IP-сервера>:3000, логинимся под admin и паролем из GF_SECURITY_ADMIN_PASSWORD. Дальше:
- Connections → Data sources → Add data source
- Выбираем Loki
- URL:
http://loki:3100(имя сервиса из docker-сети, не localhost) - Save & Test — должно появиться зелёное "Data source successfully connected"
Если у вас уже настроена связка Grafana и Prometheus по этой инструкции, Loki добавляется в ту же Grafana вторым источником данных — это и есть основная ценность подхода: метрики и логи в одном интерфейсе, с возможностью кликнуть на всплеск на графике Prometheus и сразу увидеть логи за этот момент.
Проверить, что данные идут, можно через Explore (иконка компаса в левом меню): выбираем Loki, в поле запроса вводим {job="systemd-journal"} и должны увидеть поток строк за последние часы.
LogQL: запросы, с которых стоит начать
LogQL синтаксически похож на PromQL — если вы уже писали запросы для Prometheus, освоитесь быстро. Базовая структура: селектор меток в фигурных скобках, затем опциональные фильтры и функции.
Все логи конкретного systemd-юнита:
{job="systemd-journal", unit="nginx.service"}
Логи Docker-контейнера с фильтром по тексту:
{container="my-app"} |= "error"
Исключить шумные health-check запросы:
{container="my-app"} != "GET /healthz"
Парсинг JSON-логов и фильтр по полю (если приложение логирует структурированно):
{container="my-app"} | json | level="error"
Скорость появления ошибок в секунду за последние 5 минут — это уже метрика, построенная из логов, и её можно вывести на график рядом с метриками Prometheus:
sum(rate({container="my-app"} |= "error" [5m]))
Регулярное выражение для более точного фильтра:
{job="syslog"} |~ "failed login.*root"
Эти пять паттернов покрывают большинство повседневных задач: найти сервис, отфильтровать по тексту, спарсить структурированные поля, построить метрику из частоты событий. Дальше LogQL позволяет комбинировать фильтры и агрегации — но начинать проще с простых селекторов, постепенно усложняя запрос и наблюдая за результатом в Explore.
Дашборд и алерты на основе логов
Готовый дашборд собирается за 10–15 минут из панелей двух типов: Logs (поток строк с фильтром) и Time series (график на основе rate() или count_over_time()). Практичный минимальный набор:
- панель Logs с запросом
{job=~".+"} |= "error" or "panic" or "fatal"— общий поток ошибок по всем сервисам; - панель Time series с
sum by (unit) (rate({job="systemd-journal", level=~"err|crit"} [5m]))— частота ошибок в разрезе по юнитам; - панель Stat с
count_over_time({container="my-app"} |= "OOM" [1h])— счётчик конкретного события за час.
Алерты на логах работают через тот же механизм unified alerting, что и алерты на метриках: создаёте alert rule на основе LogQL-запроса с агрегацией ("если sum(rate(... [5m])) больше 10 — сработать"), задаёте condition и получателя (Telegram, email, webhook). Это удобно для событий, которые сложно поймать метрикой напрямую — например, конкретную фразу ошибки от стороннего API.
Практический совет: не заводите алерт на "любое слово error в логах" — почти в любом стеке найдётся сервис, который пишет error в штатных ситуациях (retry, expected exception). Начните с узких условий и расширяйте по мере того, как понимаете, какой шум реален для вашей системы.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Loki заменяет Prometheus?
Нет, это разные инструменты: Prometheus — метрики (числа во времени), Loki — логи (текстовые события). Обычно их ставят вместе, и Grafana объединяет оба источника в одном дашборде.
Сколько места займут логи за месяц?
Зависит от объёма логирования — единого числа тут нет, точную оценку даст только тест на вашем трафике. Ориентируйтесь по du -sh на volume спустя сутки-двое работы и экстраполируйте, плюс не забывайте про retention_period в конфиге.
Можно ли собирать логи с нескольких серверов в один Loki?
Да, Promtail на каждом сервере отправляет данные в clients.url, указывающий на центральный Loki. Тогда центральный сервер должен принимать входящие на порт 3100 — закройте его firewall-правилами, разрешающими только ваши серверы, см. настройку UFW на Ubuntu 24.04.
Нужен ли обратный прокси перед Grafana?
Для продакшена — да, ради HTTPS и чтобы не светить порт 3000 напрямую. Разверните nginx как reverse proxy с автоматическим SSL по этой инструкции.
Чем Loki отличается от ELK на практике?
Синтаксис запросов другой (LogQL vs Kibana DSL), интерфейс — та же Grafana, что и для метрик, а не отдельная Kibana. Для сложного полнотекстового поиска и агрегаций по произвольным полям ELK гибче; для низкого потребления ресурсов и единого интерфейса с метриками проще Loki.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →