OSEN-НИЙ SAAALEСкидка 50% на виртуальный хостинг и VDS
до 30.11.2025 Подробнее
Выберите продукт

Grafana Agent Flow на VDS: единый агент для metrics, logs и traces (Prometheus, Loki, Tempo, OTLP)

Grafana Agent в режиме Flow — лёгкий агент на одном VDS для метрик, логов и трейсов с отправкой в Prometheus/VictoriaMetrics, Loki и Tempo. В статье: River‑конфиг, systemd, OTLP 4317/4318, парсинг Nginx и journald.
Grafana Agent Flow на VDS: единый агент для metrics, logs и traces (Prometheus, Loki, Tempo, OTLP)

Grafana Agent в режиме Flow — это компонентная сборка для наблюдаемости, где вы на одном VDS поднимаете единый бинарник, описываете конвейеры в языке River и на выходе получаете аккуратный поток metrics, logs и traces в привычные бэкенды: Prometheus (или совместимые через remote_write), Loki и Tempo. По сути, это альтернатива связке «Promtail + часть функций OpenTelemetry Collector», но в одном процессе, с предсказуемым потреблением и единообразной конфигурацией.

Зачем Flow на VDS: ключевые преимущества

Для админа и девопса на одном сервере важны предсказуемость и простота. Flow даёт:

  • Единый агент вместо зоопарка демонов — меньше накладных расходов и конфликтов.
  • Компонентная архитектура: явные блоки для метрик (prometheus.scrape, prometheus.remote_write), логов (loki.source.*, loki.process, loki.write) и трейсов (otelcol.receiver.otlp, otelcol.processor.*, otelcol.exporter.otlp).
  • Язык River: компактно, декларативно, связи компонентов — через явные inputs/outputs.
  • Минимум зависимостей: одно бинарное приложение + systemd‑юнит.
  • Гибкость: легко добавлять новые источники без перезапуска всего стека наблюдаемости.

Архитектура: что именно мы поднимем

Мы сконфигурируем на VDS:

  • Сбор метрик: скрейпинг Agent self‑metrics и ваших экспортёров через prometheus.scrape, отправка в Prometheus/VictoriaMetrics по prometheus.remote_write.
  • Сбор логов: loki.source.file для файлов (например, Nginx) и loki.source.journal для journald; обработка через loki.process; отправка в Loki через loki.write.
  • Трейсы: приём от приложений по OTLP (gRPC 4317 и HTTP 4318) через otelcol.receiver.otlp, буферизация/батчинг и экспорт в Tempo через otelcol.exporter.otlp.

Идея простая: всё, что происходит на машине (системные логи, веб‑доступы, ошибки, метрики сервисов и трейсы приложения), централизованно и надёжно утекает на ваши хранилища observability.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Подготовка VDS

Наблюдаемость чувствительна к сетевым и файловым правам. Если сервера ещё нет — поднимите агент на нашем облачном VDS: достаточно 1–2 vCPU и 1 ГБ RAM для старта.

  • Оцените ресурсы: 1–2 vCPU и 512–1024 МБ RAM обычно хватает для одного агента и пары лёгких конвейеров. Для высоконагруженных логов/трейсов закладывайте больше.
  • Порты: для OTLP откройте 4317/tcp (гRPC) и 4318/tcp (HTTP) только для доверенных источников.
  • Доступ к journald: агенту нужна группа systemd-journal или разрешение чтения каталога /var/log/journal.
  • Часы и хостнейм: синхронизируйте NTP (chrony/systemd‑timesyncd). Некорректное время ломает корреляцию метрик/логов/трейсов.
# Пример базовой подготовки на Debian/Ubuntu
sudo apt update
sudo apt install -y ca-certificates curl unzip ufw

# Пользователь и директории
sudo useradd -r -s /usr/sbin/nologin grafana-agent || true
sudo mkdir -p /etc/agent
sudo mkdir -p /var/lib/agent
sudo chown -R grafana-agent:grafana-agent /etc/agent /var/lib/agent

