Зачем нужен Vector и какую задачу он решает
Vector - агент и маршрутизатор логов от Datadog, написанный на Rust. Один бинарник собирает события из journald, файлов, Docker-контейнеров и Windows Event Log, приводит их к единому виду и отправляет в Graylog, Loki, OpenSearch, Elasticsearch, ClickHouse или другое хранилище. Ни JVM, ни Python не нужны: на Linux агент работает как systemd-сервис, на Windows как служба, в Docker как контейнер.
Практический сценарий статьи: смешанная инфраструктура, где есть серверы Linux, хосты Windows и контейнеры Docker, а логи нужно свести в централизованное хранилище и не потерять их при сбоях. Ниже - готовые конфигурации для источников journald, file, docker_logs и event_log, трансформации на VRL, маршрутизация по уровням логирования, отправка в пять популярных хранилищ, дисковая буферизация и чек-лист диагностики.
Коротко: source читает события, transform приводит их к общей схеме, sink отправляет по назначению. Весь конвейер описывается одним конфигом, а vector validate и vector top позволяют проверить его до и после запуска.
Ключевые возможности: источники, трансформации, sinks
Конфигурация Vector собирается из трех типов компонентов, и поток данных идет по цепочке source → transform → sink.
- Sources читают события: journald (systemd-журнал), file (файлы с ротацией), docker_logs (контейнеры через Docker API), event_log (каналы Windows Event Log), syslog (сетевое оборудование), internal_metrics (метрики самого агента).
- Transforms обрабатывают поток: remap на языке VRL парсит и обогащает события, filter отбрасывает лишнее, route разделяет поток на ветки.
- Sinks отправляют данные: gelf (Graylog), loki, elasticsearch (для Elasticsearch и OpenSearch), clickhouse, aws_s3, kafka, prometheus_exporter.
Компоненты связываются параметром inputs: sink указывает имена source или transform, от которых получает события. Один источник питает несколько приемников, поэтому копию критичных логов легко отправить в Loki для быстрого поиска и в S3 для долгого хранения. Конфигурация описывается в TOML, YAML или JSON; топология видна целиком в одном файле.
Vector vs Fluent Bit vs Filebeat: когда что выбирать
Все три агента решают похожую задачу с разными компромиссами. Таблица ниже показывает ключевые для выбора параметры.
| Критерий | Vector | Fluent Bit | Filebeat |
|---|---|---|---|
| Язык, зависимости | Rust, один бинарник | C, один бинарник | Go, один бинарник |
| Память | Обычно 50-150 МБ | 1-10 МБ | 50-100 МБ |
| Windows Event Log | Source event_log с фильтром по каналам | Input winlog в Windows-сборках | Отдельный агент Winlogbeat |
| Трансформации | VRL: функции, тесты, компиляция при старте | Фильтры и Lua-скрипты | Processors без языка |
| Дисковая буферизация | Штатная, с подтверждениями доставки | Filesystem storage | Disk queue |
| Когда выбирать | Разнородный парк, сложная обработка, несколько хранилищ | Edge и минимальный footprint | Стек Elastic уже развернут |
Fluent Bit выигрывает там, где важен каждый мегабайт памяти: IoT-шлюзы, сетевые устройства, sidecar-контейнеры с жесткими лимитами. Filebeat логично брать, когда Elasticsearch уже работает и нужен минимум настройки. Vector оправдан при смешанной инфраструктуре: с одного хоста нужно читать journald, файлы приложения и Docker-контейнеры, а затем раскладывать события по двум-трем приемникам с разными форматами и схемами.
Promtail переведен Grafana Labs в режим долгосрочной поддержки, для новых инсталляций предлагается Grafana Alloy. Если в парке уже есть Vector, отдельный агент под Loki не требуется: sink loki отправляет логи напрямую. Выбор стека хранения с готовыми docker-compose конфигурациями разобран в обзоре систем сбора и анализа логов 2026 года.
Установка Vector на Linux, Windows и в Docker
Vector распространяется как один бинарник и как пакеты для основных платформ. Конфиг по умолчанию лежит в /etc/vector/vector.toml на Linux и в C:\Program Files\Vector\config\vector.toml на Windows, рабочие данные (чекпоинты и дисковые буферы) хранятся в каталоге data_dir.
Linux
Пакет ставится из официального APT- или YUM-репозитория, служба systemd включается одной командой:
sudo systemctl enable --now vector
systemctl status vector
Установщик создает системного пользователя vector. Чтобы читать системный журнал, добавьте его в группу systemd-journal и перезапустите службу:
sudo usermod -aG systemd-journal vector
sudo systemctl restart vector
Для логов Docker на хосте пользователю нужен доступ к /var/run/docker.sock: проще всего добавить его в группу docker. Доступ к сокету дает права уровня root, поэтому на критичных хостах безопаснее запускать Vector в контейнере с примонтированным сокетом или выдать точечные права через ACL.
Windows
Для Windows есть MSI-установщик и ZIP-архив. MSI кладет бинарник в C:\Program Files\Vector и регистрирует службу; при установке из архива служба создается вручную:
vector --config "C:\Program Files\Vector\config\vector.toml" --service install
vector --service start
Служба запускается от LocalSystem или отдельной учетной записи с правом чтения нужных каналов Event Log. Для канала Security на контроллерах домена удобнее выделенная сервисная учетная запись с ограниченными правами.
Docker
Образ называется timberio/vector, доступны варианты на базе Debian и Alpine. Контейнеру нужны сокет Docker, конфиг и volume для данных, чтобы дисковый буфер переживал пересоздание:
docker run -d --name vector \
--restart unless-stopped \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v /etc/vector/vector.toml:/etc/vector/vector.toml:ro \
-v vector-data:/var/lib/vector \
timberio/vector:latest-debian
Если Vector запущен прямо на хосте, достаточно прав пользователя vector на сокет. Для Kubernetes есть режим DaemonSet с source kubernetes_logs: агент на каждой ноде читает логи подов из каталога kubelet.
Проверка конфигурации: vector validate и vector top
Перед перезапуском службы проверяйте конфиг:
vector validate --config /etc/vector/vector.toml
Команда разбирает файл, компилирует программы VRL и проверяет связи между компонентами. Ненулевой код возврата означает ошибку, а текст укажет компонент и причину. Для наблюдения за потоком в реальном времени есть vector top: таблица со счетчиками событий и ошибок по каждому компоненту.
vector top
Если счетчик на source растет, а на sink стоит на нуле, ищите проблему в transform или в соединении с хранилищем: vector top показывает, где именно поток останавливается.
Сбор логов из Linux: journald и файловые логи
На Linux есть два основных источника: systemd-журнал и текстовые файлы. Первый закрывает службы, которые пишут в journald, второй - Nginx, приложения и остальное содержимое /var/log. Оба источника включаются в одном конфиге и сводятся в общий конвейер.
Настройка source journald с фильтрацией по unit
[sources.journald]
type = 'journald'
include_units = ['nginx.service', 'sshd.service', 'postgresql.service']
current_boot_only = true
Параметр include_units ограничивает чтение перечисленными службами, exclude_units исключает ненужные. Без фильтров Vector вычитывает весь журнал вместе с системным шумом. current_boot_only = true читает только события текущей загрузки: на хостах с большим журналом это ускоряет первый запуск. Позиция чтения сохраняется в data_dir, поэтому после перезапуска агент продолжит с того же места.
Требование одно: доступ к журналу. Пользователь vector должен состоять в группе systemd-journal, иначе source не получит события, а в журнале службы появится ошибка доступа. В контейнерах journald недоступен без проброса сокета хоста.
Чтение файлов с ротацией: glob, ignore_older_secs, read_from
[sources.nginx_logs]
type = 'file'
include = ['/var/log/nginx/access.log', '/var/log/nginx/error.log']
ignore_older_secs = 86400
read_from = 'beginning'
Vector отслеживает файлы по inode и внутреннему отпечатку, а позиции хранит в чекпоинтах внутри data_dir. При ротации (logrotate переименовывает файл и создает новый) агент дочитывает переименованный файл до конца и переключается на новый. Параметр read_from работает только при первом запуске, когда чекпоинта еще нет: beginning читает файл с начала, end - с конца. ignore_older_secs отсеивает файлы, которые не менялись дольше суток, чтобы первый запуск не вычитывал гигабайты старых логов.
Для многострочных записей, например stack trace Java, включается секция multiline:
[sources.app_logs]
type = 'file'
include = ['/var/log/app/*.log']
[sources.app_logs.multiline]
start_pattern = '^\d{4}-\d{2}-\d{2}'
mode = 'continue_through'
timeout_ms = 2000
Событие начинается строкой, которая подходит под start_pattern, следующие строки присоединяются к нему, пока не встретится новый старт. timeout_ms закрывает событие, если следующая строка задерживается.
Права доступа проверяйте заранее: пользователь vector должен читать каталог и файлы. Для Nginx на Debian и Ubuntu достаточно группы adm, альтернатива - ACL на каталог /var/log/nginx. Для syslog-потока с сетевого оборудования добавьте отдельный источник:
[sources.syslog_net]
type = 'syslog'
mode = 'udp'
address = '0.0.0.0:514'
Порт 514 требует прав root или возможности CAP_NET_BIND_SERVICE; чаще агент слушает 1514, а трафик перенаправляет firewall или rsyslog.
Сбор логов из Windows: Event Log и файлы
Вместо journald на Windows используется source event_log: он читает каналы Application, System и Security. Конфиг минимален, но предъявляет требования к учетной записи службы.
[sources.windows_events]
type = 'event_log'
channels = ['Application', 'System', 'Security']
start_at = 'beginning'
Каналы перечисляются в channels, start_at = 'beginning' заставляет прочитать существующие записи с начала канала при первом запуске. На контроллере домена Security-журнал наполняется десятками тысяч событий в сутки: первый проход лучше ограничить или сразу отфильтровать шум, иначе агент загрузит канал и хранилище.
Права доступа и запуск Vector как службы Windows
Запускайте Vector как службу от LocalSystem или выделенной учетной записи с правом чтения Event Log. При ручном запуске нужна консоль с повышенными правами: без них каналы Application и System читаются, а Security возвращает ошибку доступа.
Проверка прав занимает минуту: откройте Event Viewer, убедитесь, что в каналах есть свежие записи, затем посмотрите счетчики source в vector top. Если события не идут, в первую очередь проверяйте учетную запись службы.
Фильтрация событий и файловые логи
Шумные события отбрасываются на уровне VRL. Например, вход и выход из системы (event_id 4624 и 4634) часто не нужны в общем потоке:
[transforms.win_filter]
type = 'remap'
inputs = ['windows_events']
source = '''
if .event_id == 4624 || .event_id == 4634 {
abort
}
'''
Имена полей зависят от канала и источника события, поэтому сначала выведите несколько записей в console sink и посмотрите реальную структуру. Функция abort() отбрасывает событие целиком, до приемника оно не дойдет.
Текстовые логи Windows читаются тем же source file. Для IIS-логов конфиг выглядит так:
[sources.iis_logs]
type = 'file'
include = ['C:\inetpub\logs\LogFiles\W3SVC1\*.log']
ignore_older_secs = 3600
Пути в одинарных кавычках TOML не требуют экранирования обратных слэшей. Glob-шаблоны и ротация работают так же, как в Linux.
Сбор логов Docker-контейнеров
Для контейнеров есть два пути: source docker_logs, который общается с Docker API и знает метаданные контейнера, и чтение JSON-файлов из /var/lib/docker/containers через source file. Первый вариант практичнее: в события автоматически попадают имя контейнера, образ, идентификатор и метки.
[sources.docker]
type = 'docker_logs'
docker_host = 'unix:///var/run/docker.sock'
include_containers = ['nginx', 'api']
Параметр docker_host указывает сокет или TCP-endpoint Docker, include_containers и exclude_containers фильтруют по именам, include_labels и exclude_labels по меткам. Vector подписывается на события Docker и подключается к логам новых контейнеров без перезапуска. В каждом событии доступны container_name, container_id, image, container_created_at и поля меток: их удобно использовать в labels Loki или в индексах Elasticsearch.
Фильтрация контейнеров по label и имени
[sources.docker]
type = 'docker_logs'
include_labels = ['logging=enabled']
Метка задается при запуске: docker run --label logging=enabled ... или в секции labels файла docker-compose.yml. Такой фильтр стабильнее списка имен: новые контейнеры с нужной меткой подхватываются сами, а служебные контейнеры остаются за бортом.
Альтернатива через файлы:
[sources.docker_files]
type = 'file'
include = ['/var/lib/docker/containers/*/*-json.log']
Минус в том, что в событии нет имени контейнера и меток: идентификатор придется извлекать из пути средствами VRL. Плюс в том, что не нужен доступ к Docker API. Для rootless Docker сокет лежит в /run/user/<uid>/docker.sock и доступен только владельцу.
Ограничение драйверов: docker_logs читает логи через API Docker, и это работает для драйверов json-file и local. С драйверами journald, fluentd и gelf API логи не отдает, такие потоки собираются настройками самого драйвера.
Трансформация и маршрутизация логов с помощью VRL
Сырые логи различаются форматом и шумят. Слой transforms приводит поток к единой схеме: одинаковые поля времени, уровня, сервиса и окружения, отброшенный мусор, разложенные по веткам события. Для этого есть transform remap с языком VRL, filter и route.
Практические примеры VRL: парсинг, обогащение, маскирование
Docker-логи приходят одним полем message. Если приложение пишет JSON, его разворачивают в событие:
[transforms.parse_docker]
type = 'remap'
inputs = ['docker']
source = '''
parsed, err = parse_json(.message)
if err == null {
. = merge(., parsed)
} else {
.parse_error = true
}
'''
Для Nginx в VRL есть готовый парсер:
[transforms.parse_nginx]
type = 'remap'
inputs = ['nginx_logs']
source = '''
. = parse_nginx_log!(.message, "combined")
'''
Суффикс ! превращает ошибку разбора в abort: событие, которое не удалось распарсить, не пойдет дальше с мусорными полями. Маскирование секретов и обогащение добавляются в тот же remap:
[transforms.cleanup]
type = 'remap'
inputs = ['parse_docker', 'parse_nginx']
source = '''
del(.password)
del(.request_headers.authorization)
.environment = "prod"
.datacenter = "dc1"
'''
Программы удобно проверять в интерактивной оболочке vector vrl: она принимает код и пример события, показывает результат и ошибки. Синтаксические ошибки VRL всплывают на vector validate, поэтому битый конфиг не дойдет до службы.
Маршрутизация: route по уровню логирования и источнику
Transform route делит поток на именованные ветки. Условие каждой ветки - выражение VRL, событие попадает во все ветки, чьи условия совпали:
[transforms.split]
type = 'route'
inputs = ['cleanup']
[transforms.split.route.errors]
type = 'vrl'
source = '.level == "error" || .level == "fatal"'
[transforms.split.route.audit]
type = 'vrl'
source = '.unit == "sshd.service"'
[transforms.split.route.rest]
type = 'vrl'
source = 'true'
Sinks подключаются к веткам через inputs = ['split.errors'], ['split.audit'] и ['split.rest']. Типовой шаблон: ошибки идут в Graylog, где дежурный видит их в реальном времени, остальное в Loki для поиска по контексту, аудит в ClickHouse для долгого хранения. Разделение потоков снижает нагрузку: тяжелые хранилища получают только нужные события.
Топологию удобно проверить командой vector graph: она печатает граф связей между компонентами. Больше примеров маршрутизации с приоритетами и тегами собрано в статье про конвейер логов и метрик с Fluentd, Prometheus и Grafana.
Отправка логов в Graylog, Loki, OpenSearch, Elasticsearch и ClickHouse
Sinks подключаются к источникам или веткам route. Ниже рабочие конфиги для пяти хранилищ. Что выбрать под задачу, разобрано в материале ELK, Loki и Graylog: сравнение архитектур и конфигов, а здесь сфокусируемся на стороне Vector.
Graylog: GELF sink и структурированные поля
[sinks.graylog]
type = 'gelf'
inputs = ['split.errors']
endpoint = 'http://graylog.internal:12201'
Схема endpoint определяет транспорт: http:// отправляет по HTTP, udp:// и tcp:// переключают на соответствующие порты GELF. Поля верхнего уровня события становятся дополнительными полями GELF автоматически: host, level и все обогащения из VRL видны в поиске Graylog. На стороне Graylog должен быть открыт input типа GELF HTTP или GELF UDP.
Loki: labels, batch, out_of_order_action
[sinks.loki]
type = 'loki'
inputs = ['split.rest']
endpoint = 'http://loki.internal:3100'
out_of_order_action = 'drop'
labels = { job = 'vector', host = '{{ host }}', environment = '{{ environment }}' }
[sinks.loki.batch]
max_bytes = 1048576
timeout_secs = 5
labels формируют индекс Loki, и это узкое место: значения должны быть низкокардинальными. job, host и environment подходят, а request_id, user_id и trace_id нет: тысячи уникальных значений раздуют индекс и замедлят запросы. Такие поля оставляйте в теле записи и ищите по ним полнотекстовым поиском. out_of_order_action = 'drop' отбрасывает события со старым timestamp, которые Loki не примет из-за политики упорядоченности. Для мультитенантного Loki задайте tenant_id статической строкой или шаблоном события.
Elasticsearch и OpenSearch: индексы, auth, bulk
[sinks.opensearch]
type = 'elasticsearch'
inputs = ['split.rest']
endpoints = ['https://opensearch.internal:9200']
mode = 'bulk'
index = 'logs-%Y.%m.%d'
compression = 'gzip'
[sinks.opensearch.auth]
strategy = 'basic'
user = 'vector'
password = 'secret'
[sinks.opensearch.tls]
verify_certificate = true
Для OpenSearch используется тот же sink elasticsearch: API совместимы, различия сводятся к настройкам кластера. Шаблон index с датой дает суточную ротацию, что упрощает управление retention. Аутентификация настраивается стратегиями basic или api_key, для самоподписанных сертификатов в секции tls указывается ca_file. Учетная запись Vector должна иметь право создавать индексы по шаблону и писать в них.
Маппинг полей задавайте через index template заранее. Иначе первый документ, где числовое поле пришло строкой, зафиксирует тип, и последующие записи с другим типом будут падать с ошибкой 400.
ClickHouse: таблица, формат, batch
[sinks.clickhouse]
type = 'clickhouse'
inputs = ['split.audit']
endpoint = 'http://clickhouse.internal:8123'
database = 'logs'
table = 'vector_logs'
format = 'json_each_row'
skip_unknown_fields = true
[sinks.clickhouse.auth]
strategy = 'basic'
user = 'vector'
password = 'secret'
[sinks.clickhouse.batch]
max_events = 50000
timeout_secs = 5
Таблицу создайте заранее: Vector вставляет данные, но не управляет схемой. skip_unknown_fields = true защищает от ошибок, когда в событии появилось поле, которого нет в таблице. Формат json_each_row отправляет по одному JSON-объекту на строку и подходит для HTTP-интерфейса ClickHouse на порту 8123. Батч сглаживает пики: ClickHouse не любит сотни мелких вставок в секунду. Схема таблицы, TTL и партиционирование разобраны в статье про запись логов в ClickHouse через Vector.
Надёжность: буферизация, retry и контроль нагрузки
Логи теряются в двух случаях: хранилище недоступно, а буфер в памяти переполнен, или агент перезапустился и несохраненные события пропали. Дисковая буферизация и подтверждения доставки закрывают оба сценария.
Дисковая буферизация: когда включать и как настроить
[sinks.graylog.buffer]
type = 'disk'
max_size = 268435488
when_full = 'block'
По умолчанию sink держит буфер в памяти (max_events = 500). Дисковый буфер пишет события в файл внутри data_dir и переживает перезапуск агента: накопленное уйдет в хранилище, когда связь восстановится. Параметр when_full решает, что делать при заполнении: block останавливает чтение источника и создает обратное давление, drop_newest отбрасывает новые события. Для аудита и Security-логов выбирайте block, для потоков с высокой скоростью и низкой ценой потери допустим drop_newest.
Полную гарантию доставки дает связка disk buffer и acknowledgements. Подтверждения включаются в источнике, который их поддерживает:
[sources.nginx_logs]
type = 'file'
include = ['/var/log/nginx/*.log']
acknowledgements = true
В этом режиме чекпоинт файла не сдвигается, пока событие не записано в приемник. После падения агента недоставленные события отправятся повторно: доставка становится at-least-once, а дубли отсекаются на стороне хранилища, например по хешу события.
При ошибках sink Vector повторяет отправку с экспоненциальной паузой. Число попыток и интервалы задают параметры retry_attempts, retry_initial_backoff_secs и retry_max_duration_secs. По умолчанию повторы не ограничены, и для продакшена это обычно то, что нужно: событие не потеряется, а нагрузка на упавшее хранилище останется щадящей.
Мониторинг внутренних метрик Vector
[sources.internal_metrics]
type = 'internal_metrics'
scrape_interval_secs = 15
[sinks.prometheus]
type = 'prometheus_exporter'
inputs = ['internal_metrics']
address = '0.0.0.0:9598'
После этого Prometheus собирает метрики на порту 9598. Смотрите четыре показателя: component_received_events_total и component_sent_events_total (поток на входе и выходе), component_errors_total (ошибки) и utilization (загрузка компонента от 0 до 1). Растущий разрыв между received и sent при высокой utilization означает, что sink не справляется и буфер заполняется: пора увеличивать батчи, добавлять узлы хранилища или ограничивать поток на источнике.
Резервную копию потока удобно писать в объектное хранилище: sink aws_s3 складывает логи в бакет с сжатием и разбивкой по времени. Схема с архивом в S3 на базе TrueNAS разобрана в руководстве: централизованный сбор логов в S3.
Диагностика и отладка конфигурации
Когда события не доходят до хранилища, проверки идут по цепочке от источника к приемнику. Шесть шагов покрывают большинство случаев.
- vector validate --config /path/vector.toml проверяет синтаксис, связи компонентов и компиляцию VRL.
- vector top показывает, растут ли счетчики на source, проходит ли поток через transforms и отправляет ли sink.
- Console sink выводит события в stdout в том виде, в каком их получит хранилище.
- Права доступа: группы systemd-journal и docker, ACL на файлы логов, учетная запись службы Windows.
- Сетевой доступ: проверьте endpoint приемника с того же хоста (curl, nc или telnet).
- Логи самого Vector: journalctl -u vector на Linux, консольный запуск на Windows.
Console sink: вывод событий в stdout для отладки
[sinks.debug]
type = 'console'
inputs = ['parse_docker']
encoding.codec = 'json'
Добавьте console sink в конец цепочки, остановите службу и запустите Vector в foreground командой vector --config /etc/vector/vector.toml. На экран пойдет поток событий в том виде, в каком их получит хранилище. Так проверяются имена полей после VRL, кодировка сообщений и корректность timestamp. Для отладки filter и route подключайте console sink к каждой ветке по очереди.
Типичные ошибки и их решения
- Source journald пуст: пользователь vector не в группе systemd-journal или система не использует systemd.
- Docker socket недоступен: Vector не в группе docker, сокет не примонтирован в контейнер, для rootless Docker проверьте путь /run/user/<uid>/docker.sock.
- Loki отвечает 400: высокая кардинальность labels или слишком старый timestamp; проверьте набор labels и out_of_order_action.
- Elasticsearch или OpenSearch отвечает 400: конфликт маппинга или неверный шаблон индекса, 401 указывает на неверные учетные данные.
- Windows Event Log пуст: служба запущена без прав на канал Security или указано неверное имя канала.
- Файлы не читаются: нет прав на каталог, файл старше ignore_older_secs или позиция уже сохранена в чекпоинте.
- События есть в source, но не в sink: ошибка в условии route или фильтр отбросил поток; подключите console sink к промежуточной ветке.
Итог: проверенная конфигурация и что дальше
Vector закрывает весь путь логов: чтение из journald, файлов, Docker и Windows Event Log, обработка на VRL, маршрутизация по веткам и отправка в Graylog, Loki, OpenSearch, Elasticsearch, ClickHouse и другие приемники. Надежность обеспечивают дисковая буферизация, повторы и подтверждения доставки, а vector validate и vector top упрощают отладку.
Сводный конфиг ниже соединяет все блоки статьи: три источника, парсинг, маршрутизацию и три приемника.
data_dir = '/var/lib/vector'
[sources.journald]
type = 'journald'
include_units = ['nginx.service', 'sshd.service']
current_boot_only = true
[sources.nginx_logs]
type = 'file'
include = ['/var/log/nginx/*.log']
ignore_older_secs = 86400
[sources.docker]
type = 'docker_logs'
include_labels = ['logging=enabled']
[transforms.parse_docker]
type = 'remap'
inputs = ['docker']
source = '''
parsed, err = parse_json(.message)
if err == null {
. = merge(., parsed)
}
'''
[transforms.parse_nginx]
type = 'remap'
inputs = ['nginx_logs']
source = '''
. = parse_nginx_log!(.message, "combined")
'''
[transforms.split]
type = 'route'
inputs = ['journald', 'parse_docker', 'parse_nginx']
[transforms.split.route.errors]
type = 'vrl'
source = '.level == "error" || .level == "fatal"'
[transforms.split.route.rest]
type = 'vrl'
source = 'true'
[sinks.graylog]
type = 'gelf'
inputs = ['split.errors']
endpoint = 'http://graylog.internal:12201'
[sinks.graylog.buffer]
type = 'disk'
max_size = 268435488
when_full = 'block'
[sinks.loki]
type = 'loki'
inputs = ['split.rest']
endpoint = 'http://loki.internal:3100'
labels = { job = 'vector', host = '{{ host }}' }
[sinks.opensearch]
type = 'elasticsearch'
inputs = ['split.rest']
endpoints = ['https://opensearch.internal:9200']
index = 'logs-%Y.%m.%d'
Начните с одного источника и одного приемника, убедитесь по vector top, что счетчики растут, затем добавляйте дисковый буфер и новые ветки маршрутизации. Каждый шаг проверяйте через vector validate: такой порядок снижает риск ошибок и упрощает поиск причины, если события перестанут доходить.
Если центрального узла с Graylog, Loki или агрегатором Vector еще нет, его можно разместить на облачном сервере. Например, Timeweb Cloud предоставляет серверы, VDS/VPS, хранилища и Kubernetes: этого достаточно и для тестового контура логирования, и для продакшен-связки хранилищ. Заранее оцените суточный объем логов и заложите диск под буферы агентов.