Перейти до змісту

System Info і діагностика

Сторінка Інформація (бокова панель → Інформація, route /system) — це адмін-діагностична поверхня BamDude — version metadata, DB row counts, storage breakdown, log viewer, debug-logging toggle, support bundle generator і кнопки maintenance (optimize DB, rebuild search index, check for updates).

Що це

Read-only дашборд, що тягне з GET /api/v1/system/info (більшість сторінки), GET /api/v1/system/storage-usage (storage breakdown) і GET /api/v1/support/logs (log viewer). Maintenance-actions — POST endpoint-и за відповідними permission-ами. Усе живе в running BamDude-процесі — зовнішня metrics-БД не потрібна (для цього див. Prometheus).

Version info

Поле Source
version APP_VERSION з backend/app/core/config.py, ставиться при build-time через node scripts/set_version.js.
python_version Версія Python interpreter running-процесу.
Database engine + version SHOW server_version на PostgreSQL, SELECT sqlite_version() на SQLite.
platform / architecture / hostname З Python-модуля platform.
boot_time / uptime System boot time з psutil, форматоване в Nd Nh Nm.

Build date і git SHA через цей endpoint не експонуються — release-білди печуть version string при set_version.js time, це канонічний ідентифікатор. Node version теж не репортиться; React-bundle шипиться pre-built під static/.

Database stats

GET /api/v1/system/info агрегує row counts і кілька sum-ів:

Stat Що рахує
archives Загальна кількість рядків print_archives.
archives_completed / archives_failed / archives_printing Те саме, partition за status.
printers Усі зареєстровані принтери.
spools Усі spool-records (live inventory rows).
projects Усі projects.
smart_plugs Усі зареєстровані smart-plug-и.
total_print_time_seconds / _formatted Сума print_time_seconds крізь усі архіви.
total_filament_grams / _kg Сума filament_used_grams.
database.size (під storage) Розмір файлу bambuddy.db або PostgreSQL DB size, якщо PG.

Storage usage breakdown

GET /api/v1/system/storage-usage ходить по data-директоріях і класифікує кожен файл в один з buckets, повертаючи size + percentage of total:

Bucket Roots
database bambuddy.db (і legacy bambutrack.db, якщо є).
library_thumbnails / library_files / library_other <data_dir>/library/....
archive_files / archive_thumbnails / archive_timelapses Сама archive-директорія.
virtual_printer_uploads / virtual_printer_upload_cache / virtual_printer_certs / virtual_printer_other <base_dir>/virtual_printer/....
downloads <base_dir>/firmware/.
attachments <data_dir>/projects/ і <data_dir>/products/ — вкладення замовлень і виробів.
plate_calibration Директорія plate-detection reference image.
logs Сконфігурована log-директорія.
other_data Все під data-теками, що не зматчилось правилом, з per-bucket sub-breakdown, що відрізняє system (deletable=false) від data (deletable=true).

Scan кешується на 5 хвилин (STORAGE_USAGE_CACHE_SECONDS = 300). Передай ?refresh=true, щоб форсити re-scan; передай max_age_seconds=N (clamped 0–3600), щоб override-нути cache TTL.

Дивись перед backup-ом

Окидаючи поглядом breakdown перед backup, бачиш — чи archive-тека є домінантною часткою (зазвичай так), і чи є headroom тримати timelapse-и, чи прунити їх спочатку.

Resource usage

Stat Source
CPU count + percent psutil.cpu_count() / psutil.cpu_percent(interval=0.1).
Memory total / available / used / percent psutil.virtual_memory().
Disk total / used / free / percent psutil.disk_usage(base_dir).
connected_printers Live MQTT-connected принтери з printer_manager.

Значення — point-in-time — refresh сторінки re-семплить їх. Historical rollup тут немає. Для time-series скрейпай Prometheus.

Log viewer

GET /api/v1/support/logs тейлить <log_dir>/bamdude.log, парсить кожен рядок у структурований entry, і повертає найсвіжіші entry-ї першими.

Param Замітки
limit 1–1000, default 200.
level DEBUG, INFO, WARNING або ERROR. Case-insensitive.
search Substring-match по message body і logger name. Case-insensitive.

Multi-line entry-ї (особливо stack traces) пересобираються — continuation-рядок прикріплюється до next-parsed entry над ним.

Дія Endpoint Permission
List recent logs GET /api/v1/support/logs settings:read
Truncate log-файл DELETE /api/v1/support/logs settings:update
Toggle DEBUG-level logging POST /api/v1/support/debug-logging settings:update

DEBUG-level logging gated

Helper _apply_log_level пінить httpcore і httpx на WARNING навіть у DEBUG mode — full request URL logging would leak bearer-токени в Discord / generic-webhook URL-ах. paho.mqtt перемикається на DEBUG, коли toggle on — там і живе більшість корисного printer-protocol detail.

Ротація + retention логів

Активний файл bamdude.log ротується під час першого запису після опівночі за локальним часом сервера. Архіви — звичайні текстові файли bamdude-YYYY-MM-DD.log. Перезапуск посеред дня не запускає ротацію примусово.

