feat(scheduler): every background run is a durable row

What a job last did lived in the API process's memory and was gone at
every restart; the audit log kept a run only when it was manual, failed
or changed something. Now each run is a job_runs row written at its
start and its end in its own session: who started it, its outcome as
data, what it spent of the YouTube quota (quota_events.job_run_id) and
the lines it logged (log_events.run_id, filterable in the log console).

- a run a stopped process left open is marked interrupted at startup
- "run now" is a one-shot job on the scheduler, which now always starts
  (interval jobs only with SCHEDULER_ENABLED); the manual actor is reset
  after the run, since pool threads are reused
- the dashboard's last run comes from job_runs, so it survives a deploy
- runs leave the audit log: migration 0109 moves the old job_run rows
  over (and back on downgrade); the audit page's run folding goes
- job_run_retention_days (default 30) prunes old runs in audit_gc
This commit is contained in:
2026-10-17 23:08:55 +02:00
parent 4b1f6d7ec2
commit 45c0ee7d58
31 changed files with 870 additions and 489 deletions
+2 -4
View File
@@ -1,6 +1,6 @@
{
"title": "Audit log",
"intro": "An append-only record of admin actions and scheduler run summaries — who did what, and when. Logged at action granularity, never per item.",
"intro": "An append-only record of admin actions — who did what, and when. Logged at action granularity, never per item.",
"empty": "No audit entries yet.",
"system": "System",
"clear": "Clear audit log",
@@ -20,7 +20,5 @@
"actor": "Who",
"action": "Action",
"details": "Details"
},
"earlierRuns_one": "{{count}} earlier run",
"earlierRuns_other": "{{count}} earlier runs"
}
}
@@ -16,7 +16,6 @@
"maintenance_tune": "Maintenance tuned",
"sync_pause": "Sync paused",
"sync_resume": "Sync resumed",
"job_run": "Scheduler job run",
"audit_clear": "Audit log cleared",
"download_credential_set": "Download cookies set",
"download_credential_delete": "Download cookies deleted",
+4
View File
@@ -170,6 +170,10 @@
"label": "Retention (days)",
"hint": "How long admin audit-log entries are kept before the audit-log cleanup job prunes them. 0 = keep forever. Default 180."
},
"job_run_retention_days": {
"label": "Run history (days)",
"hint": "How long the history of background runs (scheduled, run now, a channel's full history) is kept before the cleanup job prunes it. 0 = keep forever. Default 30."
},
"log_level": {
"label": "Log level",
"hint": "How much the server writes to its log. INFO is the normal setting; DEBUG and TRACE are for reproducing a problem and are far more detailed. Takes effect immediately, no restart."
+2 -4
View File
@@ -1,6 +1,6 @@
{
"title": "Eseménynapló",
"intro": "Az admin-műveletek és az ütemező futás-összegzéseinek csak-hozzáfűző naplója — ki, mit, mikor. Művelet-szinten naplózva, soha nem elemenként.",
"intro": "Az admin-műveletek csak-hozzáfűző naplója — ki, mit, mikor. Művelet-szinten naplózva, soha nem elemenként.",
"empty": "Még nincs naplóbejegyzés.",
"system": "Rendszer",
"clear": "Eseménynapló ürítése",
@@ -20,7 +20,5 @@
"actor": "Ki",
"action": "Művelet",
"details": "Részletek"
},
"earlierRuns_one": "{{count}} korábbi futás",
"earlierRuns_other": "{{count}} korábbi futás"
}
}
@@ -16,7 +16,6 @@
"maintenance_tune": "Karbantartás hangolva",
"sync_pause": "Szinkron szüneteltetve",
"sync_resume": "Szinkron folytatva",
"job_run": "Ütemezett feladat lefutott",
"audit_clear": "Eseménynapló ürítve",
"download_credential_set": "Letöltési cookie-k beállítva",
"download_credential_delete": "Letöltési cookie-k törölve",
+4
View File
@@ -170,6 +170,10 @@
"label": "Megőrzés (nap)",
"hint": "Meddig maradnak meg az admin-naplóbejegyzések, mielőtt az eseménynapló-takarító feladat törli őket. 0 = örökre. Alapérték 180."
},
"job_run_retention_days": {
"label": "Futási előzmények (nap)",
"hint": "Meddig maradnak meg a háttérfutások (ütemezett, azonnali, egy csatorna teljes előzménye) adatai, mielőtt a takarító feladat törli őket. 0 = örökre. Alapérték 30."
},
"log_level": {
"label": "Naplózási szint",
"hint": "Mennyit naplózzon a szerver. Az INFO a szokásos; a DEBUG és a TRACE hibakereséshez való, sokkal részletesebb. Azonnal érvénybe lép, újraindítás nélkül."