Аудитория: суперадминистратор, интегратор, технический заказчик. Закрывает вопрос: «есть ли отдельный клиент сбора? это уже в нашей инфраструктуре или нет?». Сценарий: планируем боевой пилот — нужно честно понимать, что готово, а что предстоит.
Концептуально «как собираем» — статья 13. Здесь — честный статус реализации без приукрашивания: что живёт в коде уже сегодня, а что — заглушка с боевым интерфейсом.
Отдельного клиента, который реально ходит в боевые KSC/1С/журналы, сегодня НЕТ. Что есть:
- вся «труба» вокруг сбора — живая и работает (планировщик в отдельном контейнере, приём
по сети, обезличивание, распознавание, идемпотентное хранение, журнал прогонов);
- контракт коннектора (
Collector) — финальный, тот самый, что будет у боевого источника; - но реализация коннектора — фикстура: она читает CSV, сгенерированный из наших данных, а
не подключается к живой системе заказчика.
Это сознательный инженерный приём — «боевая сигнатура»: сначала строим и отлаживаем весь тракт на безопасной заглушке с *настоящим* интерфейсом, потом меняем только «голову», которая достаёт данные. Переход на боевой источник не требует переписывания продукта.
| Компонент | Что это | Статус |
|---|---|---|
| Контейнер-планировщик (cron, по тикам) | отдельный сервис collector (APScheduler) | ✅ живой |
| Приём телеметрии по сети | эндпоинт POST /ingest/activity (с RBAC) | ✅ живой |
| Обезличивание табельного (Стрибог) | хеш-функция на приёме | ✅ живое |
| Распознавание ПО (сырое имя → система) | Recognition Parser | ✅ живое |
| Идемпотентное хранение фактов | ON CONFLICT по зерну (tenant, sys, user, date) | ✅ живое |
Журнал прогонов (collector_runs) + экран /collectors | таблица прогонов + фронт | ✅ живой |
Контракт коннектора (Collector Protocol) | единый протокол источника | ✅ финальный |
| Три типа источника зарегистрированы | _REGISTRY: ksc_sql / odata_1c / syslog_evtx | ✅ заведены |
То есть «петля сбора» крутится по-настоящему: каждый тик планировщик берёт коннектор, получает записи, приём их обезличивает и кладёт, прогон фиксируется. Можно зайти на /collectors и видеть, как копятся прогоны.
| Чего нет | Что вместо | Что нужно сделать |
|---|---|---|
| Реальный адаптер к KSC SQL | FixtureFileCollector("ksc_sql") читает CSV | класс KscSqlCollector с тем же Collector |
| Реальный адаптер к 1С OData | фикстура odata_1c | класс Odata1cCollector |
| Реальный приём syslog/evtx | фикстура syslog_evtx | класс SyslogEvtxCollector / приёмник WEF |
| Агент/форвардер на стороне заказчика (если нужен push) | нет | скрипт/сервис, шлющий батчи в /ingest/activity |
| Боевые строки подключения/доступы | нет | секреты заказчика (env/конфиг) |
Сегодня источник — это CSV, который генерируется из тех же сид-констант, что и витрина. Поэтому собранные данные совпадают с засеянными (близнец Static == Http == Ingested) — это удобно для демонстрации и тестов, но это не данные реальной организации.
Портал стоит внутри сети заказчика и имеет доступ к KSC/1С/журналам.
[ KSC БД / 1С OData / syslog ] ◄── коннектор (внутри контейнера collector) тянет по расписанию- Плюс: ничего не ставится на рабочие места — данные берутся у уже существующих агрегаторов.
- Реализация:
KscSqlCollector.collect()подключается к боевой БД KSC, отдаётTelemetryRecord. - Где менять: одна запись в
_REGISTRY(get_collector). Приём/планировщик не трогаем.
Портал стоит снаружи периметра или к источникам нет прямого доступа.
[ агент/скрипт у заказчика ] ──► POST /api/{tenant}/ingest/activity ──► приём- Плюс: портал не нужно пускать во внутреннюю сеть; заказчик контролирует, что уходит.
- Реализация: лёгкий форвардер (роль
collector, JWT), который раз в смену собирает выгрузку и
шлёт батч. Эндпоинт приёма уже готов — это и есть «клиентский слой» в модели push.
Важно: в обеих моделях «клиент» подключается к агрегатору (KSC/1С/журналы), а не к каждой программе. Свой агент на каждом ПК почти никогда не нужен — там, где KSC не покрывает session- минуты, их даёт штатный Windows Event Forwarding (4688/4689), это настройка ОС, а не наш агент.
# боевой коннектор — тот же контракт Collector
class KscSqlCollector:
source_type = "ksc_sql"
def collect(self, tenant_id, since=None):
# 1) подключиться к боевой БД KSC заказчика (строка подключения — из env/секрета)
# 2) SELECT по инвентарю/активности за период since..now
# 3) на каждую дневную строку: yield TelemetryRecord(tabel_no, raw_product, date, tx, minutes)
...
# заменить заглушку на боевой коннектор — ОДНА строка:
_REGISTRY["ksc_sql"] = KscSqlCollector()Всё остальное (обезличивание, распознавание, идемпотентность, прогоны, экраны) уже работает и не меняется. Это и есть выгода «боевой сигнатуры»: интеграция = написать collect(), а не переделывать продукт.
- Тракт готов — можно показывать заказчику живой сбор уже сейчас (на фикстуре).
- Боевое подключение = адаптеры под конкретные KSC/1С/журналы заказчика + его доступы.
Это ограниченная работа на стыке, а не переписывание.
- Модель (pull/push) выбирается под сетевой контур и политику ИБ заказчика — продукт
поддерживает обе без изменения ядра.
- Это в дорожной карте (ROADMAP, Фаза 2+: реальные коннекторы, провижининг через
Ansible/WinRM/SSH, SSO) — осознанно отложено до реального внедрения, чтобы не тащить зависимости и риски аттестации раньше времени.
- Не выдавайте стенд за боевой сбор. На стенде данные — из фикстуры (= из сида). «Артек
covered=6, avg 0.6585» — это демонстрационный профиль, не реальная организация.
- Боевой коннектор приносит реальные ПДн на вход — обезличивание на приёме уже это
покрывает, но доступы к KSC/1С и хранение секретов подключения — зона ответственности внедрения (env/секрет-менеджер, не БД/не git).
- `source_type` ≠ готовый источник. То, что тип
odata_1cзарегистрирован, означает «труба
под него есть», а не «1С заказчика уже подключена».
Связанные: 13 — Как собираются данные (по Фейнману) · 03 — Коннекторы под капотом · 04 — Механизм сбора.