Guide / Overview

sift

A small command line filter for structured log streams. Reads JSON lines on stdin, writes what matches on stdout. That is the whole idea.

build passing v0.9.3 linux · macos ~2.1 MB static

Installing

Prebuilt binaries are published for Linux and macOS on amd64 and arm64. Drop the binary anywhere on your PATH:

# pick the build for your platform
curl -sSL https://docs.auragg.space/dl/sift-linux-amd64 -o /usr/local/bin/sift
chmod +x /usr/local/bin/sift
sift --version

There is no installer, no daemon and no config file. If you want it gone, delete the binary.

Quick start

The common case is narrowing a noisy log down to one field:

tail -f app.log | sift '.level == "error"'
tail -f app.log | sift '.status >= 500' --pick path,status,dur_ms

Expressions are evaluated once per line. A line that fails to parse is passed through untouched unless --strict is given, which is usually what you want when piping into something else.

Streaming

Never buffers the whole input. Works on files that do not fit in memory.

No dependencies

Single static binary. Nothing to install on the machine you are debugging.

Predictable

Same expression language everywhere, no shell quoting surprises.

Options

FlagDefaultMeaning
--pickComma separated fields to keep in the output.
--strictoffDrop lines that are not valid JSON instead of passing them through.
--sinceSkip records older than a duration, e.g. 15m, 2h.
--countoffPrint only the number of matches.
--ndjsononEmit newline-delimited JSON. Disable for a single array.

Performance

On a single core sift handles roughly 400k lines per second on records around 300 bytes. Parsing is the bottleneck, so --pick does not make things meaningfully faster — it only reduces what you have to read afterwards.

$ wc -l big.log
 12400000 big.log
$ time sift '.status >= 500' < big.log | wc -l
    31204
real    0m29.8s

sift 2026 · docs@docs.auragg.space · Released under the MIT licence.