| Age | Commit message (Collapse) | Author |
|
Valve games (TF2, GMod) rotate into a new timestamped log file on every
map change. The existing fixed-path inotify watch goes stale after the
first rotation. This adds a directory-watch mode that auto-switches to
the newest matching file whenever one appears.
New YAML fields (mutually exclusive with logs:):
log_dir: directory to watch for new log files
log_pattern: fnmatch(3) glob for filenames; default "*"
Changes:
- umbrella.h: add log_dir[MAX_PATH] and log_dir_pattern[MAX_PATH] to Unit
- log_tail.c: extend LogWatch with dir_wd/dir_path/pattern fields;
add log_tail_drain, log_tail_scan_dir, log_tail_switch_file,
log_tail_open_fixed_watch, log_tail_open_dir_watch,
log_tail_reopen_fixed, log_tail_handle_rotation_dir;
refactor log_tail_init, log_tail_handle, log_tail_cleanup
- unit.c: parse log_dir and log_pattern YAML keys; warn and drop logs:
if both are set on the same unit
- AGENTS.md, README.md: document both log-tail modes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Each unit can specify log_filter: <path> pointing to any executable
that reads stdin and writes filtered output to stdout. The daemon
spawns it once at startup (and on SIGHUP), pipes raw log data through
it before ring-buffering and broadcasting to attached clients.
filter.c handles spawn (fork/exec with pipes), per-chunk apply
(write + poll with 250ms timeout, pass-through on silence/timeout),
and stop (SIGTERM + fd cleanup). Filters are stopped and restarted
cleanly on SIGHUP alongside log_tail.
Bundled filters in filters/:
source.py — TF2, GMod: strips server_cvar/stuck/path_goal spam,
strips the L MM/DD/YYYY - HH:MM:SS: prefix
minecraft.py — vanilla/Paper/Spigot: strips keepAlive, autosave,
internal class logs, strips [HH:MM:SS] [thread] prefix
terraria.py — vanilla/tModLoader: strips blank lines and mod
loading noise during startup
Any executable reading stdin/writing stdout works as a custom filter.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
inotify watches the symlink inode itself, not the target, so IN_MODIFY
never fires when the target file is written. Use realpath() to resolve
the configured path before open() and inotify_add_watch(), allowing
a stable symlink (e.g. current.log) in the unit YAML that gets
re-resolved to the actual log file on each init/SIGHUP.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Detect IN_MOVE_SELF/IN_DELETE_SELF events in log_tail_handle and
re-open the watched path so srcds log rotation is followed correctly
- Parse inotify events rather than blindly draining them
- Call log_tail_cleanup() before log_tail_init() on SIGHUP to prevent
fd leaks on reload
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|