Когда выбирают агент для телеметрии, обычно сравнивают поддержку протоколов, потребление CPU и удобство конфигурации. Я бы начал со следующего вопроса:
Что произойдёт с данными, если хранилище перестанет отвечать на 10 минут, а потом вернётся обратно?
Агент-доставщик может уметь в ретраи, персистент вольюм, но это не означает, что данные не потеряются. Ретраи должны где-то жить, а очередь должна иметь предел. После восстановления связи накопившиеся сообщения нужно выгрузить, не положив только что ожившее и еще не до конца очухавшееся хранилище. А если агент вдруг неожиданно перезапустится, очередь должна пережить и это.
Меня зовут Антон Касимов, я работаю в Gals Software, веду авторский телеграм по наблюдаемости Мониторим ИТ, а в этой статье разберу семь популярных шипперов и коллекторов: OpenTelemetry Collector, Grafana Alloy, Vector, Fluent Bit, vlagent, vmagent и vtagent. Для каждого шиппера рассмотрю следующие вещи: батчинг, очередь, поведение при недоступности бэкэнда, ключевые настройки и пример конфигурации.
Это не синтетический рейтинг кто быстрее, выше, сильнее. У инструментов разная специализация и разные единицы измерения. Очередь в 1000 OTLP-запросов нельзя честно сравнить с очередью в 10 ГБ или с WAL длительностью восемь часов. В проектах я сам периодически сталкиваюсь с проблемой выбора, поэтому тема для меня достаточно животрепещуща. Возможно, она окажется такой и для вас.
Сначала о терминах
Батч — порция данных, которую агент отправляет одним запросом. Его цель — сократить overhead на сериализацию, сжатие, TLS и HTTP/gRPC-вызовы.
Большой батч обычно говорит о том, что:
в процессе передачи будет меньше запросов и лучше сжатие;
выше пропускная способность;
будет выделено больше памяти на одну отправку;
будет выше задержка для слабонагруженного потока;
выше риск упереться в лимит размера запроса на стороне бэкэнда.
Очередь — уже принятые из источника, но ещё не доставленные данные. Её задача — пережить разницу между скоростью входа и скоростью выхода, кратковременную перегрузку или сетевой разрыв.
Возможность работы с большой очередью говорит о том, что у вас есть более длинное окно автономности (если приемник накроется), но также больше будет потребление RAM или I/O диска, а также она дольше будет вычищаться после восстановления.
Так выглядит формула оценки окна дисковой очереди:
outage_window_seconds ≈ usable_queue_bytes / incoming_bytes_per_second
Если агент принимает 20 МБ/с, а очередь имеет запас в 100 ГБ — это в районе 83,33 минут (без учёта служебных данных и прочих накладных вещей), когда вы можете принимать данные без риска их потери.
Для восстановления важна ещё одна формула:
drain_time ≈ backlog_bytes / (send_rate_after_recovery - incoming_rate)
Если после восстановления агент продолжает принимать 20 МБ/с и способен отправлять, скажем, 25 МБ/с, зависшие сообщения будут убывать со скоростью 5 МБ/с. Получается, что очередь на 100 ГБ будет выгружаться больше пяти часов.
Теперь, пока вы еще не успели осмыслить две предыдущих формулы, давайте зададимся четырьмя вопросами, которые важны при выборе шиппера (что мы тут в статье и будем дальше делать):
Где живёт очередь: в RAM, на диске, в WAL или во внешнем брокере.
Чем измеряется очередь: запросами, сэмплами, событиями, спанами, чанками или байтами.
Что происходит при заполнении очереди: обратное давление (backpressure), пауза с приемом, удаление новых или удаление старых данных.
Переживает ли очередь рестарт агента: действительно ли каталог смонтирован на персистент вольюм (а то мало ли).
Последний пункт особенно коварен в кубере.
1. OpenTelemetry Collector
OpenTelemetry Collector — самый универсальный вариант в моем сравнении. Он может всё принимает метрики, логи и трейсы, а поведение конвейера собирается из конфигурации компонентов: процессоров, экспортеров и т.д. За эту универсальность приходится платить: батчинг, очереди и ретрай — отдельные механизмы, в каждом из них есть свои настройки очереди. Причем, их легко настроить так, что один нивелирует другой, т.е. вероятна ситуация, когда batch-процессор уже сформировал батч на 8192 элемента, а в экспортере может быть настрона очередь большего или меньшего размера и там либо будет дополнительное ожидание элементов либо разбиение батча на части. Забавно, да.
Батчинг
Классическая схема использует batch processor. Настройки внутри:
send_batch_size— порог, после которого процессор инициирует отправку;timeout— максимальное ожидание неполного батча;send_batch_max_size— жёсткий верхний предел и разбиение слишком больших порций данных.
send_batch_size — триггер, а не гарантированный максимум размера (максимально он может и больше отправить). Если бэкэнд ограничивает размер принимаемых батчей, нужно явно определить send_batch_max_size.
У batch-процессора значения по умолчанию — 8192 элементов, 200ms и 0 для send_batch_max_size, то есть без жёсткого верхнего предела. Учитывайте, что некоторые дистрибутивы OTEL-коллектора могут иметь другие значения по умолчанию. В продакшене желательно ставить ограничения на максимальный размер батча.
Очередь
У большинства экспортеров есть sending_queue. По умолчанию очередь включена, хранится в памяти и имеет:
queue_size: 1000;num_consumers: 10;sizer: requests;block_on_overflow: false.
sizer: requests означает, что один экземпляр очереди (к примеру, 8192 элемента) является входным пакетом для экспортера, а не один спан или метрика. То есть очередь будет ждать 1000 таких экземпляров или 8 192 000 элементов. Причем, один элемент может содержать несколько килобайт данных или десятки мегабайт, все зависит от типа телеметрии. Следовательно, параметр sizer лучше перевести в items.
В OTEL-коллекторе выходную очередь экспортера можно считать не только в requests, но и в items или bytes. Подсчёт байтов дороже с точки зрения производительности. Для предсказуемости вы можете использовать байты , чтобы определить хотя бы примерный размер сообщений.
Чтобы очередь переживала рестарт, в sending_queue.storage подключается file_storage. К сожалению, коллектор не умеет в сначала память потом диск, у него либо одно либо другое.
Поведение при отключении хранилища
Экспортер повторяет неуспешные запросы на отправку. Стандартный max_elapsed_time — пять минут. После истечения этого времени конкретная порция данных может быть отброшена. Значение 0 означает неограниченные по времени ретраи.
Если очередь заполнена и block_on_overflow: false, новые данные отклоняются до попадания в ретрай. Если включить block_on_overflow, обратное давление пойдёт вверх по конвейеру. Это уменьшает потери внутри коллектора, но может перенести проблему на приемник или само приложение, которое отправляет данные.
Еще одна рекомендация: следите за метриками otelcol_exporter_queue_size, otelcol_exporter_queue_capacity и otelcol_exporter_enqueue_failed_*(извлекаются prometheus-экспортером).

