Skip to content

feat: add /logs skill for querying Cloud Run logs across all apps#223

Merged
taterhead247 merged 9 commits into
devfrom
feat/auth-logs-skill
Apr 9, 2026
Merged

feat: add /logs skill for querying Cloud Run logs across all apps#223
taterhead247 merged 9 commits into
devfrom
feat/auth-logs-skill

Conversation

@pstaylor-patrick

@pstaylor-patrick pstaylor-patrick commented Apr 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a monorepo-wide /logs Claude Code skill at .claude/skills/logs/ for querying Cloud Run logs across all apps (auth, api, map)
  • Config-driven via apps.conf — register a new app by adding two lines (staging + prod)
  • Deterministic bash scripts (fetch-logs.sh, format-logs.sh) for predictable gcloud log queries and markdown table output
  • Supports flexible, order-independent argument parsing: app name, environment (staging/prod), severity filters (errors/warnings), time ranges, entry count limits, and custom gcloud filters
  • Defaults to auth on staging when no app is specified, preserving backward compatibility
  • Escapes pipe characters in log output to prevent markdown table breakage
  • Accepts all gcloud duration suffixes (s, m, h, d, w) in freshness regex
  • Dependency guards for gcloud and jq CLIs with helpful install links
  • Rich prompt template with categorized examples (basic, app-specific, volume/time, advanced filters) and a tested configurations matrix
  • Fix: promotes argument-hint to top-level YAML frontmatter so Claude Code renders placeholder text when invoking /logs

Originally migrated from F3-Nation/f3-nation-auth#47, then broadened to support the full monorepo.

App Registry

App Staging Project Prod Project Region
auth f3-authentication-staging f3-authentication us-east1
api f3-api-472214 f3-api-472214 us-central1
map pin-mastery pin-mastery us-central1

Usage

/logs                          → 20 most recent auth staging entries
/logs api                      → 20 most recent api staging entries
/logs map prod                 → 20 most recent map prod entries
/logs auth prod errors 1h      → auth prod errors from the last hour
/logs api errors 50 30m        → 50 api staging errors from the last 30 minutes
/logs map httpRequest.status>=500 → map staging 5xx errors

Test plan

  • Build passes
  • Lint clean
  • Types check
  • .claude/skills/logs/SKILL.md exists with valid YAML frontmatter
  • .claude/skills/logs/apps.conf contains entries for auth, api, and map
  • scripts/fetch-logs.sh exists and is executable
  • scripts/format-logs.sh exists and is executable
  • Freshness regex accepts all gcloud duration suffixes (s, m, h, d, w)
  • fetch-logs.sh defaults to auth when no app arg is given
  • fetch-logs.sh resolves api to the correct GCP project and service name
  • fetch-logs.sh resolves map to the correct GCP project and service name
  • SKILL.md includes categorized examples (basic, app-specific, volume/time, advanced)
  • SKILL.md includes tested configurations table for all apps
  • argument-hint is a top-level frontmatter field (not nested under metadata)
  • Run /logs from the monorepo — should show 20 recent auth staging log entries
  • Run /logs api prod — should query the f3-api-472214 project
  • Run /logs map errors — should filter to ERROR severity for the map app

🤖 Generated with Claude Code

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>
@pstaylor-patrick

Copy link
Copy Markdown
Collaborator Author

Code Review — /logs skill (PR #223)

# 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

@pstaylor-patrick

Copy link
Copy Markdown
Collaborator Author

QA Validation Results — PR #223 (feat/auth-logs-skill)

Check Result Notes
Build ⚠️ SKIP 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>
@pstaylor-patrick

Copy link
Copy Markdown
Collaborator Author

Second-round code review: LGTM

Verified both fixes from round 1:

No new issues found. Scripts are well-structured — set -euo pipefail, exec for the gcloud call, proper jq fallbacks with //, and sensible defaults throughout.

One minor observation (not blocking): the freshness regex ^[0-9]+[mhd]$ won't match w (weeks) or s (seconds), which gcloud supports. Not worth changing for this use case.

pstaylor-patrick and others added 2 commits April 8, 2026 15:29
… 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>
@pstaylor-patrick pstaylor-patrick changed the title feat: add /logs Claude Code skill for auth app feat: add /logs skill for querying Cloud Run logs across all apps Apr 8, 2026
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 pstaylor-patrick left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Comment thread .claude/skills/logs/scripts/format-logs.sh
pstaylor-patrick and others added 3 commits April 8, 2026 15:46
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 pstaylor-patrick marked this pull request as ready for review April 8, 2026 21:52
@taterhead247

Copy link
Copy Markdown
Contributor

@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 taterhead247 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only adds claude skill files for pulling logs. Low risk

@taterhead247 taterhead247 merged commit d5a1ff4 into dev Apr 9, 2026
6 checks passed
@taterhead247 taterhead247 deleted the feat/auth-logs-skill branch April 9, 2026 02:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Merged

Development

Successfully merging this pull request may close these issues.

2 participants