Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Агент сбора метрик Linux

                         ┌─────────┐
                         | Alerting|  # mAlert   https://github.com/Qedr1/malert
                         └────▲────┘
                              |
           ┌────────┐    ┌────┴──────┐
# Grafana  │ VIEWER │    |  QUEUE+KV |   # NATS
           └────▲───┘    └────▲──────┘
                │ table +     |
                │ mat. view   |
                └▲────────────┘
                 |
            ┌────┴────┐
            │ STORAGE │   # ClickHouse
            └────▲────┘
                 │ insert (batch)
           ┌─────┴─────┐
           │ COLLECTOR │  # vector.dev
           └─────▲─────┘
                 │ events gRPC (batch)
             ┌───┴────┐
             │  HOST  │   # magent
             └────────┘

magent собирает системные метрики: утилизация сетевых интерфейсов, CPU, RAM, disk, fs, netflow-пары, сетевой стек, ядро, процессы и т. д. Также собирает произвольные внешние метрики: выполняет скрипты, принимает через http_server или опрашивает через http_client.

Ключевые отличия:

  • экономия трафика. Компактная структура данных без дублирования. Бинарный протокол между агентом и коллектором
  • комплексный мониторинг сетевой активности хоста, включая сбор flow-телеметрии и метрики/состояние алгоритма управления перегрузкой сетевого стека (congestion control)
  • эффективная фильтрация событий на стороне агента
  • отказоустойчивость. Локальные очереди доставки и failover до коллектора
  • эффективный коллектор. Произвольный препроцессинг и процессинг. Локальные очереди доставки в хранилище
  • хранилище. Скорость записи/поиска почти не зависит от объема данных

Решение мониторит совокупную инфраструктуру на 21к хостов с приростом хранилища ~2TB в сутки.

Стресс-тесты

magent

- file size: 3.7 MB (upx)
- vCPU:1
- RES mem: 21MB
- RAM total: 128MB

~1 719 event/s
~18 801 metrics/s

~97% load average

коллектор (vector)

- file size: 136 MB
- vCPU:2
- RES mem: 82MB
- RAM total: 512MB

~25 785 event/s
~282 015 metrics/s

~182% load average

Описание

  • потребляет минимум ресурсов и сетевой полосы пропускания. Реализует высокую автономность, надежность сбора и доставки данных через собственные очереди, failover и батчи отправки

  • метрики собираются один раз за период опроса и отправляются в локальный батч один раз за период отправки. Один период отправки может содержать 1..n периодов опроса

  • батч отправляется в коллектор при накопленном количестве событий либо по таймауту

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

  • отдельный тип воркера умеет запускать внешние скрипты и получать произвольные данные от него в строгом стандартном формате

  • периоды сбора/опроса и отправки задаются в конфиге и могут быть переопределены для каждой метрики

  • по каждой метрике собирается last, а процентили pXX (если включены) пересчитываются один раз за период отправки по выборкам периода опроса

  • между агентом и коллектором (vector) события передаются в Vector Protocol v2 (gRPC over HTTP/2, бинарный protobuf). EventWrapper.log

  • обязательные теги: dc, project, role, host. Задаются в секции конфига [global]. Добавляются во все события и не могут переопределяться в секциях метрик. Метрика не может создавать собственные теги. Если host отсутствует/пустой — берётся os.Hostname(). Отсутствие других тегов недопустимо

  • dt — время опроса метрики агентом (uint64, миллисекунды).

  • dts — время отправки метрики в коллектор (секунды).

  • dtv — время обработки метрики в коллекторе (секунды).

  • реализует failover. Адрес коллектора — это массив в формате "адрес:порт". При недоступности одного адреса агент идёт в другой. Если недоступны все адреса — сохраняет в локальную очередь этого коллектора

  • отправляет одновременно в несколько коллекторов, если они определены конфигом

  • агент имеет собственную дисковую очередь на каждый коллектор по принципу first in, first out. При недоступности коллектора данные пишутся в очередь и хранятся в готовом для отправки формате

  • агент копит данные и отправляет в коллектор только батчами. Размер батча и очереди задается в конфиге коллектора

  • коллектор принимает массив событий. Каждое событие (log event) разворачивает в плоскую структуру. data — объект (map) вида var_name -> {last,pXX...}. При развороте в ClickHouse формируется N строк по числу пар (key × var × agg), где agg ∈ {last,pXX} из конфига. Запись в CH идёт батчами по 1000 шт. или по минутному интервалу. Это даёт универсальность схемы хранения и максимальную скорость поиска/записи в ClickHouse

