feat: add /logs skill for querying Cloud Run logs across all apps#223
Conversation
Adds a skill to query Cloud Run logs for the f3-auth service with deterministic bash scripts for argument parsing and output formatting. Supports environment selection (staging/prod), severity filters, time ranges, entry limits, and custom gcloud filters. Co-Authored-By: Claude <noreply@anthropic.com>
Code Review —
|
| # | File | Line | Severity | Finding |
|---|---|---|---|---|
| 1 | format-logs.sh |
35 | 🔴 Bug | Pipe characters (|) in textPayload or jsonPayload.message will break the markdown table. Add gsub("|"; "\|") to the non-httpRequest branch of the jq expression to escape them. |
| 2 | fetch-logs.sh |
49-57 | 🟡 Suggestion | TIME_FILTER (explicit timestamp>=) and --freshness are both set for the same time range, making the filter redundant. Consider dropping TIME_FILTER and relying solely on --freshness, or vice versa — using both creates a confusing contract. |
| 3 | fetch-logs.sh |
70 | 🟡 Suggestion | ${CUSTOM_FILTERS[*]:-} works on macOS default bash (3.2) but can behave differently across bash versions under set -u. A safer pattern: ${CUSTOM_FILTERS[@]+"${CUSTOM_FILTERS[@]}"} joined manually, or guard with if (( ${#CUSTOM_FILTERS[@]} > 0 )). |
| 4 | fetch-logs.sh |
61 | 🟡 Suggestion | Custom filters are appended verbatim into the gcloud filter string. While this is safe from shell injection (the filter is a single quoted arg to gcloud), a malformed filter like " could break the gcloud query with a confusing error. Consider validating that custom filter args don't contain unbalanced quotes. |
| 5 | SKILL.md |
31 | 🟢 Nit | The instruction shows $ARGS unquoted. Adding a note that Claude should expand user arguments as separate words (not a single quoted string) would make the contract clearer for future maintainers. |
| 6 | format-logs.sh |
11 | 🟢 Nit | INPUT=$(cat) reads the entire JSON into memory. Fine for typical log volumes (20-100 entries), but worth noting if someone passes --limit 10000. |
Overall: Clean, well-structured scripts. The only functional bug is #1 (pipe chars in log messages). The rest are hardening suggestions. LGTM with the table-escaping fix.
Reviewed by Claude Code
QA Validation Results — PR #223 (
|
| Check | Result | Notes |
|---|---|---|
| Build | f3-nation-map fails due to missing NEXT_PUBLIC_MAP_API_KEY env var — pre-existing, unrelated to this PR. Auth and API builds were in progress when map failed. |
|
| Lint | ✅ PASS | 16/16 tasks clean, no warnings or errors |
| Format | ✅ PASS | 16/16 tasks clean, all files use Prettier code style |
| Typecheck | ✅ PASS | 15/15 tasks clean (auth filter excluded per root config, but f3-auth:typecheck still ran and passed) |
File existence: SKILL.md |
✅ PASS | Exists at apps/auth/.claude/skills/logs/SKILL.md |
File existence: fetch-logs.sh |
✅ PASS | Exists at apps/auth/.claude/skills/logs/scripts/fetch-logs.sh |
File existence: format-logs.sh |
✅ PASS | Exists at apps/auth/.claude/skills/logs/scripts/format-logs.sh |
Executable bit: fetch-logs.sh |
✅ PASS | -rwxr-xr-x |
Executable bit: format-logs.sh |
✅ PASS | -rwxr-xr-x |
| YAML frontmatter | ✅ PASS | Starts with ---, has name: logs and description: ... fields |
Shell syntax: fetch-logs.sh |
✅ PASS | bash -n clean |
Shell syntax: format-logs.sh |
✅ PASS | bash -n clean |
Summary: 11/12 checks pass. Build skipped due to pre-existing env var issue in the map app (not introduced by this PR). All PR-specific validations pass — the skill files are well-formed and ready for functional testing.
- Escape | chars in textPayload/jsonPayload via jq gsub to prevent markdown table corruption - Replace redundant TIME_FILTER + --freshness with --freshness only, which is simpler and sufficient for gcloud logging read Co-Authored-By: Claude <noreply@anthropic.com>
|
Second-round code review: LGTM ✅ Verified both fixes from round 1:
No new issues found. Scripts are well-structured — One minor observation (not blocking): the freshness regex |
… regex Co-Authored-By: Claude <noreply@anthropic.com>
…pport Move from apps/auth/.claude/skills/logs/ to .claude/skills/logs/ so it works for any Cloud Run app in the monorepo (auth, api, map). App config is driven by apps.conf — add two lines to register a new app. Co-Authored-By: Claude <noreply@anthropic.com>
Address preflight code review findings:
- P1: replace unsafe ${CUSTOM_FILTERS[*]:-} with explicit loop join
- P3: check gcloud CLI is installed before exec
Co-Authored-By: Claude <noreply@anthropic.com>
pstaylor-patrick
left a comment
There was a problem hiding this comment.
Code Review — Clean (1 minor suggestion)
Preflight already addressed the blockers (P1: unsafe array expansion, P3: missing gcloud guard). The remaining accepted items (P2 colon delimiter, P4 stdin buffering, P5 pipe escaping) are reasonable tradeoffs.
New finding (1 warning):
| ID | Severity | File | Title |
|---|---|---|---|
| P1 | warning | format-logs.sh |
Missing jq dependency guard |
Branch status: Current with dev — no rebase needed.
Verdict: No blockers. One warning-level suggestion for consistency with the existing gcloud guard pattern. Ship-ready as-is.
Validated code review — 0 findings dropped. 1 finding promoted (warning).
Matches the gcloud guard pattern in fetch-logs.sh for consistency. Co-Authored-By: Claude <noreply@anthropic.com>
Add organized example sections (basic, app-specific, volume/time, advanced filters), supported time units, and a tested configurations table showing verified app+env combinations. Co-Authored-By: Claude <noreply@anthropic.com>
…nders placeholder text Co-Authored-By: Claude <noreply@anthropic.com>
|
@pstaylor-patrick does this skill cover writing code to log events in the app? I don't think so. But in case it does, one thing I noticed is that if you don't wrap the error message in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify then every single line in the message is a different log, which makes searching basically impossible. |
taterhead247
left a comment
There was a problem hiding this comment.
only adds claude skill files for pulling logs. Low risk
feat: add /logs skill for querying Cloud Run logs across all apps #223 - Watch Video
Summary
/logsClaude Code skill at.claude/skills/logs/for querying Cloud Run logs across all apps (auth, api, map)apps.conf— register a new app by adding two lines (staging + prod)fetch-logs.sh,format-logs.sh) for predictable gcloud log queries and markdown table outputstaging/prod), severity filters (errors/warnings), time ranges, entry count limits, and custom gcloud filtersauthonstagingwhen no app is specified, preserving backward compatibilitys,m,h,d,w) in freshness regexgcloudandjqCLIs with helpful install linksargument-hintto top-level YAML frontmatter so Claude Code renders placeholder text when invoking/logsApp Registry
authf3-authentication-stagingf3-authenticationus-east1apif3-api-472214f3-api-472214us-central1mappin-masterypin-masteryus-central1Usage
Test plan
.claude/skills/logs/SKILL.mdexists with valid YAML frontmatter.claude/skills/logs/apps.confcontains entries for auth, api, and mapscripts/fetch-logs.shexists and is executablescripts/format-logs.shexists and is executablefetch-logs.shdefaults toauthwhen no app arg is givenfetch-logs.shresolvesapito the correct GCP project and service namefetch-logs.shresolvesmapto the correct GCP project and service nameargument-hintis a top-level frontmatter field (not nested undermetadata)/logsfrom the monorepo — should show 20 recent auth staging log entries/logs api prod— should query thef3-api-472214project/logs map errors— should filter to ERROR severity for the map app🤖 Generated with Claude Code