Пример конфигурации
extensions: file_storage/queue: directory: /var/lib/otelcol/queue timeout: 10s receivers: otlp: protocols: grpc: {} http: {} processors: memory_limiter: check_interval: 1s limit_mib: 1024 batch: timeout: 1s send_batch_size: 8192 send_batch_max_size: 10000 exporters: otlp/backend: endpoint: observability.example:4317 sending_queue: enabled: true storage: file_storage/queue sizer: items queue_size: 5000 num_consumers: 10 block_on_overflow: true retry_on_failure: enabled: true initial_interval: 5s max_interval: 30s max_elapsed_time: 0 service: extensions: [file_storage/queue] pipelines: traces: receivers: [otlp] processors: [memory_limiter, batch] exporters: [otlp/backend]
2. Grafana Alloy
Alloy — это набор компонентов: prometheus.remote_write, loki.write и otelcol.exporter.*, которые под капотом используют разные механизмы. Поэтому нельзя просто так взять и настроить буфер Alloy (напрашивается картинка с известным мемом, но уж не буду тут её размещать). Дальше разберемся с метриками, логами и трейсами, которые так лихо умеет перелопачивать Alloy.
Батчинг
В prometheus.remote_write (передача метрик) каждый поток отправляет порцию при выполнении одного из двух условий:
накоплено
max_samples_per_send, по умолчанию 2000 сэмплов;прошло
batch_send_deadline, по умолчанию 5 секунд.
Максимальная теоретическая пропускная способность рассчитывается как max_shards × max_samples_per_send / latency. Не нужно рассматривать это как приглашение выкрутить max_shards: слишком агрессивное опустошение буфера способно залить бэкэнд по самое не балуйся.
Для loki.write (передача логов) и otelcol.exporter.otlp (передача трейсов) модель аналогична OpenTelemetry Collector с batch processor и sending queue, которую мы рассмотрели выше.
Очередь
Что касается метрик, то они сначала пишутся samples в WAL (его нельзя отключить). Затем каждый endpoint читает WAL через собственную sharded queue. На один shard по умолчанию приходится capacity: 10000 samples в памяти, а число shards автоматически меняется между min_shards и max_shards.
WAL имеет временное окно хранения:
min_keepalive_time: 5m;max_keepalive_time: 8h;truncate_frequency: 2h.
Это не бесконечная очередь на весь свободный диск. Если потоки prometheus.remote_writeотстают слишком сильно, данные могут быть прибиты внутри WAL. В документации они предупреждают об этом риске.
Что касается тракта loki.write(передача логов), то здесь тоже имеется WAL, но он пока экспериментальный. По умолчанию батчи и очереди перелопачиваются в RAM.
Для трейсов, пролетающих через otelcol.exporter.* настройки точно такие как и для OTEL-коллектора: хотите в RAM, хотите на диск. Но либо одно либо другое, комбо не поддерживается.
Поведение при отключении хранилища
Сэмплы логов/метрик остаются в WAL, пока не будут отправлены или не выйдут за установленный период транкейта. Сэмплы трейсов продолжают жить на файловой системе установленное время.
Для метрик, после восстановления коннекта, Alloy увеличивает число потоков prometheus.remote_write и начинает догонять хвост. Здесь появляется типичная ловушка: задержка для свежих метрик остаётся высокой, пока не выгружены имеющиеся сэмплы, а резкий рост параллелизма создаёт дополнительную нагрузку на бэкэнд.
Для логов и трейсов, после восстановления коннекта, Alloy сразу запустит их отправку в бэкэнд.