Конфиг

  • формат TOML
  • -config принимает путь к одному TOML-файлу или к директории; для директории агент читает только *.toml и объединяет их в лексикографическом порядке имён файлов
  • в config dir одиночные таблицы ([global], [metrics], [log.*], [pprof], [db.*]) описывайте один раз; повторение таких секций в разных файлах приведёт к ошибке TOML
  • отдельная секция для каждой сущности: глобальные параметры вместе с тегами, коллектор, логи, метрики и т. д.
  • метрику можно описать любое количество раз, и каждая секция генерирует собственное событие. Повтор задается как массив таблиц [[metrics.<name>]]
  • теги используются как глобальные переменные и содержатся во всех метриках. Определяются в глобальной секции. Не могут быть переопределены в секции метрики
  • значение переменных может быть получено из переменных окружения или systemd-сервиса. Формат ${VAR}
  • в глобальной секции должны быть определены обязательные теги dc (датацентр), project (подпроект в продукте), role (роль хоста в продукте)
  • если тег host не задан или пустой — берем имя сервера (os.Hostname())
  • секция [db.clickhouse] задаёт параметры подключения к ClickHouse для docs/tests tooling: host, port, database, user, password, secure, dial_timeout
  • секция [pprof] включает runtime-профилирование агента: enabled, listen (host:port, например 127.0.0.1:6060)
  • hot reload конфига выполняется по SIGHUP: агент перечитывает и валидирует путь из -config (файл или директория), затем полностью пересоздаёт runtime (все воркеры/коллекторы/listeners); при ошибке применения автоматически возвращает предыдущий рабочий runtime
  • при успешном hot reload окна агрегации сбрасываются и новые события начинают копиться заново по новым параметрам

Логи

  • вывод в консоль цветной строкой
  • кастомный пакет поверх стандартного slog. Содержит логику раскраски событий в консоли
  • два режима логирования: консоль и файл. Сообщения в консоль раскрашиваются по уровню логов и паттернам текста (строка/ip-адрес/число)
  • для каждого режима отдельный уровень логирования
  • стандартные уровни логов: info/warn/error/panic/debug
  • в файл или консоль пишем строкой или в JSON (задается в конфиге)
  • если в консоль пишем строкой, применяется раскраска строк по уровню события
  • info: события прикладной логики (не системной)
  • warn: ошибка, не нарушающая прикладную логику приложения. Выполнение программы продолжается. Качество данных гарантируется
  • error: ошибка, нарушающая прикладную или системную логику приложения. Выполнение программы продолжается. Качество данных не гарантируется
  • panic: ошибка, нарушающая и прикладную, и системную логику приложения. Выполнение программы невозможно
  • debug: отладочный режим. Пишем любую итерацию в программе

Метрики

  • в collector.batch.max_events событием считается целый объект метрики (metric + key + data), а не отдельная пара var/value; разворот в строки (var,agg,value) выполняется уже в Vector.
  • по каждой метрике всегда фиксируется last; процентили pXX считаются только если они заданы в конфиге.
  • метрики собираются по периоду опроса (scrape), агрегируются и отправляются в батч по периоду отправки (send). Если процентили не указаны, период опроса метрики (scrape) равен периоду отправки метрики (send)
  • процентили вычисляет сам агент на основе конфига.
  • на выходе из агента все метрики нормализуются: все числовые непроцентные значения в data преобразуются в uint64, процентные — в uint8. Округление математическое (0.5 и выше — вверх, ниже 0.5 — вниз)
  • 0 считается валидным значением выборки
  • если в периоде опроса нет значений, last=0, а при включенных процентилях все pXX=0
  • процентили (если включены) агрегируются один раз за период (send) по измеренным значениям за периоды scrape.
  • dt, dts не подчиняются этим правилам и передаются как есть
  • встроенные метрики отправляются в lower-case (cpu,ram,swap,net,netflow,disk,fs,process) для прямого маппинга в lower-case таблицы ClickHouse

