
Skill
symfony-log-investigation
investigate Symfony application logs
Description
Investigate an error or behavior across Monolog log files when there is no single profile to read, or when tracking something over time or across requests. Use for "when did this start", "how often", or following one request/user through the logs. For a single known request that still has a profile, prefer profiler debugging.
SKILL.md
Log investigation
Reads Monolog files through Mate's CLI. Entries come back as {datetime, channel, level, message, context, extra, source_file, line_number}. Sensitive context keys are redacted in the output but still matched when you search them.
monolog-list-files(optenvironment): what log files exist, newest first.monolog-list-channels: distinct channel names (app,security,doctrine, ...). Reads every file, so it is the slow one; skip it if you already know the channel.monolog-tail(limit,level,environment,channel): most recent entries. Reads ONLY the single newest file.monolog-search(term,regex,level,channel,environment,from,to,limit): searches across all files. Emptytermwith filters set = filter-only.monolog-context-search(key,value,level,environment,limit): matches a structured context field. No channel or date filter here.
These commands accept --format: json to parse the result, toon (when helgesverre/toon is installed) for the smallest context footprint. A wide search returns many entries, so narrow with filters and a limit before widening the output format.
Workflow
- Orient:
vendor/bin/mate tools:call monolog-list-files. Confirm the environment you care about is present and recently modified. - Latest state:
vendor/bin/mate tools:call monolog-tail --level=error --limit=50. Good for "what just broke", nothing else. - Narrow with search:
vendor/bin/mate tools:call monolog-search --term="Timeout" --level=error- Time-box it:
--from="-1 hour",--from=2026-07-01 --to=2026-07-02. Any PHP-parseable date works. - Regex:
vendor/bin/mate tools:call monolog-search --term="user \d+ locked" --regex. A bare pattern is wrapped as/.../i; pass your own/.../or#...#to control anchoring and flags.
- Pivot on a field: once you have an identifier (request id, user id, order id), follow it with
vendor/bin/mate tools:call monolog-context-search --key=request_id --value=abc123. This is how you reconstruct one request or one user across many lines.
Reading
- Correlate
channel+level+datetime. The channel tells you the subsystem (doctrine= DB,security= auth,request/php= framework), the level tells you severity, the timestamp anchors it to a deploy or an incident. - A cluster of same-
messageerrors starting at one timestamp is the onset. Use it as the--fromto see what preceded it. source_file+line_numberpoint back into the log file, not your application code.
Failure paths
- No matches: widen before concluding. Drop
--level, widen the date window, try a shorter or partialterm.levelmatches exactly (case-insensitive);WARNwill not matchWARNING. - Wrong channel:
--channelis an exact (case-insensitive) name. Runmonolog-list-channelsif unsure rather than guessing. monolog-taillooks empty or stale: it only reads the newest file. Rotated history (prod-2026-07-01.log) is invisible to tail; usemonolog-searchwith a date range to reach it.- Nothing logged at all: the app may log to stderr/syslog rather than a file, or the level threshold filters it out before it is written. The profiler
loggercollector still captures per-request logs even when file logging is quiet.