У Системній інформації → Файли логів першим показано bamdude.log із позначкою Поточний, розміром, часом зміни й кнопкою Завантажити. Він доступний, навіть якщо добових архівів ще немає. Завантажується повний файл станом на початок копіювання; запис логів триває. Перезапуск і ввімкнення DEBUG не потрібні, обмеження на хвіст логу з support bundle тут немає. Розмір у списку оновлюється кнопкою Оновити й може відрізнятися від пізнішого завантаження через нові записи.

Далі йдуть добові архіви, від найновішого, з кнопками Завантажити та Видалити з підтвердженням другим кліком. У поточного рядка кнопки видалення немає; наявна дія Обрізати у переглядачі логу залишається окремо.

Завантаження поточного логу використовує GET /api/v1/support/logs/download і потребує settings:read. Віддається необроблений текст, як і для архівів. Бекенд копіює знімок обмеженого розміру в робочому потоці, закриває активний файл до передачі мережею та видаляє тимчасову копію після передачі або обриву з'єднання. Якщо лог очистили під час копіювання, повторіть завантаження.

log_retention_days за замовчуванням — 7 (діапазон 1–365). Оператори з settings:update можуть змінити його в налаштуваннях. Новий ліміт одразу застосовується до хендлера, а зайві архіви видаляються під час наступної успішної ротації; саме збереження налаштування їх не видаляє.

Support bundle

GET /api/v1/support/bundle створює ZIP-файл з:

Файл Вміст
support-info.json Version, OS info, DB row counts, sanitised printer/integration info, anonymized settings, dependency versions, log-file size, network interfaces з masked subnets, WebSocket connection count, Docker memory limit (якщо containerised) — і сам процес BamDude, див. нижче.
bamdude.log Tail bamdude.log, sanitised.

Bundle вимагає, щоб debug logging був наразі ввімкнений — endpoint відмовляється генерувати інакше (400 Debug logging must be enabled before generating a support bundle). Workflow:

  1. Settings → System → перемкни DEBUG logging on.
  2. Відтвори issue.
  3. Згенеруй bundle.
  4. Перемкни DEBUG logging back off (інакше залишається on — стан персистить у Settings-таблиці і re-apply при рестарті).

Сам процес BamDude

Раніше бандл описував машину, базу, принтери й налаштування — усе, крім процесу, який власне працює. Тож звіт «пам'ять росте днями, поки його не вб'ють» приходив без нічого, з чим можна працювати: числа, які вказують на причину, існують лише поки це відбувається, а на момент запитання контейнер уже перезапущено.

Тепер бандли несуть:

Поле Чому важливо
Пам'ять у користуванні проти зарезервованої Різниця між цими двома й відрізняє справжній витік від нешкідливого адресного простору
Кількість потоків і дочірніх процесів Зростання кількості потоків — це інший баг, ніж зростання купи
Відкриті файли й сокети Витік дескрипторів ззовні виглядає як витік пам'яті
Uptime Дає масштаб усім іншим числам
Розбивка того, чим заповнена пам'ять Вказує, яке саме виділення росте

На вже дуже великому процесі розбивка пропускається — і про це сказано

Генерація бандла для діагностики некерованого росту пам'яті не має стати тим, що добиває машину.

Дочірні процеси записуються лише за іменем, ніколи за командним рядком — у командному рядку ffmpeg лежить пароль камери.

Це потрапляє і в бандл, який ти завантажуєш, і в пакет, доданий до звіту про баг.

Sanitisation