Структура события

Универсальная структура пакета данных любой метрики

dt        // дата и время опроса события. Один раз за период опроса, мсек
dts       // дата и время отправки события. Один раз за период отправки, сек
metric    // название метрики (по этому полю создается таблица CH)
dtv       // формируется в коллекторе. Время обработки события
dc        // локация сервера. Обязательный глобальный тег
host      // имя хоста, на котором собрана метрика. Обязательный глобальный тег. Если не задан явно — берётся из ОС
project   // название проекта. Обязательный глобальный тег
role      // роль хоста в системной архитектуре (frontdb/back/db ...). Обязательный глобальный тег
host_ip   // формируется агентом при отправке в коллектор из локального TCP адреса соединения
key       // обязательный строковый ключ метрики
data      // все метрики и их значения. Например ram_total, ram_used, cpu_total и т.д.

Принципы key

  • key всегда строка и всегда присутствует
  • если у метрики нет естественного ключа, используется key="total"
  • если у метрики несколько сущностей, агент формирует отдельное событие на каждую сущность с собственным key
  • при развороте в плоскую таблицу кол-во строк = кол-во key × кол-во элементов в data × кол-во элементов в agg. т. е. в таблице для каждого key формируется набор строк: по одной строке на каждую пару (data, agg) (строка содержит key, var, agg, value).

Пример универсальной структуры

{
  "metric": "cpu",
  "dt": 1231231232,
  "dts": 1231231254,
  "dc": "DC1",
  "host": "host1",
  "project": "Infra",
  "role": "DB_Postgres",
  "key": "core0",
  "data": {
    "util": { "last": 67, "p90": 97, "p99": 98 }
  }
}

Пример метрики CPU в таблице ClickHouse:

|dc |host|project|role|host_ip  |key  |var |agg |value|
+---+----+-------+----+---------+-----+----+----+-----+
|dc1|dev |infra  |soak|127.0.0.1|core0|util|last|    1|
|dc1|dev |infra  |soak|127.0.0.1|core0|util|p50 |    1|
|dc1|dev |infra  |soak|127.0.0.1|core0|util|p90 |    2|
|dc1|dev |infra  |soak|127.0.0.1|core0|util|p99 |    2|
|dc1|dev |infra  |soak|127.0.0.1|core1|util|last|    0|
|dc1|dev |infra  |soak|127.0.0.1|core1|util|p50 |    1|
|dc1|dev |infra  |soak|127.0.0.1|core1|util|p90 |    1|
|dc1|dev |infra  |soak|127.0.0.1|core1|util|p99 |    1|
|dc1|dev |infra  |soak|127.0.0.1|core2|util|last|    0|
|dc1|dev |infra  |soak|127.0.0.1|core2|util|p50 |    1|
|dc1|dev |infra  |soak|127.0.0.1|core2|util|p90 |    2|
|dc1|dev |infra  |soak|127.0.0.1|core2|util|p99 |    2|
|dc1|dev |infra  |soak|127.0.0.1|core3|util|last|    1|
|dc1|dev |infra  |soak|127.0.0.1|core3|util|p50 |    1|
|dc1|dev |infra  |soak|127.0.0.1|core3|util|p90 |    1|
|dc1|dev |infra  |soak|127.0.0.1|core3|util|p99 |    1|
|dc1|dev |infra  |soak|127.0.0.1|total|util|last|    1|
|dc1|dev |infra  |soak|127.0.0.1|total|util|p50 |    1|
|dc1|dev |infra  |soak|127.0.0.1|total|util|p90 |    1|
|dc1|dev |infra  |soak|127.0.0.1|total|util|p99 |    1|

LowCardinality снижает накладные расходы на дублируемые строковые поля.

CPU

Системная метрика загрузки CPU по ядрам и в агрегате по хосту.

  • секция конфига: [[metrics.cpu]]
  • key: строковый идентификатор сущности метрики; coreN для отдельного ядра или total для агрегата по всем ядрам.
  • util: утилизация либо всех ядер либо конкретного ядра, uint8, %

RAM

Системная метрика использования оперативной памяти хоста.

  • секция конфига: [[metrics.ram]]
  • key: строковый идентификатор сущности метрики; всегда total.
  • total: вся физическая память. uint64, bytes
  • used: использованная память. uint64, bytes
  • free: доступная память. uint64, bytes
  • util: утилизация (used/total*100). uint8, %

