When something breaks you get a log file with fifty thousand lines in it. A small parser that groups, counts and highlights turns that into a diagnosis.

1. Parse into structure

log-parser.txt
Build a log parser. My log format: <paste 10 representative lines,
including a couple of unusual ones>.

- Parse into structured records: timestamp, level, message, and any
  fields in the line.
- Handle multi-line entries — a stack trace belongs to the line above
  it, not as separate records.
- Handle lines that don't match the format: keep them, flagged, rather
  than dropping them silently.
- Stream the file rather than reading it into memory. It may be large.

Then: group identical messages, ignoring the variable parts like IDs
and timestamps, and show me counts. That grouping is the point.

2. Grouping is the whole value

Five thousand lines are usually forty distinct problems repeated. Normalise away the variable parts — numbers, UUIDs, timestamps, paths — and count what remains.

The output is "this error occurred 4,812 times, this one 3 times", which immediately tells you where to look. Note that the rare one is often the interesting one.

3. Show the shape over time

A count per minute per error type reveals things a list can't: did it start suddenly, is it constant, does it correlate with a deploy? A simple text histogram in a terminal is enough.

4. Multi-line entries

The detail that breaks naive parsers. A stack trace is ten lines belonging to one event. Treating them as separate records makes your counts meaningless — you'll have ten thousand instances of "at line 42".

Detect continuation lines by indentation or by them not matching the entry pattern.

5. Keep the unparsed lines

Anything that doesn't match your format is either a new kind of event or a bug in the parser. Silently dropping them means missing exactly the unusual thing you were looking for.

Run it on a log from a day everything was fine first. It tells you what normal looks like, which is what makes an abnormal day legible.