Пример конфигурации
prometheus.remote_write "prod" { wal { truncate_frequency = "2h" min_keepalive_time = "5m" max_keepalive_time = "12h" } endpoint { url = "https://metrics.example/api/v1/write" queue_config { capacity = 20000 min_shards = 1 max_shards = 50 max_samples_per_send = 4000 batch_send_deadline = "5s" min_backoff = "100ms" max_backoff = "10s" retry_on_http_429 = true sample_age_limit = "0s" } } }
3. Vector
У Vector одна из самых понятных моделей в этом списке: у каждого синка есть собственные батчи и буферы. Поломка одного бэкэнда не остановит передачу данных в другие. Vector может для хранения очереди одновременно использовать и RAM и диск (в режиме overflow при переполнении RAM будет скидывать сэмплы на диск). Особенностью является то, что при переполнении памяти новые данные начинают записываться на диск (а не в память) и когда соединение с бэкэндом будет восстановлено сначала будут передаваться данные из памяти (при этом они могут быть более старыми нежели на диске). Да, и сам Vector в документации пишет, что режим overflowпока что не совсем продакшен-реди и его лучше не использовать.
Батчинг
Для HTTP-синка батч отправляется при первом наступившем условии:
достигнут
batch.max_events;достигнут
batch.max_bytes;истёк
batch.timeout_secs.
Для HTTP-синка значение параметра max_bytes по умолчанию 10 MB до сериализации и сжатия, timeout_secs — 1 секунда. Обратите внимание, что значения по умолчанию каждого синка свои, поэтому нельзя бездумно оставлять значения по умолчанию для ClickHouse, Loki или generic HTTP.
Очередь
По умолчанию синк использует буфер в памяти на 500 событий. Дисковый буфер задаётся в байтах и должен быть не меньше 256 МБ. Он дописывает в файл новые события и сливает новые данные на диск примерно каждые 500 мс.
Есть две опции поведения при отключении бэкэнда:
blockпередаёт обратное давление выше по конвейеру;drop_newestпродолжает работу, отбрасывая новые события.
Дисковый буфер переживает обычный рестарт и крэш в пределах уже синхронизированных данных. При ошибке I/O Vector намеренно завершает процесс.
Поведение при отключении хранилища
Синк начинает повторять отправку, а события накапливаются в его буфере (в RAM или на диске). При block обратно давление распространяется на источник. При чтении из файла это приемлемо: непрочитанные строки остаются в исходном файле. Для источника типа push нужно понимать, умеет ли отправитель повторять запросы на отправку. Если нет — потери неизбежны
У Vector еще есть интересная фича End-to-end Acknowledgements, которая умеет сообщать источнику, что приемник успешно принял батч.