# Чтение journald (если используете loki.source.journal)
sudo usermod -aG systemd-journal grafana-agent

# Фаервол: откроем OTLP только для доверенной сети
sudo ufw allow from 10.0.0.0/8 to any port 4317 proto tcp
sudo ufw allow from 10.0.0.0/8 to any port 4318 proto tcp
sudo ufw reload

Установка Grafana Agent (Flow)

Устанавливаем бинарник и готовим systemd‑юнит. Ниже пример: сначала попытайтесь поставить пакет из репозитория ОС; при ручной установке поместите заранее бинарник в каталог и используйте install.

# Установка через пакетный менеджер (если доступен)
sudo apt update
sudo apt install -y grafana-agent

# Либо ручная установка бинарника, заранее положив его в /tmp/agent/grafana-agent
sudo install -o root -g root -m 0755 /tmp/agent/grafana-agent /usr/local/bin/grafana-agent

# Проверка версии
/usr/local/bin/grafana-agent --version

Создадим systemd‑юнит и включим режим Flow. Важно: агенту нужен HTTP‑эндпоинт для собственных метрик (мы его будем скрейпить).

# /etc/systemd/system/grafana-agent.service
[Unit]
Description=Grafana Agent (Flow)
After=network-online.target
Wants=network-online.target

[Service]
User=grafana-agent
Group=grafana-agent
ExecStart=/usr/local/bin/grafana-agent run --server.http.listen-addr=127.0.0.1:12345 --config.file=/etc/agent/flow.river
Restart=always
RestartSec=5s
NoNewPrivileges=true
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
AmbientCapabilities=

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable grafana-agent
# Пока не стартуем — сначала подготовим конфиг

River‑конфиг: каркас

Создадим базовый /etc/agent/flow.river с каркасом логирования и переменными окружения. River поддерживает обращения к env(), удобно прокидывать секреты через файловые переменные systemd или окружение.

// /etc/agent/flow.river
logging {
  level  = "info"
  format = "logfmt"
}

// Можно задать глобальные лейблы/теги через env
// Например: export INSTANCE=shop-api-1; export ENV=prod

Пример River‑конфига и схема OTLP‑портов 4317/4318

Метрики: prometheus.scrape и remote_write

Начнём с простого — соберём метрики самого агента и отправим их в ваш TSDB (Prometheus или совместимый по remote_write, например VictoriaMetrics). Если у вас уже есть экспортёры (node_exporter, nginx‑exporter и т.п.), просто добавьте их таргеты в targets.

// Скрейпим self‑metrics агента (по адресу, который указали в ExecStart)
prometheus.scrape "agent_self" {
  job_name        = "grafana-agent"
  scrape_interval = "15s"
  targets = [
    {
      "__address__" = "127.0.0.1:12345"
    }
  ]
  forward_to = [prometheus.remote_write.default.receiver]
}

// Отправляем в TSDB
prometheus.remote_write "default" {
  endpoint {
    url = env("PROM_REMOTE_URL") // например: vm.example:8428/api/v1/write
    // При необходимости добавьте авторизацию:
    // basic_auth {
    //   username = env("PROM_USER")
    //   password = env("PROM_PASS")
    // }
    // bearer_token = env("PROM_TOKEN")
  }
}

Если вы хотите скрейпить дополнительные приложения, добавляйте их таргеты:

// Пример: скрейп Nginx‑экспортёра на localhost:9113
prometheus.scrape "nginx" {
  job_name        = "nginx"
  scrape_interval = "15s"
  targets = [
    {
      "__address__" = "127.0.0.1:9113"
    }
  ]
  forward_to = [prometheus.remote_write.default.receiver]
}

Логи: файлы и journald в Loki

Типичный набор для единого VDS — это логи Nginx и системный журнал. В Flow это делается через компоненты local.file_match, loki.source.file и loki.source.journal с последующей обработкой в loki.process и отправкой в loki.write.