SWAP

Системная метрика использования swap-памяти хоста.

  • секция конфига: [[metrics.swap]]
  • key: строковый идентификатор сущности метрики; всегда total.
  • total: размер свапа. uint64, bytes
  • used: использовано. uint64, bytes
  • util: утилизация. uint8, %

KERNEL

Системная метрика ядра Linux из /proc/loadavg и /proc/stat.

  • секция конфига: [[metrics.kernel]]
  • key: строковый идентификатор сущности метрики; всегда total.
  • load1: средняя нагрузка за 1 минуту. uint64
  • load5: средняя нагрузка за 5 минут. uint64
  • load15: средняя нагрузка за 15 минут. uint64
  • procs_running: количество runnable задач. uint64, количество
  • procs_blocked: количество blocked задач. uint64, количество
  • ctxt_per_sec: переключения контекста за интервал опроса (в сек). uint64, опер/сек
  • intr_per_sec: аппаратные прерывания за интервал опроса (в сек). uint64, опер/сек
  • softirq_per_sec: softirq за интервал опроса (в сек). uint64, опер/сек
  • forks_per_sec: созданные процессы за интервал опроса (в сек). uint64, опер/сек

DISK

Системная метрика блочных устройств; собираются только базовые диски, партиции игнорируются (/dev/sda1, /dev/sda2, /dev/nvme0n1p1, /dev/mmcblk0p1).

  • секция конфига: [[metrics.disk]]
  • key: строковый идентификатор сущности метрики; путь к базовому блочному устройству (/dev/...).
  • rx_io: операций чтения в секунду. uint64, операций/сек
  • tx_io: операций записи в секунду. uint64, операций/сек
  • rx_bytes: прочитано байт за интервал опроса. uint64, bytes
  • tx_bytes: записано байт за интервал опроса. uint64, bytes
  • rx_bytes_per_sec: скорость чтения. uint64, bytes/сек
  • tx_bytes_per_sec: скорость записи. uint64, bytes/сек
  • rx_await: общее среднее время ожидания ввода-вывода за чтение. uint64, мс
  • tx_await: общее среднее время ожидания ввода-вывода на запись. uint64, мс
  • await: общее среднее время ожидания ввода-вывода. uint64, мс
  • qdepth: глубина очереди запросов к устройству. uint64, количество
  • util: утилизация устройства по IOPS. uint8, %
  • inflight: количество запросов в полёте (отправлены, не завершены). uint64, количество

FS

Системная метрика файловых систем по точкам монтирования.

  • секция конфига: [[metrics.fs]]
  • key: строковый идентификатор сущности метрики; точка монтирования <mpoint>.
  • total: общий размер файловой системы. uint64, bytes
  • used: использовано. uint64, bytes
  • free: свободно. uint64, bytes
  • avail: доступно (с учётом reserved). uint64, bytes
  • util: утилизация файловой системы. uint8, %
  • inodes_total: общее количество inodes. uint64, количество
  • inodes_used: использовано inodes. uint64, количество
  • inodes_free: свободно inodes. uint64, количество
  • inodes_util: утилизация inodes. uint8, %
  • readonly: файловая система в режиме только чтения (0/1). uint8

NET

