v2.17.0: Structured Logs and Readiness Timeouts
This release brings structured log parsing, filtering, and colorized highlighting to pitchfork logs, adds opt-in timeouts for every readiness check type, extends Tera templates to the remaining ready-check fields, and lets you drop the start subcommand for a quick shorthand.
Highlights
- Structured logs land in
pitchfork logs— auto-detected JSON/logfmt parsing, hl-style colorized rendering, and rich filtering by level, field, orjqexpression (#584, #592, #595) — @gaojunran. - Readiness checks get overall timeouts and full template support so slow or hung startups fail cleanly and check fields can reference other daemons' resolved ports (#597, #600).
Added
-
Structured log parsing and filtering (#584) — @gaojunran. pitchfork now understands structured daemon output. A new
logs.log_formatsetting (auto/json/logfmt/text, with per-daemon overrides inpitchfork.toml) controls parsing, andpitchfork logsgains structured filters:pitchfork logs api --level warn # minimum severity: warn and error pitchfork logs api --field status=500 # repeatable KEY=VALUE field match pitchfork logs api --jq '.duration_ms > 100' # jq expression over parsed fields
JSON output (
--json) now includes parsedlevel,msg,logger, andfields. -
hl-style structured log highlighting (#592, #595) — @gaojunran. Structured entries render with color-coded level badges, dim logger names, and
key=valuefields (keys in blue, numbers in green, booleans andnullcolored) instead of raw JSON. A configurablelogs.timestamp_formatsetting (chrono strftime, default%m-%d %H:%M:%S, also settable viaPITCHFORK_LOG_TIMESTAMP_FORMAT) controls the text-mode timestamp.--rawoutput is now honored even when combined with--jq, andpitchfork logs(no daemon named) always shows the daemon id label so you can tell lines apart. PTY control sequences are stripped from all log output to prevent pager corruption forpty = truedaemons. -
Optional overall timeout for readiness checks (#597, closes #545) — @gaojunran. All four check types accept an optional
timeoutin their object form, usinghumantimedurations. Omitting it preserves the current unbounded polling. When every configured check exhausts its deadline, the daemon is killed and startup fails with exit code124, so retry, hooks, anddependspropagate as usual.[daemons.api] run = "node server.js" ready_http = { url = "HOST/health", status = [200], timeout = "30s" } [daemons.cache] run = "redis-server" ready_port = { port = 6379, timeout = "10s" }
-
Tera templates in the remaining ready-check fields (#600) — @disintegrator.
ready_http,ready_port, andready_outputnow render through the template pipeline, joiningready_cmd, so readiness checks can reference other daemons' resolved values:[daemons.worker] ready_http = "HOST:{{ daemons.redis.port }}/health" ready_port = "{{ daemons.redis.port }}" ready_output = "listening on {{ daemons.redis.port }}" depends = ["redis"]
ready_portaccepts a plain integer or a string/template that must resolve to a valid port (1-65535); a template that renders to an invalid port now fails the start with a clear error. -
Implicit
startshorthand (#593) — @gaojunran. When the first argument isn't a known subcommand, it's treated as a daemon id and forwarded tostart, sopitchfork apiis shorthand forpitchfork start api. Allstartflags, validation, and help output are reused.pitchfork api # same as: pitchfork start api pitchfork api redis --force
Fixed
- Global config no longer requires a
daemonsfield (#605) — @senekor. Settings-only global config files (with no daemons) now validate and load correctly, defaultingdaemonsto an empty set instead of failing.
Breaking Changes
ready_port = 0now fails config parsing at load time, whereas it was previously accepted and produced a TCP check against port 0 (#600). Numeric strings such asready_port = "8080"are now accepted and normalized.
New Contributors
- @disintegrator made their first contribution in #600
- @senekor made their first contribution in #605
Full Changelog: v2.16.0...v2.17.0
💚 Sponsor pitchfork
pitchfork is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, hk, and more. Development is sustained by sponsorships.
If pitchfork has a place in your dev workflow, please consider sponsoring at jdx.dev. Individual and company sponsorships are what keep the project healthy and moving forward.