// Куда писать логи в Loki
loki.write "default" {
  endpoint {
    url = env("LOKI_URL") // например: loki.example:3100/loki/api/v1/push
    // basic_auth {
    //   username = env("LOKI_USER")
    //   password = env("LOKI_PASS")
    // }
    // headers = { "X-Scope-OrgID" = env("LOKI_TENANT") }
  }
}

// Описываем файлы логов Nginx
local.file_match "nginx_logs" {
  path_targets = [
    { __path__ = "/var/log/nginx/access.log" },
    { __path__ = "/var/log/nginx/error.log" }
  ]
}

// Источник: читаем файлы
loki.source.file "nginx" {
  targets    = local.file_match.nginx_logs.targets
  forward_to = [loki.process.nginx.receiver]
}

// Обработка: лейблы, мультилайн и т.д.
loki.process "nginx" {
  stage.static_labels {
    values = {
      job  = "nginx",
      host = env("INSTANCE"),
      env  = env("ENV")
    }
  }
  // Для стектрейсов/длинных строк можно объединять строки
  stage.multiline {
    firstline = "^\\S+ - \\S+ \\[\\d{2}/\\w{3}/\\d{4}:\\d{2}:\\d{2}:\\d{2}"
  }
  forward_to = [loki.write.default.receiver]
}

// Системный журнал через journald
loki.source.journal "systemd" {
  labels = {
    job  = "systemd",
    host = env("INSTANCE"),
    env  = env("ENV")
  }
  max_age    = "24h"
  forward_to = [loki.process.systemd.receiver]
}

loki.process "systemd" {
  stage.static_labels { values = { stream = "journal" } }
  forward_to = [loki.write.default.receiver]
}

Следите за кардинальностью лейблов и пайплайнами. Подробно о практиках мы писали в материале Пайплайны лейблов для Loki: экономим и ускоряем.

Трейсы: OTLP‑приёмник и экспорт в Tempo

Трейсы примем от приложений через OTLP (gRPC/HTTP) и отправим в Tempo. Приложения на Go/Node.js/PHP/Python с библиотеками OpenTelemetry умеют отправлять OTLP почти «из коробки».

// Принимаем OTLP от приложений
otelcol.receiver.otlp "ingest" {
  protocols {
    grpc { endpoint = "0.0.0.0:4317" }
    http { endpoint = "0.0.0.0:4318" }
  }
  output {
    traces = [otelcol.processor.batch.default.input]
  }
}

// Батчинг/окно отправки
otelcol.processor.batch "default" {
  timeout         = "5s"
  send_batch_size = 8192
  output {
    traces = [otelcol.exporter.otlp.tempo.input]
  }
}

// Экспорт в Tempo по OTLP (чаще gRPC 4317)
otelcol.exporter.otlp "tempo" {
  client {
    endpoint = env("TEMPO_ENDPOINT") // например: tempo.example:4317
    tls {
      insecure = true // в проде настройте ca_file и проверку сертификата
    }
    // headers = { "X-Scope-OrgID" = env("TEMPO_TENANT") }
  }
}

На стороне приложения часто достаточно указать переменные окружения, чтобы SDK OpenTelemetry стал слать трейсы в агент на localhost:

# Пример для приложения: шлём на локальный агент (gRPC)
export OTEL_EXPORTER_OTLP_ENDPOINT=127.0.0.1:4317
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.1
# Для HTTP используйте порт 4318

Запуск и проверка

Когда конфиги готовы, стартуем службу и проверяем логи агента.

sudo systemctl start grafana-agent
sudo systemctl status grafana-agent
journalctl -u grafana-agent -f

Быстрая проверка:

  • Метрики: Prometheus/VictoriaMetrics должны увидеть новый job="grafana-agent".
  • Логи: в Loki появляются стримы с лейблами job="nginx" и job="systemd".
  • Трейсы: в Tempo начинают приходить спаны от вашего приложения.

Безопасность: доступы, TLS и минимизация поверхности

Набор базовых мер, которые не стоит пропускать:

  • OTLP‑порты 4317/4318 открывайте только для доверенных источников или вовсе слушайте на 127.0.0.1, если приложение живёт на той же машине.
  • Используйте аутентификацию к удалённым бэкендам: basic_auth/Bearer в prometheus.remote_write, loki.write, заголовки/токены в otelcol.exporter.otlp.
  • Шифруйте трафик к внешним бэкендам по TLS и включайте верификацию сертификата. При необходимости оформите SSL-сертификаты для своих публичных эндпоинтов.
  • Ограничьте системные привилегии сервиса через systemd (ProtectSystem, NoNewPrivileges и т.д.).
  • Следите за составом лейблов в логах: слишком высокая кардинальность ведёт к росту счета в Loki.

Оптимизация ресурсов: частоты, буферы, кардинальность

Чтобы агент потреблял мало CPU и RAM, настройте:

  • Интервалы скрейпа: для большинства сервисов достаточно 15–30s.
  • Отбрасывание шума: в логах используйте loki.process для нормализации и объединения строк, выпиливайте бессмысленные лейблы.
  • Батчинг трейсов: otelcol.processor.batch снижает overhead сетевых вызовов.
  • Бэкап очередей: агент выдержит кратковременные отказы бэкендов, но не превращайте его в очередь «на века».

Дашборды Grafana с метриками, логами и трейсами

Надёжность: что делать при падениях бэкенда

Если Loki/Tempo/TSDB временно недоступны, главное — не потерять данные и не «захлебнуть» сервер. Практические советы:

  • Логи: держите размер журналов под контролем, ограничьте количество и размер файлов в /var/log, используйте logrotate. Агент дочитает хвост, когда бэкенд оживёт.
  • Трейсы: снижайте частоту сэмплинга в приложениях при деградации (например, 0.01 вместо 0.1), чтобы не забить сеть/память.
  • Метрики: временные провалы remote_write переживут ретраи; для регулярных простоев подумайте о повышении надёжности канала.
FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Тонкости конфигурации Flow: читаемость и поддержка

Несколько рекомендаций по стилю River:

  • Именуйте компоненты по назначению: prometheus.scrape "nginx", loki.process "systemd" и т.д.
  • Группируйте блоки по доменам (metrics/logs/traces), оставляйте комментарии с форматами логов.
  • Используйте переменные окружения для секретов и эндпоинтов, чтобы один и тот же конфиг легко запускался в dev/stage/prod.
  • Изменения проверяйте по частям: сначала запускайте только раздел metrics, затем logs, затем traces.

Обновления и миграция со «статического» режима

Если у вас уже работал «старый» режим Grafana Agent или отдельный Promtail/OTel Collector, мигрируйте постепенно:

  • Поднимите Flow в параллель с новыми портами и другим лейблом инстанса.
  • Отзеркальте метрики/логи/трейсы на тестовый сторедж и сравните нагрузку и полноту данных.
  • Переключите источники по одному (сначала логи, затем метрики, затем трейсы), уберите старые демоны.

Диагностика неполадок

Самые частые проблемы и быстрые проверки:

  • Permission denied у journald: проверьте группу systemd-journal и перезапуск агента.
  • Порты 4317/4318 заняты: найдите конфликтующий процесс (ss -lntp), поменяйте endpoint или отключите лишнее.
  • Нет метрик в TSDB: проверьте prometheus.remote_write (авторизация/URL), затем prometheus.scrape (доступность таргетов).
  • Нет логов в Loki: проверьте права на файлы, ротацию логов, соответствие путей и лейблов; временно поднимите logging.level = "debug".
  • Нет трейсов в Tempo: убедитесь, что приложение действительно отправляет OTLP, а экспортер в агенте видит endpoint и не ругается на TLS.

Мини‑чеклист перед продом

  • Стабильные DNS и NTP.
  • Ограничены сетевые порты и права доступа.
  • Отключены лишние лейблы с высокой кардинальностью.
  • Сбор нагрузочного профиля: проверьте CPU/RAM бюджет агента.

Полный пример flow.river для старта

Соберём всё вместе в один файл, который можно использовать как основу. Замените переменные окружения на ваши значения.