Системная метрика сети: интерфейсные счетчики + host-level TCP/UDP стек + TCP congestion snapshot.

  • секция конфига: [[metrics.net]]
  • key: строковый идентификатор сущности метрики; используется в трёх режимах:
    • <iface> (например eth0) для интерфейсных var
    • total для host-level TCP/UDP var
    • cc:<algo> (например cc:cubic) для TCP congestion snapshot
  • для key=<iface>:
    • tx_bytes: отправлено байт за интервал опроса. uint64, bytes
    • rx_bytes: получено байт за интервал опроса. uint64, bytes
    • tx_bytes_per_sec: скорость отправки. uint64, bytes/сек
    • rx_bytes_per_sec: скорость приема. uint64, bytes/сек
    • tx_pkt: отправлено пакетов в секунду. uint64, пакетов/сек
    • rx_pkt: получено пакетов в секунду. uint64, пакетов/сек
    • rx_err: ошибки приёма. uint64, количество
    • tx_err: ошибки отправки. uint64, количество
    • rx_drop: отброшено при приёме. uint64, количество
    • tx_drop: отброшено при отправке. uint64, количество
  • для key=total:
    • tcp_active_opens: новые active TCP opens за интервал опроса. uint64, количество
    • tcp_passive_opens: новые passive TCP opens за интервал опроса. uint64, количество
    • tcp_retrans_segs: TCP ретрансмит-сегменты за интервал опроса. uint64, количество
    • tcp_timeouts: TCP timeouts за интервал опроса. uint64, количество
    • tcp_out_rsts: TCP reset-пакеты за интервал опроса. uint64, количество
    • udp_in_datagrams: входящие UDP datagrams за интервал опроса. uint64, количество
    • udp_out_datagrams: исходящие UDP datagrams за интервал опроса. uint64, количество
    • udp_in_errors: UDP ошибки приёма за интервал опроса. uint64, количество
    • udp_no_ports: UDP пакеты на закрытые порты за интервал опроса. uint64, количество
    • udp_rcvbuf_errors: UDP recv-buffer ошибки за интервал опроса. uint64, количество
    • udp_sndbuf_errors: UDP send-buffer ошибки за интервал опроса. uint64, количество
  • для key=cc:<algo>:
    • tcp_sockets: число TCP socket-сэмплов (после top-N). uint64, количество
    • tcp_tx_queue_bytes: сумма TCP tx-queue (bytes) по сэмплам. uint64, bytes
    • tcp_rx_queue_bytes: сумма TCP rx-queue (bytes) по сэмплам. uint64, bytes
    • tcp_retrans_pending: сумма pending retransmits по сэмплам. uint64, количество
    • tcp_cwnd_segs: средний cwnd (segments) по сэмплам. uint64, количество
  • tcp_cc_top_n: лимит TCP socket-сэмплов для key=cc:<algo>; 0 отключает cc:*

NETFLOW

Системная pull-метрика top-N сетевых flow-пар по интерфейсам (без cgo).

  • секция конфига: [[metrics.netflow]]
  • использует ту же кодовую базу доставки, что и другие pull-метрики: scrape -> window aggregate -> collector batch/queue/failover -> Vector -> ClickHouse. materialized view разворачивает значения составного ключа в отдельную таблицу netflow_pairs
  • key: строковый идентификатор сущности метрики; составной ключ iface|proto|src_ip|src_port|dst_ip|dst_port.
  • vars: bytes, packets, flows
  • все счетчики считаются за окно scrape и сбрасываются после каждого опроса (не монотонные):
    • bytes: сумма байт пакетов потока за окно
    • packets: количество пакетов потока за окно
    • flows: количество новых flow за окно
  • правило flows:
    • TCP: +1 только на пакете с флагами SYN && !ACK (новое соединение)
    • UDP: +1 при первом пакете tuple или после простоя tuple не меньше flow_idle_timeout (по умолчанию 10s)
  • поддерживаются несколько интерфейсов через маски ifaces = ["eth*","enp*","lo"]
  • top_n ограничивает число flow-ключей, отправляемых за окно
  • для raw-capture нужны привилегии: запуск агента от root (или capability CAP_NET_RAW)
  • рекомендуемый режим: percentiles = [] (last-only)

PROCESS

Системная метрика процессов с отбором по порогам cpu_util/ram_util/iops (логика ИЛИ, достаточно одного порога за окно отправки).

  • секция конфига: [[metrics.process]]
  • key: строковый идентификатор сущности метрики; имя процесса (proc.Name, без pid/cmdline).
  • cpu_util: утилизация CPU процессом. uint8, %
  • ram_util: утилизация RAM процессом = rss_process/ram_total_host*100. uint8, %
  • iops: операции чтения и записи процессом с блочного устройства. uint64, опер/сек

SCRIPT