Пример конфигурации
data_dir: /var/lib/vector sinks: backend: type: http inputs: - processed uri: https://logs.example/ingest method: post encoding: codec: json compression: zstd batch: max_events: 2000 max_bytes: 10000000 timeout_secs: 1 buffer: type: disk max_size: 10737418240 when_full: block
4. vlagent
vlagent — специализированный агент VictoriaLogs. Он умеет собирать логи Kubernetes, контейнеров и файлов, принимать сообщения через HTTP, обогащать записи и отправлять их в один или несколько эндпоинтов VictoriaLogs. Очередь агента гибридная (сначала RAM, потом диск), что является его большим плюсом.
Батчинг
Внутренний отправитель формирует блоки. Ключевые параметры:
-remoteWrite.maxBlockSize=8MiB— максимальный размер блока;-remoteWrite.flushInterval=1s— максимальное время ожидания блока;-remoteWrite.queues=2×CPU— число параллельных очередей/worker-ов на destination по умолчанию.
Больший блок уменьшает нагрузку на CPU, но увеличивает нагрузку на RAM и, если первая попытка завершится неудачей, повторно он снова будет отправлять все тот же большой блок. Больше потоков помогают разгружать внутреннюю очередь, но увеличивают число одновременных запросов и нагрузку на VictoriaLogs.
Очередь
Количество блоков, которые можно держать в памяти, vlagent вычисляет автоматически исходя из:
доступной процессу памяти;
количества
remoteWrite.url;количества
remoteWrite.queues.
Если бэкэнд не успевает и RAM-очередь заполняется, агент сбрасывает накопленные блоки в файловую очередь. У каждого приемника отдельная постоянная очередь на диске (управляется -remoteWrite.tmpDataPath). По умолчанию программного лимита нет: очередь ограничена свободным местом на диске. Файловую очередь отключить нельзя.
Лимит задаётся при помощи параметра -remoteWrite.maxDiskUsagePerURL. Он применяется отдельно к каждому приемнику. Это удобно при репликации: недоступность одной ноды VictoriaLogs не задержит доставку в остальные.
Поведение при отключении хранилища
Неотправленные блоки складываются на диск. После восстановления эндпоинта агент начинает выгружать данные из очереди. Если очередь достигает maxDiskUsagePerURL, удаляются самые старые записи, чтобы освободить место для новых.
Это политика FIFO. Она разумна для оперативных логов, но её нужно учитывать в SLO: заполнение очереди означает не остановку, а потерю данных за некоторый период.

Пример конфигурации
apiVersion: apps/v1 kind: DaemonSet metadata: name: vlagent namespace: monitoring spec: selector: matchLabels: app: vlagent template: metadata: labels: app: vlagent spec: containers: - name: vlagent image: victoriametrics/vlagent:v1.52.0 args: - -kubernetesCollector - -remoteWrite.url=http://victoria-logs:9428/insert/native - -remoteWrite.maxBlockSize=8MiB - -remoteWrite.flushInterval=1s - -remoteWrite.queues=4 - -remoteWrite.tmpDataPath=/var/lib/vlagent - -remoteWrite.maxDiskUsagePerURL=20GB - -tmpDataPath=/var/lib/vlagent volumeMounts: - name: state mountPath: /var/lib/vlagent volumes: - name: state hostPath: path: /var/lib/vlagent type: DirectoryOrCreate
5. vmagent
vmagent специализируется на метриках и remote write. Его очередь включена по умолчанию и устроена как гибрид аналогично vlagent: RAM плюс диск.
Батчинг
Основные параметры блока:
-remoteWrite.maxRowsPerBlock=10000— максимумальное количество сэмплов в блоке;-remoteWrite.maxBlockSize=8MiB— максимальное время ожидания блока;-remoteWrite.flushInterval=1s— максимальное время ожидания блока;-remoteWrite.queues=2×CPU— workers на каждый remote URL.
Блок закрывается по количеству rows, размеру или времени. Увеличение лимитов может поднять пропускную способность, но увеличивает потребление RAM и размер повторно отправляемых батчей.
Очередь
Если worker не успевает забрать блок, in-memory очередь заполнена или на диске уже есть неотправленные сэмплы, данные попадают на диск. Каталог задаётся параметром -remoteWrite.tmpDataPath, лимит -remoteWrite.maxDiskUsagePerURL.
По умолчанию лимит равен 0, то есть ограничением становится диск. Постоянную очередь на диске можно отключить через -remoteWrite.disableOnDiskQueue, но тогда при отставании бэкэнда данные будут теряться.
Поведение при отключении хранилища
При временной ошибке отправка повторяется. При ответе бэкэнда 400 и 404 блок считается окончательно отклонённым и пропускается.
При достижении дискового лимита удаляются старые блоки. После восстановления обычные воркеры выгружают очередь в формате FIFO, поэтому свежие метрики могут появляться в хранилище с большой задержкой.
Опция -remoteWrite.inmemoryQueues добавляет воркеры для свежих данных параллельно с выгружаемыми данными из дисковой очереди. Это уменьшает лаг, но свежие сэмплы в такой ситуации могут обогнать старые.