// /etc/agent/flow.river
logging {
  level  = "info"
  format = "logfmt"
}

// -------------------- METRICS --------------------
prometheus.remote_write "default" {
  endpoint { url = env("PROM_REMOTE_URL") }
}

prometheus.scrape "agent_self" {
  job_name        = "grafana-agent"
  scrape_interval = "15s"
  targets = [{ "__address__" = "127.0.0.1:12345" }]
  forward_to = [prometheus.remote_write.default.receiver]
}

// ---------------------- LOGS ---------------------
loki.write "default" {
  endpoint { url = env("LOKI_URL") }
}

local.file_match "nginx_logs" {
  path_targets = [
    { __path__ = "/var/log/nginx/access.log" },
    { __path__ = "/var/log/nginx/error.log" }
  ]
}

loki.source.file "nginx" {
  targets    = local.file_match.nginx_logs.targets
  forward_to = [loki.process.nginx.receiver]
}

loki.process "nginx" {
  stage.static_labels {
    values = { job = "nginx", host = env("INSTANCE"), env = env("ENV") }
  }
  stage.multiline { firstline = "^\\S+ - \\S+ \\[" }
  forward_to = [loki.write.default.receiver]
}

loki.source.journal "systemd" {
  labels = { job = "systemd", host = env("INSTANCE"), env = env("ENV") }
  max_age    = "24h"
  forward_to = [loki.process.systemd.receiver]
}

loki.process "systemd" {
  stage.static_labels { values = { stream = "journal" } }
  forward_to = [loki.write.default.receiver]
}

// --------------------- TRACES --------------------
otelcol.receiver.otlp "ingest" {
  protocols {
    grpc { endpoint = "0.0.0.0:4317" }
    http { endpoint = "0.0.0.0:4318" }
  }
  output { traces = [otelcol.processor.batch.default.input] }
}

otelcol.processor.batch "default" {
  timeout         = "5s"
  send_batch_size = 8192
  output { traces = [otelcol.exporter.otlp.tempo.input] }
}

otelcol.exporter.otlp "tempo" {
  client {
    endpoint = env("TEMPO_ENDPOINT")
    tls { insecure = true }
  }
}

Что дальше

Дальше можно наращивать конфигурацию: добавьте парсинг JSON‑логов, структурируйте лейблы, подключите дополнительные экспортёры метрик и автодискавери, включите ресемплинг трейсов, вынесите секреты в EnvironmentFile systemd, добавьте алерты на сбои отправки. Flow хорошо масштабируется: если завтра у вас станет два и больше VDS, вы просто повторите агент с тем же конфигом, меняя лейблы инстанса и сетевые ACL.

В итоге вы получаете полноценный стек наблюдаемости из одного бинарника, понятный и управляемый, который можно быстро «поднять, проверить и забыть» — до следующего релиза.

Поделиться статьей

Вам будет интересно

systemd-nspawn на VDS: лёгкие контейнеры, изоляция и сеть без Kubernetes OpenAI Статья написана AI (GPT 5)

systemd-nspawn на VDS: лёгкие контейнеры, изоляция и сеть без Kubernetes

Как запустить и подружить systemd-nspawn с вашим VDS: развертывание контейнеров, изоляция, bind mounts, сеть и cgroup-лимиты, упра ...
Node.js keepalive и http.Agent: практическая настройка с Nginx и upstream-пулами OpenAI Статья написана AI (GPT 5)

Node.js keepalive и http.Agent: практическая настройка с Nginx и upstream-пулами

Разбираем пул http.Agent в Node.js и практику keepalive: какие параметры важны (maxSockets, freeSocketTimeout, socketActiveTTL), к ...
PostgreSQL: HOT UPDATE, fillfactor и борьба с bloat без боли OpenAI Статья написана AI (GPT 5)

PostgreSQL: HOT UPDATE, fillfactor и борьба с bloat без боли

HOT UPDATE экономит обновления индексов и сдерживает bloat, но срабатывает не всегда. Разбираем, как работает HOT, как выбрать fil ...