Пользовательская pull-метрика из внешнего скрипта [[metrics.script.<name>]], где stdout содержит format=json ({key,data}) или format=prometheus (text exposition).

  • секция конфига: [[metrics.script.<name>]]
  • key: строковый идентификатор сущности метрики; для json берётся из поля key, для prometheus фиксирован total (labels игнорируются).
  • для format=prometheus: принимаются только gauge/counter, var_mode=full|short; отбор переменных делается стандартными filter_var/drop_var/drop_event.
  • при ненулевом exit code скрипта данные не отправляются
  • для каждого скрипта создаётся отдельная таблица в ClickHouse (<name>)
  • схема хранения для script-метрик полностью совпадает с остальными: dt, dts, dtv, теги, key, var, agg, value
  • пользователь самостоятельно создаёт стандартную схему таблицы ClickHouse под конкретный скрипт с обязательным полем key.

HTTP-SERVER

Пользовательская push-метрика: агент поднимает HTTP endpoint, принимает внешние данные и отправляет их по общим правилам.

  • секция конфига: [[metrics.http_server.<name>]]
  • key: строковый идентификатор сущности метрики; для json берётся из поля key, для prometheus фиксирован total (labels игнорируются).
  • HTTP: POST http://<listen><path>; тело запроса в формате json или prometheus (по format в конфиге); успешный приём: 204
  • для format=prometheus: принимаются только gauge/counter, var_mode=full|short; отбор переменных делается стандартными filter_var/drop_var/drop_event.
  • нет периода scrape (данные приходят извне); используется только send (период агрегации/отправки)
  • max_pending ограничивает буфер принятых пакетов; при переполнении политика фиксированная: сохраняем старое, дропаем новое (503)

HTTP-CLIENT

Пользовательская pull-метрика: агент делает GET по URL, парсит ответ в json или prometheus и отправляет данные по общим правилам.

  • секция конфига: [[metrics.http_client.<name>]]
  • key: строковый идентификатор сущности метрики; для json берётся из поля key, для prometheus фиксирован total (labels игнорируются).
  • поддерживаемые форматы ответа: format=json (контракт {key,data}) и format=prometheus (text exposition, только gauge/counter)
  • для format=prometheus: var_mode=full|short; отбор переменных делается стандартными filter_var/drop_var/drop_event
  • HTTP: GET (пока только GET); формат ответа определяется полем format
  • url поддерживает переменные в пути (path-escaped): {dc},{host},{project},{role},{metric},{instance}
  • instance = имя воркера (name в конфиге или автогенерированное), используется только для URL и логов (в событие/БД не попадает)

Внешние метрики (script, http_client, http_server)

  • отдельный тип метрик, формируемый внешним скриптом или приложением
  • применяются те же правила доставки и агрегации, что и для обычных метрик
  • общие поля события (dt, dts, глобальные теги, metric) формируются агентом, а не внешним источником
  • format=json: один и тот же JSON-контракт для stdout скрипта, body HTTP-SERVER, response HTTP-CLIENT
  • root: объект или массив объектов; каждый объект = 1 сущность метрики (1 key)
  • минимальный пример:
{"key":"total","data":{"util":{"last":67}}}
  • data.<var>: число, bool (0/1) или объект {last: <number>, kind?: "percent"|"number"}
  • format=prometheus: text exposition; принимаются только gauge/counter; key фиксирован total
  • format=prometheus: labels игнорируются; если для одного var пришло несколько series (разные labels), агент суммирует их значения в рамках одного scrape
  • last/pXX считает агент и уже их сохраняет/отправляет
  • общий лимит payload для json и prometheus: 16 MiB (больше — отклоняется)
  • для внешних метрик (script/http_server/http_client) без данных в окне событие не отправляется (synthetic zero не генерируется)

