Vector — агент и агрегатор логов, написанный на Rust. Один бинарник собирает данные из файлов, journald, syslog и сетевых источников, приводит их к общему виду и отправляет в несколько хранилищ. В отличие от связки Filebeat плюс Logstash, здесь нет JVM и двух разных языков конфигурации: топология описывается в одном файле, а обработка — на языке VRL. Разберём установку, конфиг для Nginx и journald, маршрутизацию и диагностику.
Топология: источники, преобразования, приёмники
Конфигурация Vector — это граф. Секция sources описывает, откуда читать; transforms меняют события; sinks отправляют результат. Каждый компонент имеет имя и список входов, поэтому один поток легко разветвить: часть логов уйдёт в Loki, часть — в файловый архив, а ошибки — в отдельный индекс.
- Агент ставится на каждый хост и читает локальные файлы.
- Агрегатор принимает данные по сети и централизованно раскладывает их.
- Буфер на диске переживает перезапуск и кратковременную недоступность приёмника.
- VRL позволяет разбирать и обогащать события без внешних скриптов.
Vector требователен к диску при включённом буфере, но заметно экономнее JVM-решений по памяти. Для домашней лаборатории хватит 256–512 МБ.
Vector или альтернативы
Fluent Bit занимает меньше памяти и проще встраивается в Kubernetes, но его фильтры беднее. Filebeat хорошо дружит с Elasticsearch, зато хуже маршрутизирует. Logstash гибок, однако JVM съедает сотни мегабайт. Vector выбирают, когда нужны единый конфиг, несколько приёмников и обработка без внешних плагинов. Если на хосте меньше 128 МБ свободной памяти, смотрите в сторону Fluent Bit.
Установка
Официальный скрипт ставит бинарник в домашний каталог. Для службы удобнее системный пакет или контейнер.
curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev | bash
~/.vector/bin/vector --version
sudo install -m 0755 ~/.vector/bin/vector /usr/local/bin/vector
В контейнере смонтируйте каталог с конфигом и логи. Для journald дополнительно пробросьте сокет /run/systemd/journal/socket.
docker run --rm -v /etc/vector:/etc/vector:ro -v /var/log:/var/log:ro \
timberio/vector:latest-debian --config /etc/vector/vector.yaml
При установке из пакета служба работает от пользователя vector, и ему нужен доступ к журналу: sudo usermod -aG systemd-journal vector. После изменения групп перезапустите службу, иначе чтение journald останется запрещённым.
Если ставите бинарник вручную, создайте unit-файл. Он перезапускает процесс при сбое и ждёт сеть перед стартом.
sudo tee /etc/systemd/system/vector.service >/dev/null <<'EOF'
[Unit]
Description=Vector log agent
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/vector --config /etc/vector/vector.yaml
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now vector
Рабочий конфиг для Nginx и journald
Начнём с источников. Файловый источник читает строки и запоминает позицию; journald забирает записи через системный API.
sources:
nginx_access:
type: file
include: ["/var/log/nginx/access.log"]
read_from: beginning
journal:
type: journald
include_units: ["nginx.service"]
Теперь преобразования. Для access-лога есть готовый парсер parse_nginx_log; для journald достаточно убрать лишние служебные поля и выставить общее имя сервиса.
transforms:
nginx_parse:
type: remap
inputs: [nginx_access]
source: |
parsed, err = parse_nginx_log(.message, "combined")
if err == null {
. = merge(., parsed)
}
.service = "nginx"
.host = get_hostname!()
journal_clean:
type: remap
inputs: [journal]
source: |
.service = "systemd"
.host = get_hostname!()
del(.SYSLOG_FACILITY)
del(._BOOT_ID)
Приёмники завершают граф. Loki получает оба потока с метками, файловый архив хранит только access-лог в JSON.
sinks:
loki:
type: loki
inputs: [nginx_parse, journal_clean]
endpoint: http://127.0.0.1:3100
labels:
service: "app-{{ service }}"
host: "node-{{ host }}"
encoding:
codec: json
archive:
type: file
inputs: [nginx_parse]
path: /var/log/vector/nginx-%Y-%m-%d.log
encoding:
codec: json
Префиксы app- и node- нужны не для красоты: свежие версии Vector требуют у шаблонов меток статический префикс и отклоняют полностью динамические значения.
VRL: разбор без регулярных страданий
VRL — небольшой язык выражений с явной обработкой ошибок. Функции с восклицательным знаком завершают обработку при ошибке, безопасный вариант возвращает пару «значение и ошибка». Проверить выражение можно в интерактивной консоли:
vector vrl
> parse_json!("{\"status\":500,\"path\":\"/api\"}")
> parse_regex!(.message, r'^(?P<ip>\S+) (?P<code>\d{3})')
Типичные операции: parse_json, parse_regex, to_int, merge, del, abort. Не оставляйте ошибки разбора без ветки else: иначе одно кривое сообщение может оборвать обработку события.
Маршрутизация и буферы
Преобразований route и filter достаточно для большинства схем. Фильтр отбрасывает отладочные записи, маршрутизатор раскладывает события по именам выходов, а разные приёмники подписываются на нужные ветки.
transforms:
split_errors:
type: route
inputs: [nginx_parse]
route:
errors: '.status >= 500'
normal: 'true'
В секции inputs у приёмника укажите split_errors.errors или split_errors.normal. Условие true работает как ветка по умолчанию. Для каждого приёмника можно включить дисковый буфер:
buffer:
type: disk
max_size: 2147483648
when_full: drop_newest
Режим block останавливает чтение источника, пока буфер полон, и создаёт обратное давление. drop_newest теряет новые события, зато не тормозит приложение. Выбирайте осознанно: для аудита лучше block и большой диск, для отладочного потока допустим drop.
Наблюдаемость и диагностика
Включите API и внутренние метрики, чтобы видеть, сколько событий принимает и отправляет каждый компонент. Если секции уже объявлены, добавьте в них только новые компоненты.
api:
enabled: true
address: 127.0.0.1:8686
sources:
internal_metrics:
type: internal_metrics
sinks:
prometheus:
type: prometheus_exporter
inputs: [internal_metrics]
address: 127.0.0.1:9598
Проверка конфигурации не требует запуска: vector validate --no-environment /etc/vector/vector.yaml. Ошибки чтения файлов и права доступа видны в journalctl -u vector. Если события не доходят, сравните счётчики vector_component_received_events_total и vector_component_sent_events_total на порту 9598. Рассинхрон означает проблему с приёмником, а не с источником.
Интерактивный просмотр топа компонентов доступен командой vector top при включённом API. Не публикуйте порты 8686 и 9598 наружу: они не предполагают аутентификацию.
Для быстрой проверки отправьте тестовое событие через источник demo_logs и убедитесь, что оно появилось в приёмнике. Если метрики растут, а записей нет, проверьте формат меток Loki и права на запись в файловый архив.
Итог
Vector закрывает задачи сбора и маршрутизации логов одним бинарником и одним конфигом. Начните с двух источников и одного приёмника, проверьте схему через vector validate, затем добавляйте фильтры и дисковый буфер. Держите метрики компонентов под наблюдением: они быстро показывают, где теряются события. Проверяйте каждое изменение на тестовом стенде и расширяйте схему постепенно.