_sanitize_log_content і _collect_support_info працюють разом, щоб тримати secret-и зовні:

  • Printer names → [PRINTER], serial numbers → [SERIAL], IP addresses → [IP], access codes → [ACCESS_CODE], usernames → [USER], email-и → [EMAIL].
  • URL credentials (http://user:pass@host, rtsps://bblp:code@host) → [CREDENTIALS]@.
  • LDAP Distinguished Name-и → [DN]. Провідний CN= у DN — це справжнє ім'я користувача, тож поводимось із ним як з email. На відміну від решти списку, DN не візьмеш із БД — він per-user і приходить із твого каталогу — тому ловиться за формою: два або більше attr=value-компонентів через кому. Тобто CN=Joe Schmoe,OU=Staff,DC=example,DC=com прибирається всюди, де трапиться, включно з текстом помилки від бібліотеки каталогу. Одинокий key=value у сторонньому рядку не чіпається.
  • Path-компоненти типу /home/<user>/, /Users/<user>/, /opt/<user>/ колапсуються в /home/[user]/ тощо.
  • MQTT relay broker → masked: bare IP стає [IP], hostname стає *.tld.
  • Subnets в network info → перші два октети стають x.x (тож 192.168.1.0/24 → x.x.1.0/24).
  • Settings values — ключі, що містять будь-яке з access_code, password, token, secret, api_key, cloud_token, mqtt_password, email, username, vapid, private_key, public_key, webhook, url, path, config, _ip, host, credential редактяться у [REDACTED] (або "" якщо порожнє). Будь-які інші settings passthrough as-is, тож feature flags і themes видно в bundle.

Bundle — правильна штука, щоб приклеїти до GitHub-issue при репорті бага.

Maintenance actions

Дія Endpoint Permission
Optimize / vacuum SQLite — виконує ANALYZE, PRAGMA wal_checkpoint(TRUNCATE), потім VACUUM POST /api/v1/settings/optimize-db settings:backup
Rebuild archive search index — див. Search POST /api/v1/archives/search/rebuild-index archives:update_all
Check for updates — див. Updates нижче GET /api/v1/updates/check system:read

Окремої "Clear Cache" кнопки на BamDude System-сторінці немає — page-level кеші (storage breakdown, system info) автоекспайряться самі; єдиний manual flush — ?refresh=true query-param на /system/storage-usage.

"Restart application" кнопки теж немає — upstream Bambuddy-концепт in-app restart має сенс тільки для bare-metal/systemd-інсталів, а target-deployment BamDude — Docker. Рестартуй контейнер через docker compose restart bamdude (або що там в твоєму orchestrator-і).

Update checker

GET /api/v1/updates/check poll-ить GitHub Releases і порівнює latest-tag до APP_VERSION. Два setting keys кермують поведінкою:

Setting key Ефект
check_updates (default true) Коли false, endpoint повертає {update_available: false, message: "Update checks are disabled"} без походу на GitHub.
include_beta_updates (default false) Коли true, prerelease-и (X.Y.ZbN) — eligible matches. Коли false, тільки stable-релізи. Detection — dual-signal: реліз вважається prerelease якщо тег матчить bN/betaN/alphaN/rcN АБО якщо marked-prerelease у GitHub UI.

Check-response несе is_prerelease, is_docker, latest_version — UI рендерить правильні install-команди per-channel + per-install-shape.

In-app apply (native-інстали)

POST /api/v1/updates/apply робить фактичний git checkout + dependency install. Поведінка з 0.4.4:

  • Приймає опційний tag_name body field — frontend передає те, що тільки що отримав з /check, щоб apply ударив exact-реліз який юзер бачив.
  • Резолвить у vX.Y.Z[bN] git-ref через _resolve_git_ref() (працює і з v-prefixed і з bare формами).
  • Виконує git fetch origin --tags --prune --force потім git reset --hard refs/tags/<ref>. Працює для будь-якого tag незалежно від гілки — pre-fix хардкодив git reset --hard origin/main, що тихо no-op'ило бета-інстали (бо бета-теги на dev, не main).
  • Встановлює Python-deps (pip install -r requirements.txt) і ребілдить frontend-бандл (npm install && npm run build) коли npm доступний.

Endpoint потребує settings:update. Запуск з Settings → System → Install Update коли update показано як available.

Docker-інстали

Docker-інсталам /apply відмовляє з is_docker: True — запуск git fetch / pip install / npm build всередині запущеного контейнера зіпсує image. Замість того UI surface-ить дві бокові секції з конкретними командами що використовують resolved latest_version + is_prerelease:

Image-based (типове) — більшість операторів запускає image: kainpl/bamdude:<tag> у compose-файлі:

# docker-compose.yml
image: kainpl/bamdude:0.4.5b1     # для бет — явний пін обов'язковий
# АБО
image: kainpl/bamdude:latest      # для stable (latest трекає тільки main)
docker compose pull && docker compose up -d

Hint-текст у UI явно пояснює чому :latest не підтягне бету — :latest Docker tag трекає main, бети тегаються на dev і шипляться як :X.Y.ZbN без :latest-промоушна.

Source-build — для операторів які склонували репо і використовують build: у compose:

git fetch origin --tags --prune --force
git checkout v0.4.5b1
docker compose build --pull
docker compose up -d

Це BamDude self-update path. Для printer firmware оновлень див. Firmware Updates — повністю окремий flow.

Permission-и

Дія Permission
Дивитись system info, storage usage, update check system:read
Дивитись logs, отримати debug-logging state, генерувати support bundle settings:read
Toggle debug logging, clear logs settings:update
Optimize/vacuum DB, restore backup settings:backup
Rebuild archive search index archives:update_all

system:maintenance чи support_bundle:create permission-у немає — support bundle і log endpoint-и сидять під namespace settings.

API reference

GET    /api/v1/system/info             # full system snapshot
GET    /api/v1/system/storage-usage    # bucketed storage breakdown
GET    /health                         # unauthenticated liveness probe ({"status":"healthy"})
GET    /api/v1/support/logs            # tail bamdude.log
DELETE /api/v1/support/logs            # truncate log-файл
GET    /api/v1/support/debug-logging   # поточний debug-logging state
POST   /api/v1/support/debug-logging   # toggle debug logging
GET    /api/v1/support/bundle          # download support ZIP
POST   /api/v1/settings/optimize-db    # ANALYZE + WAL checkpoint + VACUUM
POST   /api/v1/archives/search/rebuild-index  # rebuild FTS index
GET    /api/v1/updates/version         # current version (unauthenticated)
GET    /api/v1/updates/check           # check GitHub for newer release

Unauthenticated /health whitelist-нутий setup-gate middleware-ом, тож скрейпай його ще до того, як initial setup completes.