Конфиг

  • раздел [metrics]: параметры по умолчанию для всех метрик. [[metrics.<name>]] — раздел конкретной метрики. [[metrics.script.<name>]] — метрика, собираемая внешним скриптом. [[metrics.http_server.<name>]] — push HTTP-метрика. [[metrics.http_client.<name>]] — pull HTTP-метрика
  • для внешних метрик (script, http_server, http_client): format по умолчанию json; для prometheus используется var_mode=full|short, а отбор — через filter_var/drop_var/drop_event
  • percentiles — агрегаты значений раз в период отправки по периодам опроса. Массив целых значений (например [50,90,99]); ключи в JSON формируются как pXX
  • если percentiles не заданы ни глобально, ни в метрике, агрегации нет. Сохраняется только последнее измеренное значение за период отправки last (без pXX)
  • если глобальные percentiles заданы, метрика наследует их по умолчанию
  • если в конкретной метрике указать percentiles = [], процентили для этой метрики отключаются (только last)
  • интервалы scrape/send задаются с суффиксами времени (например 5s, 1m). Задаются глобально и могут быть переопределены в каждой метрике
  • для [[metrics.net]] доступен параметр tcp_cc_top_n (по умолчанию 2000); 0 отключает key=cc:<algo>
  • исключение по умолчанию: для [[metrics.process]] при отсутствии явного scrape используется 20s
  • drop_var и filter_var фильтруют поля (переменные) метрики, а не их значения. Задаются только в [[metrics.<name>]]. drop_var удаляет перечисленные переменные метрики. filter_var оставляет только перечисленные переменные. Можно использовать wildcard-маску *. Действия опциональны. Применяются только к переменным, не к тегам
  • drop_event дропает событие целиком, если одно или несколько условий выполнены. Формат условия: <field><op><value>, где op in =, !=, >, <.
  • для строк с = и != поддерживается wildcard * (пример: cmd=*postgres*, key!=core*)
  • пример: drop_event = ["iops>10000","key!=core*","var=rx_*"]
  • пример фильтрации по DISK ключам:
[[metrics.disk]]
name = "disk-main"
drop_event = ["key=/dev/loop*", "key=/dev/ram*"]

[[metrics.disk]]
name = "disk-nvme-only"
drop_event = ["key!=/dev/nvme*"]
filter_var = ["util", "*_bytes", "*_bytes_per_sec"]
  • теги не попадают под drop_var/filter_var/drop_event
  • таймаут выполнения скриптов в секундах (по умолчанию 5s), опционально
  • путь к скрипту для метрик из внешних скриптов, обязателен только в секции вызова скриптов
  • для [[metrics.process]] доступны пороги cpu_util, ram_util, iops. Если указаны — берём события выше или равные хотя бы одному порогу (логика ИЛИ). Если все три порога отсутствуют в конфиге, метрика не собирается

Отправка в коллектор

Передача в коллектор (vector)

  • Transport: Vector Protocol v2 (gRPC over HTTP/2, бинарный protobuf).
  • Семантика события: отправляем как log-event (структурированный payload), чтобы сохранять “пакет” 1:1 и не дробить на множество metric-events.
  • Отправлять батчами как PushEventsRequest с events: [EventWrapper, ...] (100..300/1000 шт), одним RPC.
  • конфиг коллекторов задаётся массивом [[collector]]
  • внутри одного [[collector]] поле addr = ["host1:port","host2:port"] используется в режиме failover (по очереди)
  • если задано несколько [[collector]], отправка выполняется во все коллекторы независимо
  • на подключение устанавливаются timeout, retry_interval
  • при временном переполнении внутреннего буфера отправки применяется backpressure: запись в буфер ждёт освобождения места или отмены context (без немедленного дропа события)

Дисковая очередь

  • отдельная дисковая очередь на каждый коллектор.
  • сохраняет сообщения по принципу «первый пришёл, первый ушёл», если все адреса коллектора недоступны. Пытается отправить раз в N секунд бесконечно. Очередь копится по количеству событий и/или по времени, что наступит раньше
  • хранит данные в нативном protobuf формате vector (тот же формат что и при отправке)
  • запись — только append в конец файла. Редактирование и удаление отдельных записей не поддерживается
  • чтение — последовательное, с хранением текущего offset в самой очереди и кэшированием в памяти
  • при отправке: читаем из файла батчами, отправляем. Если связь пропала — offset остаётся на месте, продолжаем при восстановлении
  • offset синхронизируется батчами/по таймеру (не на каждый ack), при корректной остановке принудительно flush
  • после полной отправки всего содержимого файла — файл очищается (truncate), offset сбрасывается в 0
  • путь к директории хранения очередей задаётся в конфиге (collector.queue.dir, обязательный параметр при enabled=true)

Конфиг

  • addr принимает массив значений в формате адрес:порт
  • [[collector.queue]] по умолчанию enabled=false. dir — путь до очереди, max_events — максимальное количество событий, max_age — время хранения в очереди. Работает то, что наступит раньше. Если указано что-то одно — работает только оно. При достижении лимитов старые события остаются, а новые не принимаются
  • данные для отправки копятся в батчи по количеству событий или по времени. Что наступит раньше
  • [[collector.batch]]: max_events — количество событий в батче, max_age — период накопления батча. Работает то, что наступит раньше
  • очередь и батчи ведутся отдельно для каждого коллектора, независимо от количества адресов в нём