Пример конфигурации
apiVersion: apps/v1 kind: Deployment metadata: name: vmagent namespace: monitoring spec: replicas: 1 selector: matchLabels: app: vmagent template: metadata: labels: app: vmagent spec: containers: - name: vmagent image: victoriametrics/vmagent:v1.152.0 args: - -remoteWrite.url=http://victoria-metrics:8428/api/v1/write - -remoteWrite.maxRowsPerBlock=10000 - -remoteWrite.maxBlockSize=8MiB - -remoteWrite.flushInterval=1s - -remoteWrite.queues=4 - -remoteWrite.tmpDataPath=/var/lib/vmagent - -remoteWrite.maxDiskUsagePerURL=50GiB - -remoteWrite.rateLimit=50MB volumeMounts: - name: queue mountPath: /var/lib/vmagent volumes: - name: queue persistentVolumeClaim: claimName: vmagent-queue
6. vtagent
vtagent — специализированный агент VictoriaTraces. Он принимает OTLP/HTTP и OTLP/gRPC, формирует блоки и отправляет их в один или несколько VictoriaTraces.
Батчинг
Механика remote write близка к другим агентам VictoriaMetrics:
-remoteWrite.maxBlockSize=8MiB— максимальный размер блока;-remoteWrite.flushInterval=1s— максимальное время ожидания блока;-remoteWrite.queues=2×CPU— workers на каждый remote URL.
Больше block size — меньше сетевого overhead, но выше RAM и стоимость повторной отправки.
Очередь
Каждый -remoteWrite.url получает отдельную постояннуб очередь в -remoteWrite.tmpDataPath. -remoteWrite.maxDiskUsagePerURL ограничивает очередь для конкретного destination; 0 оставляет её ограниченной только диском.
При нескольких URL vtagent реплицирует спаны во все эндпоинты, а не распределяет их как равномерно. Следовательно, два URL примерно удваивают потенциальные потребности в дисковых мощностях.
Поведение при отключении хранилища
Недоступный эндпоинт приводит к накоплению очереди (только локально), доступные эндпоинты продолжают получать спаны. После восстановления очередь выгружается автоматически.
При достижении лимита удаляются старые данные, чтобы принять новые (классический FIFO). Для трейсов это болезненно по-особому: частичная потеря спанов способна оставить дырявые трейсы, которые формально есть, но плохо объясняют исходный запрос (трейсы Да Винчи, хех).

Пример конфигурации
apiVersion: apps/v1 kind: Deployment metadata: name: vtagent namespace: monitoring spec: replicas: 1 selector: matchLabels: app: vtagent template: metadata: labels: app: vtagent spec: containers: - name: vtagent image: victoriametrics/vtagent:v0.11.0 args: - -remoteWrite.url=http://victoria-traces:10428/insert/native - -remoteWrite.maxBlockSize=8MiB - -remoteWrite.flushInterval=1s - -remoteWrite.queues=4 - -remoteWrite.tmpDataPath=/var/lib/vtagent - -remoteWrite.maxDiskUsagePerURL=30GiB - -otlpGRPCListenAddr=:4317 ports: - name: otlp-grpc containerPort: 4317 - name: otlp-http containerPort: 10429 volumeMounts: - name: queue mountPath: /var/lib/vtagent volumes: - name: queue persistentVolumeClaim: claimName: vtagent-queue
7. Fluent Bit
Fluent Bit оперирует не абстрактными батчами, а чанками внутреннего бинарного формата. Средний chunk — около 2 MB, но это не жёсткая гарантия. Буферизация настраивается на входе, а логические лимиты дисковой очереди задаются на выходе.
Батчинг
Глобальный параметр service.flush задаёт интервал, с которым Fluent Bit запускает отправку готовых chunks. Конкретные output-плагины могут иметь собственные параметры агрегации.
Очередь
Есть три режима:
memory— быстрее, но накопленное пропадает при аварийном рестарте;filesystem— гибридный режим: чанки хранится на диске и при возможности в RAM;memrb— кольцевой RAM-буфер, который удаляет старые chunks ради новых.
storage.max_chunks_up определяет число чанков в RAM. storage.backlog.mem_limit определяет объем RAM, выделяемое под хранение чанков. Сработает тот лимит, который будет достигнут первым.
storage.total_limit_size задаётся на выходе и ограничивает его логическую очередь. Один chunk может быть нужен нескольким outputs, поэтому Fluent Bit хранит ссылки по маршрутам, а не независимые физические копии во всех случаях.
Поведение при отключении хранилища
В режиме memory чанки растут до величины mem_buf_limit, после чего прием приостанавливается. Для чтения логов это означает, что чтение продолжится позже с сохранённой позиции. Для приема данных по сети пауза может приводить к потерям, если отправитель не повторит запросы.
В режиме filesystem новые чанки могут складываться на диск после достижения storage.max_chunks_up, если storage.pause_on_chunks_overlimit: off. Если переключить последний на on, то прием данных будет приостановлен.
При достижении storage.total_limit_size будет удален самый старый chunk, чтобы освободить место для нового.

Пример конфигурации
service: flush: 1 log_level: info storage.path: /var/lib/fluent-bit/storage storage.type: filesystem storage.inherit: on storage.sync: normal storage.checksum: off storage.max_chunks_up: 128 storage.backlog.mem_limit: 64M pipeline: inputs: - name: tail tag: kubernetes.* path: /var/log/containers/*.log db: /var/lib/fluent-bit/tail.db storage.type: filesystem storage.pause_on_chunks_overlimit: off outputs: - name: http match: '*' host: logs.example port: 443 tls: on uri: /ingest format: json_lines retry_limit: false storage.total_limit_size: 20G
Сводная таблица
Агент | Телеметрия | Хранение | Что происходит при превышении лимита очереди |
|---|---|---|---|
OpenTelemetry Collector | метрики, логи, трейсы | память или диск | reject/drop или backpressure |
Grafana Alloy | метрики, логи, трейсы | метрики и логи в WAL, трейсы в памяти или на диске | зависит от экспортера |
Vector | метрики, логи, трейсы (опционально) | память и/или диск | блокировка приема новых и отбрасывание новых |
vlagent | логи | память и диск | удаляет старые блоки после disk limit |
vmagent | метрики | память или память и диск | удаляет старые блоки после disk limit |
vtagent | трейсы | память и диск | удаляет старые блоки после disk limit |
Fluent Bit | логи | память и/или диск | pause/backpressure либо удаление старых чанков |
Что я посоветовал выбрать
Победителя, к сожалению, определить нельзя. При выборе агента нужно исходить из задачи. Начать можно с этого, а потом копнуть глубже, если нужно:
Если нужно vendor-neutral решение — это OpenTelemetry Collector. Его универсальность можно рассматривать и как преимущество и как недостаток.
Если уже используете стек Grafana — Alloy. Его универсальность можно рассматривать и как преимущество и как недостаток.
Нужен выразительный конвейер с трансформациями и изоляцией отправителей — Vector.
Используете VictoriaLogs — vlagent. В комплекте удобный сбор логов из Kubernetes и файлов, обогащение метаданными и фильтрация полей.
Используете VictoriaMetrics — vmagent. На борту найдете relabeling, aggregation, replication/sharding и управляемую очистку буфера.
Используете VictoriaTraces — vtagent. Решение пока молодое, лучше присмотритесь.
Нужен лёгкий Kubernetes лог-шиппер с большим количеством плагинов — Fluent Bit.
Как протестировать выбранный агент
Подайте близкий к боевому поток данных: похожие размеры событий, та же кардинальность и т.д..
Зафиксируйте скорость приема, отправки, CPU, RAM, IOPS и p95 latency.
Отключите бэкэнд на 5 и 30 минут.
Проверьте, растёт ли очередь, которую вы собирались мониторить.
Перезапустите агент.
Доведите очередь до 90–100% лимита и посмотрите, какие данные теряются — новые или старые.
Включите бэкэнд с ограниченным объемом приема данных.
Измерьте временной лаг сообщений и время полной очистки очереди.
Проверьте дубликаты, потерянные сообщения и полноту трейсов.
Главный вывод
Очередь телеметрии — это не большой и надежный теплоход, а медленно сдувающийся спасательный круг. Самое важное, чтобы ваша команда знала какие данные, через сколько времени и при каком именно сбое начнут теряться.
Спасибо за внимание, надеюсь, статья была полезна. Если вам нужна консультация или помощь с проектированием observability-платформы, я всегда открыт к предложениям —пишите в телеграм (контакты в профиле).

