23

I wanted a small tool to slice gigabyte-sized JSON-lines logs by level and time range and print a summary, but the first version the model gave me did open(f).read() and json.loads on the whole thing, which OOM'd on anything real.

The prompt now mandates streaming line-by-line, tolerating malformed lines, and supporting both a file and stdin so it drops into a pipe. Requiring it to handle a truncated final line and non-JSON garbage without crashing made it robust against real logs, which are always messier than the sample.

How do people prompt for time-range filtering when logs mix timezones? I force UTC normalization and treat naive timestamps as a configurable default.

THE PROMPT
Build a Python CLI `logslice` that reads JSON-lines logs (one JSON object per line) from a FILE argument or stdin, filters and summarizes them, and never loads the whole file into memory.

Requirements:
- Stream line by line (iterate the file object); memory usage must be O(1) in the number of lines. Works on multi-GB files and on `tail -f`-style pipes.
- Read from stdin when no file is given or the arg is `-`, so it composes in pipelines.
- Tolerate messy input: skip and count malformed/non-JSON lines and a truncated final line; never crash on bad data. A `--strict` flag makes malformed lines a hard error instead.
- Filters: `--level {debug,info,warn,error}` (>= threshold), `--since`/`--until` ISO timestamps, `--grep REGEX` on the message field. Normalize all timestamps to UTC; treat naive timestamps as `{DEFAULT_TZ}`.
- Output modes: default prints matching lines; `--summary` prints counts by level, top {N} messages, and time span, without printing every line.
- Correct exit codes (0 = matches found or summary ok, 1 = runtime error, 2 = bad args) and grep-like behavior for pipelines. Flush stdout so `| head` doesn't cause a BrokenPipe traceback (handle SIGPIPE).
- Keep parse/filter/summarize as separate pure functions for unit tests.

List the failure modes you handle (empty file, all-malformed, huge single line, mixed timezones) and confirm each is covered.

2 Answers

15

The SIGPIPE detail is the one everyone forgets and then their tool spews a BrokenPipeError traceback the moment you pipe it to head. On Python you basically have to restore the default SIGPIPE handler at startup on Unix, or wrap the write loop and swallow BrokenPipe. Bake the exact snippet into the prompt or the model will 'handle' it with a try/except that still prints the traceback on exit.

THE PROMPT
Add at startup (Unix): `import signal; signal.signal(signal.SIGPIPE, signal.SIG_DFL)` and explain it makes the tool die quietly like a normal Unix filter when the downstream pipe closes.
8

For the huge-single-line failure mode, add a --max-line-bytes cap. A corrupt log can contain a 2GB 'line' with no newline and your O(1) streaming assumption dies right there because readline buffers the whole thing. Guard it and skip+count over-length lines like any other malformed record.

Your Answer