Pretty-Printing JSON in CI Logs — Readability Without Leaks
CI pipelines that dump raw JSON logs are unreadable; pretty-printing everything risks leaking secrets. Safe formatting practices for build logs and debug output.
A failed deploy printed 4,000 lines of minified JSON — one line, no breaks. The engineer missed "error": "invalid_client" buried at column 9,000. Next pipeline added jq '.' everywhere. The following week, a public GitHub Actions log showed a full OAuth token in a pretty-printed response body.
Readable logs help until they become readable leaks.
Why CI JSON is painful
Build systems capture:
- API health check responses
- Terraform plan JSON
- Test report aggregates
- npm audit output
- Deployment webhook payloads
Tools emit compact JSON by default. Humans scrolling GitHub Actions or GitLab CI need indentation — but pipelines also run in shared, sometimes public environments.
Pretty-print mechanics
jq (shell pipelines)
curl -s https://api.example.com/status | jq '.'
Select fields instead of full dump:
jq '{status: .status, version: .version}'
Node / JavaScript
console.log(JSON.stringify(payload, null, 2));
Use the JSON Formatter locally to prototype output shape before wiring CI — pair with JSON Validator on fixtures.
Python
import json
print(json.dumps(data, indent=2, sort_keys=True))
For formatting philosophy and common mistakes, see JSON Formatting Guide and Common JSON Formatting Errors.
Safe pretty-print rules
1. Redact before indent
Maintain a denylist of keys:
authorization, token, api_key, password, secret, cookie
Replace values with [REDACTED] recursively. Tools like jq support walking with filters; custom scripts should handle nested objects.
2. Truncate large arrays
Log items[0:3] and "... 47 more" instead of full inventory dumps. Size caps prevent log platform rate limits too.
3. Pretty-print artifacts, not streams
Write full formatted JSON to CI artifacts (downloadable, access-controlled). Keep console to summary lines:
Test report: 142 passed, 3 failed — see artifacts/report.json
4. Separate public vs private workflows
Fork PRs on public repos run with restricted secrets. Don't pretty-print env files in PR logs — even redaction can miss novel key names.
5. Fail on parse errors
jq empty < response.json || exit 1
Invalid JSON in a "success" step hides integration breakage.
JSON vs JSONL in pipelines
| Format | CI console | Log aggregator | | --- | --- | --- | | Pretty JSON | Human debugging | Poor per-line search | | Compact JSON | One line OK | Better for grep | | JSONL | One event per line | Ideal for Datadog/Splunk |
For streaming build events, JSONL wins. For one-shot API failure inspection, pretty JSON wins — redacted.
Read JSON vs JSONL when choosing export formats for test output.
Structured logging without full dumps
Instead of printing entire webhook bodies:
{
"event": "deploy_failed",
"status": 422,
"error_code": "INVALID_IMAGE",
"request_id": "req_abc123"
}
One line, grep-friendly, no secrets. Save full body to artifact if engineers need depth.
Local vs CI parity
Developers pretty-print locally with browser tools and formatters. CI should use the same jq filters checked into repo (scripts/format-healthcheck.sh) so "works on my machine" matches pipeline output.
Troubleshooting
Should I pretty-print all JSON in CI logs? Not unconditionally. Pretty-printing large API responses or config dumps bloats logs, slows pipelines, and may print secrets. Pretty-print small debug artifacts; summarize or redact large payloads.
How do I pretty-print JSON in a shell script? Pipe to jq with '.' for formatting: cat response.json | jq '.'. In Node, JSON.stringify(obj, null, 2). Ensure jq failures don't mask the original error.
Can CI logs expose API keys in JSON? Yes. Environment variables, OAuth responses, and error bodies often contain tokens. Redact known key names (authorization, api_key, password) before logging. Never echo full process.env in public CI.
Limitations
When not to use this approach
Conclusion
Pretty-print JSON in CI to read failures faster — not to dump entire authenticated responses to shared logs.
Redact, truncate, artifact the rest. Validate JSON before formatting. When the token would have appeared on line 47 of a indented block, you'll be glad you masked it on line 1.
GitHub Actions vs GitLab CI patterns
GitHub Actions public repos: assume logs are world-readable. Use ::add-mask:: for secrets and never echo ${{ secrets.* }} in debug steps. GitLab CI job artifacts for JSON reports with expire_in: 7 days and restricted visibility.
Fork PR workflows should not receive production secrets — mock API responses in CI fixtures instead of live authenticated calls that would pretty-print real tokens.
jq recipes for CI
Extract error code only:
jq -r '.error.code // "UNKNOWN"' response.json
Validate array length before full print:
count=$(jq '.items | length' data.json)
if [ "$count" -gt 50 ]; then jq '.items[:10]' data.json; else jq '.' data.json; fi
On-call handoff
When paging engineers at 3 AM, attach redacted pretty JSON artifact — not raw Slack paste of 8k lines. Train on-call to use artifact download links in incident tickets.
Frequently Asked Questions
Common questions answered to help you get the most from this tool.
Vertex Solutions Editorial Team
Guides and articles are produced under this collective byline — not attributed to invented individual experts. We research tool workflows, check steps against live tools where practical, and avoid fabricated personal stories, client anecdotes, or invented test results.
- Content research — Topics come from real tool workflows, common questions, and gaps in existing guides.
- Technical review — Steps, tool behavior, and examples are checked against the live tools on this site before publication when practical.
- Fact checking — Claims about formats, browser behavior, and calculator outputs are verified against documentation and tested sample inputs where practical.
- Updates — Pages may be revised when tools, official guidance, or browser behavior changes. There is no fixed review calendar for every URL.
- Corrections — Report factual errors via Contact.
Full policy: Editorial Standards. Tool checks: How we verify tools.