| Age | Commit message (Collapse) | Author |
|
Switch the default log config to directory-watch mode, which handles
TF2's per-map log rotation automatically. Keep the old logs: symlink
approach as a commented alternative.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
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>
|
|
README gets a Matrix bot section covering setup, commands, config paths,
and dependencies. AGENTS gets the bot added to the file map and a full
Matrix bot section covering the formatting rules (markdown->HTML via the
markdown library, no emojis, no em dashes), power level requirements,
command/socket message mapping, tail data flow, and config layout.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
markdown.markdown() collapses single newlines into soft wraps, causing
multi-line responses (e.g. !units list) to render as one long line.
The nl2br extension converts \n to <br> in the HTML output.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
formatted_body was passing raw Markdown to Matrix clients, causing literal
asterisks and backticks to display instead of rendered formatting. Now
converts to HTML via the markdown library with the fenced_code extension.
Also replaced emoji characters (checkmarks, X marks) with plain text and
substituted em dashes with hyphens throughout response strings and HELP_TEXT.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
README covers build, install layout, unit YAML format, bundled filters,
log setup, and CLI usage.
AGENTS.md is a compact reference for AI coding assistants: hard design
rules, full file map, key data flows, wire protocol, YAML parser gotcha,
log tail setup pattern, filter contract, and all limits.
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>
|
|
Sequence items arrive as SCALAR events with in_value==0 (no preceding
key), so they were being treated as keys and silently discarded.
Handle SECTION_LOGS scalars directly as list items when in_value is
unset, leaving the normal key/value path for all other sections.
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>
|
|
State probing overhaul, A2S queries, tail/broadcast, bot audit log
|
|
State detection:
- Add STATE_STOPPING to ProcessState enum
- Replace system("systemctl is-active") with libsystemd sd-bus API for
accurate starting/stopping/crashed state reporting; works for any unit
type (RCON or STDIN) that declares a service: field
- Implement real A2S_INFO UDP queries (src/console/a2s.c) for units
with health.type = a2s (Valve games: TF2, GMod); differentiates
running / hibernating (0 players) / changing_map (A2S down, RCON up)
/ unreachable; includes player count and map name in responses
- Refactor probe_rcon_state() into probe_unit_state() returning a
ProbeResult struct with state, players, max_players, map fields
- status and list responses now include players/max_players/map fields
New daemon commands:
- tail <unit>: return ring buffer snapshot as a single response
- broadcast <message>: send broadcast_cmd-formatted message to all
running units; works for both RCON and STDIN console types
New YAML field:
- broadcast_cmd: command template (e.g. "say {msg}") — opt-in per
unit; units without it are skipped by broadcast
CLI (umbrella-cli):
- Add tail subcommand (non-interactive output snapshot)
- Add broadcast subcommand
- status shows Players and Map when available
- list adds PLAYERS and MAP columns
Bot (umbrella-bot):
- Replace !attach / !detach with !tail (shows last 30 lines, no streaming)
- Add !broadcast command
- Write per-!cmd audit entries to /var/log/umbrella/bot-audit.log
- !units and !status responses include player counts when available
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Previously, `umbrella-cli list` reported each unit's cached internal
state, while `umbrella-cli status <unit>` used probe_rcon_state() to
actively verify RCON units via systemd and a live network probe. This
caused the list to show stale or inconsistent state compared to status.
Move probe_rcon_state() before cmd_list() and use it there so both
commands share the same state determination logic.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Add Claude Code GitHub Workflow
|
|
|
|
|
|
|
|
|