Коллектор Vector

  • Vector обрабатывает пришедшее событие log-event Vector Protocol v2
  • разворачивает одно событие в N. Количество строк = сумма по всем переменным в data. Например: disk — имя таблицы, rx_iovar, last/p90agg, value — конкретные значения
  • для keyed полей (например core): каждый ключ × каждый агрегат = отдельная строка
  • роутинг в таблицу по имени метрики: table = {metric_name}
  • трансформация выполняется средствами VRL (Vector Remap Language): remap (разворот в массив событий); отдельный route не используется
  • результаты [[metrics.script.<name>]] направляются в таблицу <name>
  • стандартное поле времени события (.timestamp) переименовывается в dtv
  • host_ip берём из локального TCP адреса отправителя (агент добавляет поле перед PushEvents)

ClickHouse: принцип хранения

  • одна таблица на каждое имя метрики
  • для script-метрик имя таблицы равно <name>
  • для netflow аналитики используется связка:
    • raw-таблица netflow (универсальная схема dt,dts,dtv,tags,key,var,agg,value, в ней хранятся входные агрегаты потока)
    • materialized view mv_netflow_pairs (парсит составной key из raw-события и формирует аналитические поля пары)
    • итоговая таблица netflow_pairs (пары iface/proto/src_ip/src_port/dst_ip/dst_port + bytes/packets/flows)

Структура хранения ClickHouse

Имя таблицы задается по имени метрики

dt: DateTime64(3) CODEC(DoubleDelta)              // дата и время опроса события. один раз за период опроса, мсек
dts: DateTime CODEC(DoubleDelta)                  // дата и время отправки события. один раз за период отправки, сек
dtv: DateTime DEFAULT now() CODEC(DoubleDelta)    // время обработки события в Vector, сек
dc: LowCardinality(String)                        // хостер или площадка сервера, с которого пришла метрика. обязательный тег
host: LowCardinality(String)                      // имя хоста, с которого пришла метрика. обязательный тег
project: LowCardinality(String)                  // название проекта или часть системной архитектуры (frontdb/back)
role: LowCardinality(String)                     // роль хоста в системной архитектуре (frontdb/back/db ...)
host_ip: IPv6                                    // внешний IP-адрес хоста, с которого пришла метрика
key: LowCardinality(String)                      // обязательный ключ метрики
var: LowCardinality(String)                      // конкретная переменная метрики. total, used, util и т.д.
agg: LowCardinality(String)                      // название агрегата переменной метрики. last, p90, p99 и т.д.
value: UInt64                                    // конкретное значение агрегата agg
ORDER BY: (dt, host, key)
Партиционирование toYYYYMMDD(dt)
TTL: dt + INTERVAL 4 MONTH

netflow_pairs (итоговая аналитическая таблица)

dt: DateTime64(3) CODEC(DoubleDelta)               // время окна агрегации в агенте
dts: DateTime CODEC(DoubleDelta)                   // время отправки в коллектор
dtv: DateTime CODEC(DoubleDelta)                   // время вставки в итоговую таблицу
dc: LowCardinality(String)                         // глобальный тег
host: LowCardinality(String)                       // глобальный тег
project: LowCardinality(String)                    // глобальный тег
role: LowCardinality(String)                       // глобальный тег
host_ip: IPv6                                      // IP отправителя события
iface: LowCardinality(String)                      // интерфейс
proto: LowCardinality(String)                      // протокол (tcp/udp/...)
src_ip: IPv6                                       // source IP
src_port: UInt16                                   // source port
dst_ip: IPv6                                       // destination IP
dst_port: UInt16                                   // destination port
bytes: UInt64                                      // байты за окно
packets: UInt64                                    // пакеты за окно
flows: UInt64                                      // количество flow-записей за окно
ORDER BY: (dt, host, iface)
PARTITION BY: toYYYYMMDD(dt)
TTL: dt + INTERVAL 4 MONTH

Алертинг

https://github.com/Qedr1/malert

TODO

  • snmp trap

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages