Коллектор логов на старом железе или встречайте Vector 32bit

от автора

В любой большой компании, и X5 не исключение, имеется «старое железо» которое успешно работает и работает хорошо, но приходит время и с него тоже необходимо начать забирать логи и метрики. В нашем случае это машины c x86_32 Debian 9.5 и 512Мб оперативной памяти.

Небольшой Disclaimer

Автор статьи не является экспертом по языку Rust и соответственно любые улучшения, и конкретные рекомендации от гуру приветствуются. Статья не является рекламой Vector и автор никак не связан с компанией Timber и ее контрибуторами. Все ниже описанное является чистым DIY экспериментом с целью показать, что нет непреодолимых барьеров, если очень хочется.

Итак, начнем

Речь пойдет о Vector версии 0.10.0, хотя модный и хайповый лог коллектор только недавно обновился до версии 0.11.0, возможно этот способ подойдет и для него )))

Нам в компании X5 нравится Vector и мы хотели его попробовать на архитектуре x86_32. Тогда как из коробки он доступен для почти любых операционок в двух архитектурах x86_64 и ARM7.

Собирать будем в Docker на основе рекомендаций изложенных тут:
https://vector.dev/docs/setup/installation/manual/from-source/#compiling-using-docker

Описание по ссылке выше подходит только частично, так как нам нужна некая i686-unknown-linux-gnu конфигурация для Rust, как показывает великий Гугл. Собирать будем в докере «целевой» системы (x86_32 Debian 9.5) потому что я понял, что компиляция 32bit Rust в 64bit окружении мне не под силу.

FYI: Да, до этого я попробовал i686-unknown-linux-musl и мне не удалось заставить ее работать.

Магия Docker

Копируем файлы из репозитория на github:

mkdir -p vector && \   curl -sSfL --proto '=https' --tlsv1.2 https://api.github.com/repos/timberio/vector/tarball/v0.10.0 | \   tar xzf - -C vector --strip-components=1

В директории vector/scripts/ci-docker-images создаем папку builder-i686-unknown-linux-gnu, базовый Dockerfile берем из vector/scripts/ci-docker-images/builder-x86_64-unknown-linux-gnu и начинаем править.

После нескольких часов экспериментов, гугления и мук выбора, получилось следующее:

FROM i386/debian:9.5 as builder # This is formatted "$UID:$GID" by the docker-compose/scripts. ARG USER  RUN apt-get update && \     apt-get -y upgrade  RUN apt-get install -y \         make libssl-dev cmake git \         build-essential sudo curl          RUN curl -L https://cpanmin.us | perl - App::cpanminus  RUN cpanm File::Rename \  && rename --version  RUN cd /tmp && \   git clone https://github.com/github/cmark-gfm && \   cd cmark-gfm && \   git checkout 0.29.0.gfm.0 && \   make install INSTALL_PREFIX=/usr && \   ldconfig && \   cd .. && \   rm -rf cmark-gfm && \   cmark-gfm --version  RUN sudo adduser runner RUN sudo usermod -aG sudo runner  USER runner RUN curl https://sh.rustup.rs -sSf | sh -s -- --no-modify-path --default-host i686-unknown-linux-gnu -y ENV PATH=/home/runner/.cargo/bin:$PATH RUN echo "export PATH=/home/runner/.cargo/bin:$PATH" >> ~/bashrc ENV LIBRARY_PATH /usr/local/lib:$LIBRARY_PATH ENV LD_LIBRARY_PATH /usr/local/lib:$LD_LIBRARY_PATH  RUN rustup update stable RUN rustup run stable cargo install cargo-deb --target=i686-unknown-linux-gnu --version '^1.24.0'  CMD ["bash"]

Также пришлось поправить файл vector/Makefile.

Добавив и описав build-i686-unknown-linux-gnu в нескольких местах и сделав ее единственным вариантом сборки.

Кусочек файла vector/Makefile для примера:

#build-all: build-x86_64-unknown-linux-musl build-armv7-unknown-linux-musleabihf build-aarch64-unknown-linux-musl  ## Build the project in release mode for all supported platforms build-all: build-i686-unknown-linux-gnu  ….  package-archive-i686-unknown-linux-gnu: build-i686-unknown-linux-gnu ## Build the x86_32 archive $(RUN) package-archive-i686-unknown-linux-gnu

Конфигурация зависимостей Rust лежит в файле vector/Cargo.toml. Туда была добавлена секция profile.release:

[profile.release] opt-level = 'z'  # Optimize for size. debug = false debug-assertions = false lto = true codegen-units = 1

Это было сделано из соображений оптимизации, т.к. первые собранные бинарники были размером с чугунный мост ~ 60Мб, что не приемлемо. Размер оригинальных бинарников с сайта примерно 7Мб.

Вдохновение навеяно на мой взгляд великолепным описанием методик уменьшения размеров бинарников Rust от @johnthagen тут: https://github.com/johnthagen/min-sized-rust

В стремлении сэкономить на размере в секциях sources, transforms закомментированы
logplex|splunk_hec и aws_ec2_metadata|lua соответсвенно, что позволило без секции profile.release сэкономить примерно 10Мб в собранном состоянии.

# Sources sources = [   "sources-docker",   "sources-file",   "sources-generator",   "sources-http",   "sources-internal_metrics",   "sources-journald",   "sources-kafka",   #"sources-logplex",   "sources-prometheus",   "sources-socket",   #"sources-splunk_hec",   "sources-statsd",   "sources-stdin",   "sources-syslog",   "sources-tls",   "sources-vector", ]  # Transforms transforms = [   "transforms-add_fields",   "transforms-add_tags",   "transforms-ansi_stripper",   #"transforms-aws_ec2_metadata",   "transforms-coercer",   "transforms-concat",   "transforms-dedupe",   "transforms-field_filter",   "transforms-filter",   "transforms-geoip",   "transforms-grok_parser",   "transforms-json_parser",   "transforms-log_to_metric",   "transforms-logfmt_parser",   #"transforms-lua",   "transforms-merge",   "transforms-regex_parser",   "transforms-remove_fields",   "transforms-remove_tags",   "transforms-rename_fields",   "transforms-sampler",   "transforms-split",   "transforms-swimlanes",   "transforms-tag_cardinality_limit",   "transforms-tokenizer",   "transforms-reduce", ]

Сборка

Запускаем все это дело командой:

PASS_FEATURES=default-cmake ./scripts/docker-run.sh builder-i686-unknown-linux-gnu make build

В процессе сборки могут вываливаться ошибки вроде этой:

error: Input/output error (os error 5) warning: build failed, waiting for other jobs to finish...     Building [===>                                                    ] 40/537: regex-syntax                                                                                                              error: build failed Makefile:156: recipe for target 'build' failed make: *** [build] Error 101

Унывать не советую, перезапускаем make и после “бесконечного” cargo downloading component, Updating crates.io index и Updating git repository сборка продолжается с того места, на котором прервалась. Кстати если кто-то знает, как это прекратить и заставить cargo и crates использовать локальный кэш было бы супер)

На macbook pro i5 8gb этот процесс длится примерно 2 часа, из них сама сборка минут 50.

После сборки файлик можно сжать UPX’ом:

upx --best --lzma target/release/vector

На этом все.

Репозиторий github с исправленными файлами и Vector 0.10.0 тут
Собранный бинарник 8,7Мб, сжатый UPX тут

ссылка на оригинал статьи https://habr.com/ru/company/X5RetailGroup/blog/532400/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *