Request Sieve

Filter Nginx JSONL by host, request URI and time. Keep matching lines byte-for-byte.

Python 3.9+ and its standard library. No install step or network access. MIT license.

Try the included example

Extract the archive, enter its directory and run:

python3 request_sieve.py --host app.example \
  --uri '/report?a=1&b=2' --since 1700000000 \
  examples/access.jsonl

The three synthetic input records produce this one unchanged line:

{"epoch":1700000000.125,"host":"app.example","uri":"/report?a=1&b=2","status":200}

Exact means exact

  • --host and --uri use case-sensitive string equality. Repeat either flag to accept alternatives.
  • Host, URI and time filters combine with AND. No URL decoding, query sorting, wildcards or regular expressions.
  • --since includes the boundary. --before excludes it. Times are decimal Unix seconds, without binary floating-point rounding.
  • Spaces, key order, Unicode bytes, CRLF and a missing final newline stay intact.

Read a file or stdin

cat access.jsonl | python3 request_sieve.py \
  --host app.example --uri '/health?full=1'

One line is processed at a time. Memory depends on the longest line and its decoded JSON object. This is a finite-stream filter, not a log follower.

A small input contract

Every UTF-8 JSONL object needs these fields. Extra fields are retained.

host
A nonempty string, normally Nginx $host.
uri
The raw request URI, including its original query: $request_uri.
epoch
Finite decimal Unix seconds as a number or numeric string: $msec.

Compatible Nginx logging example

Malformed records stop processing with a filename and line number. Earlier matches may already be on stdout. Check the exit status before using an output file as complete.

Exit 0: success, including no matches. Exit 1: input or I/O error. Exit 2: invalid arguments. A closed output pipe stops quietly; see the full rules.

Release 0.1.0

Source archive: 6,421 bytes. Includes the standalone CLI, synthetic examples, guide, license and black-box CLI checks. Run python3 tests/test_cli.py from the extracted directory.

SHA-256: 6998d61b5b127628ce49ad0713e089cc51a4a5c7c37e1ae8fff0555028d6f2f0
Checksum file