Add owner-only logging and Brickset API call tracking

LIM configured no logging at all, so the instruction fetcher had no trail to follow. Adds a rotating file handler on the root logger plus two owner-only admin pages.

- Admin > Logs: filter by level, source and text; tracebacks kept with their error; auto-refresh, raw download, rotated-file browsing and rotate-now

- Admin > Logs > Brickset API calls: every outbound call recorded with method, params, caller, duration, result count and error, plus daily quota accounting (only getSets counts) and a comparison against getKeyUsageStats

- New owner concept (services/ownership.py): a single account, distinct from is_admin, since these pages expose other admins activity. Defaults to the first admin; flask owner show/set to change

- Services now log through module loggers; retention setting and pruning for call records

- New CLI: flask owner show/set, flask logs path/prune

- New table brickset_api_calls, created automatically at boot; LOG_* env vars, /data/logs in Docker
This commit is contained in:
jessikitty committed 2026-09-27 10:42:49 +10:00
1 parent 89f65e2d74
commit f7c20de5ac
27 files changed
+1914 -35

No files matched your search

+27 -3
View File
@@ -1,6 +1,6 @@
@echo off
REM ===========================================================================
REM LEGO Instructions Manager - Instruction Fetcher installer
REM LEGO Instructions Manager - Instruction Fetcher + Logging installer
REM
REM RUN THIS FROM THE FOLDER YOU EXTRACTED THE UPDATE INTO, not from your
REM LIM install - the two cannot be the same folder.
@@ -46,23 +46,31 @@ call :need "app\__init__.py"
call :need "app\cli.py"
call :need "app\config.py"
call :need "app\models\__init__.py"
call :need "app\models\api_call.py"
call :need "app\models\instruction.py"
call :need "app\models\instruction_fetch.py"
call :need "app\models\site_setting.py"
call :need "app\routes\__init__.py"
call :need "app\routes\instruction_fetch.py"
call :need "app\routes\logs.py"
call :need "app\services\brickset_api.py"
call :need "app\services\fetch_worker.py"
call :need "app\services\instruction_fetcher.py"
call :need "app\services\logging_setup.py"
call :need "app\services\ownership.py"
call :need "app\services\schema_upgrade.py"
call :need "app\templates\admin\brickset_calls.html"
call :need "app\templates\admin\dashboard.html"
call :need "app\templates\admin\instruction_fetch.html"
call :need "app\templates\admin\logs.html"
call :need "app\templates\admin\settings.html"
call :need "diagnose_fetcher.py"
call :need "docker-compose.yml"
call :need "docker\entrypoint.sh"
call :need "docs\INSTRUCTION_FETCHER.md"
call :need "docs\LOGGING.md"
if not "%MISSING%"=="0" goto :incomplete
echo all 22 present.
echo all 30 present.
REM --- backup ------------------------------------------------------------------
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /value') do set "DT=%%I"
@@ -81,21 +89,29 @@ call :save "app\__init__.py"
call :save "app\cli.py"
call :save "app\config.py"
call :save "app\models\__init__.py"
call :save "app\models\api_call.py"
call :save "app\models\instruction.py"
call :save "app\models\instruction_fetch.py"
call :save "app\models\site_setting.py"
call :save "app\routes\__init__.py"
call :save "app\routes\instruction_fetch.py"
call :save "app\routes\logs.py"
call :save "app\services\brickset_api.py"
call :save "app\services\fetch_worker.py"
call :save "app\services\instruction_fetcher.py"
call :save "app\services\logging_setup.py"
call :save "app\services\ownership.py"
call :save "app\services\schema_upgrade.py"
call :save "app\templates\admin\brickset_calls.html"
call :save "app\templates\admin\dashboard.html"
call :save "app\templates\admin\instruction_fetch.html"
call :save "app\templates\admin\logs.html"
call :save "app\templates\admin\settings.html"
call :save "diagnose_fetcher.py"
call :save "docker-compose.yml"
call :save "docker\entrypoint.sh"
call :save "docs\INSTRUCTION_FETCHER.md"
call :save "docs\LOGGING.md"
echo %SAVED% file^(s^) backed up.
REM --- install -------------------------------------------------------------------
@@ -108,26 +124,34 @@ call :put "app\__init__.py"
call :put "app\cli.py"
call :put "app\config.py"
call :put "app\models\__init__.py"
call :put "app\models\api_call.py"
call :put "app\models\instruction.py"
call :put "app\models\instruction_fetch.py"
call :put "app\models\site_setting.py"
call :put "app\routes\__init__.py"
call :put "app\routes\instruction_fetch.py"
call :put "app\routes\logs.py"
call :put "app\services\brickset_api.py"
call :put "app\services\fetch_worker.py"
call :put "app\services\instruction_fetcher.py"
call :put "app\services\logging_setup.py"
call :put "app\services\ownership.py"
call :put "app\services\schema_upgrade.py"
call :put "app\templates\admin\brickset_calls.html"
call :put "app\templates\admin\dashboard.html"
call :put "app\templates\admin\instruction_fetch.html"
call :put "app\templates\admin\logs.html"
call :put "app\templates\admin\settings.html"
call :put "diagnose_fetcher.py"
call :put "docker-compose.yml"
call :put "docker\entrypoint.sh"
call :put "docs\INSTRUCTION_FETCHER.md"
call :put "docs\LOGGING.md"
if not "%COPYFAIL%"=="0" goto :copyfailed
echo.
echo ==========================================================
echo Done - 22 files installed.
echo Done - 30 files installed.
echo.
echo No migration step: the new table and columns are created
echo the next time LIM starts.