journald-backed logging
By default, modules started by this app log to a flat file under PYOBS_LOG_DIR (via
pyobs --log-file). As an alternative, modules can instead log directly into the
systemd journal (via pyobs --syslog, a flag pyobs-core already supports) – one
switch changes both where modules are started to log and where the log viewer reads
them back from, so the two can never drift out of sync with each other.
Choosing a backend
PYOBS_LOG_BACKEND = None # None (default): auto-detect from pyobsd's own config
# "file" / "journald": explicit override
If unset, the effective backend is auto-detected from pyobsd’s own global config file
(~/.config/pyobs.yaml, /etc/pyobs.yaml, or /opt/pyobs/storage/pyobs.yaml, first
one found wins) – the same file pyobsd (pyobs-core’s daemon manager) reads to
decide whether it starts modules with --syslog, so this app’s own choice can’t
silently disagree with what pyobsd does for modules it manages itself. An explicit
"file"/"journald" setting always wins over auto-detection.
This is a global, fleet-wide switch, not a per-module setting – consistent with
PYOBS_LOG_DIR/PYOBS_LOG_LEVEL already being global. Switching backends is a clean
cutover: a module’s log history written under the old backend becomes invisible to the log
viewer once the switch flips. There’s no dual-read or merge-both-backends logic, and log
retention/rotation is unmanaged by this app either way – logrotate for file logs,
journald’s own retention settings (SystemMaxUse= etc.) for the journal.
What changes, and what doesn’t
Only the log-related pieces change: start_module() passes --syslog instead of
--log-file, and the log viewer shells out to journalctl instead of tail``ing a
file. Process management -- PID files, start/stop/restart, status checks, ``psutil-based
resource stats – is entirely unaffected either way.
Journal entries are queried by SYSLOG_IDENTIFIER=pyobs (the same for every module) plus
PYOBS_MODULE=<name> (the module-distinguishing field), and reconstructed into the exact
same text shape the file backend already produces (timestamp, [LEVEL], module name,
file:line, message) – so the level/timestamp parsing, filtering, and templates
downstream need no per-backend branching at all.
Deployment note: reading the journal cross-user requires the account running
pyobs-web-admin to have journal read access – typically satisfied by membership in the
adm or systemd-journal group on Debian/Ubuntu-family systems. A dedicated,
minimal-privilege service account may need to be added to one of those groups explicitly.
Loading older logs
Both log views (a module’s own Logs tab, and the fleet-wide All Logs page) only ever
fetch the most recent lines entries. Scrolling either view’s log pane to the top
auto-loads the next page of older entries and prepends them, preserving scroll position so
the line you were looking at doesn’t jump.
Setting a start date in the time-range filter turns it into a server-side since bound
rather than just a client-side filter, so the pane loads logs since that date and you can
page back through them. Setting an end date likewise becomes a server-side until bound,
so a past window is fetched exactly as [since, until] instead of the newest lines
entries being filtered down client-side (which previously showed “no matching log lines”
for any range that ended before the newest activity). The initial fetch and every
scroll-to-top page-back send both dates as since/until; the server bounds the query
accordingly (journalctl --since/--until on the journald backend, a timestamp window on
the file backend).
Scrolling to the top pages back with before (the oldest currently-loaded line’s own
timestamp). For the journald backend that’s a journalctl --until cutoff alongside the
existing -n <lines>, giving the next page of entries immediately before what’s already
on screen; the end date combines with the cursor as a second upper bound, the earlier of the
two winning. The file backend supports the same page-back once a start date is set (the
window is bounded by since), but a plain tail -n has no seek/offset to page further
back without a start date – so on a file-backed module with no start date the pane
reports “Beginning of available logs” the first time you scroll to the top, rather than
silently re-serving the same tail on every scroll.