Log Analysis
When to use this skill
- The main job is read-only log triage, not code changes or monitoring design.
- The user wants the first actionable blocker, not a paraphrase of every line.
- The evidence is application, API, worker, proxy, container, pod, browser, CI, or JSON logs.
- The user needs the repeated signature or blast radius summarized after the first failure is isolated.
- The prompt is really "which lines matter / what is the real error / where does the cascade start?" even if the user never says "triage".
Do not use this skill as the main workflow when:
- The logs are Unity / Unreal build, cook, package, editor, or player logs → use
game-build-log-triage.
- The real job is instrumentation, dashboards, alerting, ingestion, retention, or observability coverage → use
monitoring-observability.
- The likely blocker is already known and the user now needs reproduction, hypotheses, or fixes → use
debugging.
- The main job is repeated anomaly/rule hunting across logs or telemetry families rather than first-failure triage → use
pattern-detection.
Core idea
log-analysis should act like a packet router, not a giant troubleshooting encyclopedia.
- Normalize the request into one primary log packet.
- Narrow the evidence slice before interpreting it.
- Isolate the earliest actionable failure.
- Group repeated fallout into a pattern / blast radius note.
- Route out as soon as the work becomes debugging, observability design, anomaly hunting, or engine-specialist triage.
Read these support docs before choosing the packet:
- references/intake-packets-and-route-outs.md
- references/triage-playbook.md
- references/source-boundaries.md
Instructions
Step 1: Normalize the request
Convert the prompt into this intake shape first:
log_analysis_packet:
primary_packet: app-runtime | container-runtime | browser-plus-api | ci-cascade | structured-json | security-signal
source_shape: app | proxy | worker | browser | ci | container | pod | json | mixed | unknown
environment: local | ci | staging | production | browser | container | pod | unknown
failure_goal: first-blocker | cascade-start | repeated-signature | blast-radius | suspicious-access | unknown
anchor: timestamp | request-id | trace-id | job-build-id | browser-route | none | unknown
route_after: stay-here | debugging | monitoring-observability | pattern-detection | game-build-log-triage
Choose one primary packet for the run. If two seem plausible, pick the cheaper packet that reduces uncertainty fastest.
Step 2: Choose the packet
| Packet |
Use when |
Best fits |
Typical anchors |
app-runtime |
The key evidence is app/API/worker/proxy text logs |
crashes, stack traces, request failures, queue poison messages |
earliest fatal/error line, route, service, request ID |
container-runtime |
The evidence comes from docker logs, kubectl logs, pod output, or deploy-window restarts |
container crashes, env/config mismatch, dependency connectivity, restart loops |
pod/container name, deploy window, host, request ID |
browser-plus-api |
Browser console/network symptoms need server-side confirmation |
401/403/500 flows, failed fetch, CORS/auth mismatch, SSR/client divergence |
route, request ID, timestamp, browser/network trace |
ci-cascade |
CI output contains many secondary failures after one blocker |
install/import/test/build cascades, missing dependency/config, runner mismatch |
job name, step name, stage, earliest stack trace/import error |
structured-json |
The logs are JSON or field-rich event records |
grouped error families, request/trace correlation, worker/event triage |
level, service, request ID, trace ID, tenant, event name |
security-signal |
Access/error logs suggest suspicious probing or auth/permission anomalies |
repeated 401/403/404 probes, token misuse, rate-limit storms |
IP/user/session, route family, status code, time window |
Packet rules:
- Prefer
app-runtime for plain text stack traces and server logs.
- Prefer
container-runtime when restart timing, pod identity, or env/deploy context matters.
- Prefer
browser-plus-api when frontend symptoms are not sufficient on their own.
- Prefer
ci-cascade when the visible failure may be generic abort noise.
- Prefer
structured-json when fields make grouping and correlation cheaper than free-text scanning.
- Prefer
security-signal only when suspicious access/auth behavior is the main job; otherwise keep security-looking noise inside the packet that owns the first blocker.
Step 3: Narrow the slice before reading everything
Apply at least one narrowing move before interpreting the logs:
- limit by time window
- limit by request / trace / job / build / session / tenant identifier
- separate fatal/actionable lines from retries and fallout
- separate one noisy source from many affected sources
- separate browser symptom lines from server-side blocker lines
- in CI, locate the earliest failing step before summarizing the full transcript
Useful heuristics by packet:
- app-runtime → exception / fatal / failed / timeout / refusal first
- container-runtime → restart window + dependency/connectivity/env mismatch first
- browser-plus-api → backend auth/config/runtime evidence before generic client symptoms
- ci-cascade → earliest import/config/build/test failure before abort/footer lines
- structured-json → group by message family, exception class, request ID, or service before reading raw rows
- security-signal → distinguish broad probing from one broken client before escalating
Step 4: Isolate the first actionable failure
Use this order:
- Hard stop — crash, panic, uncaught exception, process exit, build failure
- Dependency / environment blocker — missing config, secret, DNS, file, service, auth, or connection
- Request / runtime failure —
500, timeout, rejected promise, queue poison message, parser failure
- Fallout — retries, secondary warnings, repeated health-check failures, broad abort text
Do not report 20 repeated downstream lines as 20 different causes.
Step 5: Correlate and classify
If the evidence spans more than one source, correlate instead of concatenating.
Primary classification buckets:
missing-config-or-secret
dependency-or-connection
auth-or-permission
request-or-runtime-error
data-shape-or-validation
resource-or-capacity
browser-network-mismatch
ci-build-test-failure
security-or-suspicious-pattern
unknown-needs-more-context
Correlation anchors to prefer:
- timestamp window
- request / trace / correlation ID
- job/build ID or CI step
- service / worker / pod / container name
- route, browser action, or API endpoint
- user / tenant / session identifier when safe to mention
Step 6: Return a triage brief
Default response shape:
# Log Triage
## Source
- Packet: app-runtime | container-runtime | browser-plus-api | ci-cascade | structured-json | security-signal
- Environment: local | CI | staging | production | browser | container | pod
- Confidence: high | medium | low
## First actionable failure
- Line or excerpt: `...`
- Why it matters: ...
- Why later lines look secondary: ...
## Pattern / blast radius
- Repeated signature: ...
- Scope: one request | repeated requests | one worker | one deploy window | one environment | broad
## Classification
- Primary bucket: ...
- Secondary bucket: ...
## Likely root cause
- 1-3 sentence explanation grounded in the evidence
## Next read-only checks
1. ...
2. ...
3. ...
## Route-out
- stay in `log-analysis` | `debugging` | `monitoring-observability` | `pattern-detection` | `game-build-log-triage`
Step 7: Route out aggressively
Switch when the next job is no longer first-failure log triage:
- Reproduction, hypotheses, code/config fixes →
debugging
- Dashboards, alerts, ingestion, telemetry coverage, retention →
monitoring-observability
- Repeated signature hunting across many windows or datasets →
pattern-detection
- Unity / Unreal build/editor/package logs →
game-build-log-triage
If the excerpt is too short or starts mid-cascade:
- mark confidence low
- ask for the earliest error cluster or 20-80 lines around the first blocker
- ask for one anchor only if needed: time window, request ID, job/build, pod/container, or browser route
- do not pretend certainty from a truncated excerpt
Examples
Example 1: Container dependency failure
Prompt:
kubectl logs shows Error: connect ECONNREFUSED redis:6379 and then dozens of job retry failed lines.
Good response shape:
- choose
container-runtime
- identify the Redis connection failure as the first actionable blocker
- group later retry lines as fallout
- route next to
debugging or monitoring-observability only after the blocker is isolated
Example 2: Browser + API mismatch
Prompt:
Browser console says Failed to fetch, the network tab shows 401 on /api/session, and the server log says JWT audience invalid.
Good response shape:
- choose
browser-plus-api
- identify backend auth validation as the actionable blocker
- treat browser failure as a symptom, not the cause
- route next to
debugging once the config/code suspect is clear
Example 3: CI cascade
Prompt:
CI ends with test suite aborted, but earlier there is ModuleNotFoundError: No module named 'dotenv'.
Good response shape:
- choose
ci-cascade
- isolate the earliest import failure
- treat the abort/footer text as fallout
- route next to
debugging after the failing dependency path is known
Example 4: Automation/webhook JSON logs
Prompt:
These JSON webhook logs show repeated status=429 retries after one invalid API key response. What actually matters?
Good response shape:
- choose
structured-json or security-signal depending on whether auth abuse or one bad credential is the primary job
- isolate the first credential/auth failure
- summarize retry volume separately
- route repeated pattern hunting to
pattern-detection only if the user wants broader anomaly work
Best practices
- Choose the smallest packet that can answer the question.
- Lead with the earliest blocker, not the loudest line.
- Group repeated fallout into one signature or blast-radius summary.
- Correlate browser/network/app evidence instead of summarizing each source independently.
- Keep all suggested checks read-only inside this skill.
- Treat engine-specific logs as a hard specialist boundary.
- Route out as soon as the work becomes debugging, observability design, or anomaly hunting.
References
references/intake-packets-and-route-outs.md
references/triage-playbook.md
references/source-boundaries.md
1---2name: log-analysis3description: Routes runtime-log requests into an evidence packet to isolate the first actionable blocker, repeated signature, blast radius, or safest next read-only check.4---56# Log Analysis78## When to use this skill9- The main job is **read-only log triage**, not code changes or monitoring design.10- The user wants the **first actionable blocker**, not a paraphrase of every line.11- The evidence is **application, API, worker, proxy, container, pod, browser, CI, or JSON logs**.12- The user needs the **repeated signature or blast radius** summarized after the first failure is isolated.13- The prompt is really **"which lines matter / what is the real error / where does the cascade start?"** even if the user never says "triage".1415Do **not** use this skill as the main workflow when:16- The logs are **Unity / Unreal build, cook, package, editor, or player logs** → use `game-build-log-triage`.17- The real job is **instrumentation, dashboards, alerting, ingestion, retention, or observability coverage** → use `monitoring-observability`.18- The likely blocker is already known and the user now needs **reproduction, hypotheses, or fixes** → use `debugging`.19- The main job is **repeated anomaly/rule hunting across logs or telemetry families** rather than first-failure triage → use `pattern-detection`.2021## Core idea22`log-analysis` should act like a **packet router**, not a giant troubleshooting encyclopedia.23241. Normalize the request into **one primary log packet**.252. Narrow the evidence slice before interpreting it.263. Isolate the **earliest actionable failure**.274. Group repeated fallout into a **pattern / blast radius** note.285. Route out as soon as the work becomes debugging, observability design, anomaly hunting, or engine-specialist triage.2930Read these support docs before choosing the packet:31- [references/intake-packets-and-route-outs.md](references/intake-packets-and-route-outs.md)32- [references/triage-playbook.md](references/triage-playbook.md)33- [references/source-boundaries.md](references/source-boundaries.md)3435## Instructions3637### Step 1: Normalize the request38Convert the prompt into this intake shape first:3940```yaml41log_analysis_packet:42 primary_packet: app-runtime | container-runtime | browser-plus-api | ci-cascade | structured-json | security-signal43 source_shape: app | proxy | worker | browser | ci | container | pod | json | mixed | unknown44 environment: local | ci | staging | production | browser | container | pod | unknown45 failure_goal: first-blocker | cascade-start | repeated-signature | blast-radius | suspicious-access | unknown46 anchor: timestamp | request-id | trace-id | job-build-id | browser-route | none | unknown47 route_after: stay-here | debugging | monitoring-observability | pattern-detection | game-build-log-triage48```4950Choose **one** primary packet for the run. If two seem plausible, pick the cheaper packet that reduces uncertainty fastest.5152### Step 2: Choose the packet5354| Packet | Use when | Best fits | Typical anchors |55|---|---|---|---|56| `app-runtime` | The key evidence is app/API/worker/proxy text logs | crashes, stack traces, request failures, queue poison messages | earliest fatal/error line, route, service, request ID |57| `container-runtime` | The evidence comes from `docker logs`, `kubectl logs`, pod output, or deploy-window restarts | container crashes, env/config mismatch, dependency connectivity, restart loops | pod/container name, deploy window, host, request ID |58| `browser-plus-api` | Browser console/network symptoms need server-side confirmation | 401/403/500 flows, failed fetch, CORS/auth mismatch, SSR/client divergence | route, request ID, timestamp, browser/network trace |59| `ci-cascade` | CI output contains many secondary failures after one blocker | install/import/test/build cascades, missing dependency/config, runner mismatch | job name, step name, stage, earliest stack trace/import error |60| `structured-json` | The logs are JSON or field-rich event records | grouped error families, request/trace correlation, worker/event triage | level, service, request ID, trace ID, tenant, event name |61| `security-signal` | Access/error logs suggest suspicious probing or auth/permission anomalies | repeated 401/403/404 probes, token misuse, rate-limit storms | IP/user/session, route family, status code, time window |6263Packet rules:64- Prefer `app-runtime` for plain text stack traces and server logs.65- Prefer `container-runtime` when restart timing, pod identity, or env/deploy context matters.66- Prefer `browser-plus-api` when frontend symptoms are not sufficient on their own.67- Prefer `ci-cascade` when the visible failure may be generic abort noise.68- Prefer `structured-json` when fields make grouping and correlation cheaper than free-text scanning.69- Prefer `security-signal` only when suspicious access/auth behavior is the main job; otherwise keep security-looking noise inside the packet that owns the first blocker.7071### Step 3: Narrow the slice before reading everything72Apply at least one narrowing move before interpreting the logs:73- limit by time window74- limit by request / trace / job / build / session / tenant identifier75- separate fatal/actionable lines from retries and fallout76- separate one noisy source from many affected sources77- separate browser symptom lines from server-side blocker lines78- in CI, locate the earliest failing step before summarizing the full transcript7980Useful heuristics by packet:81- **app-runtime** → exception / fatal / failed / timeout / refusal first82- **container-runtime** → restart window + dependency/connectivity/env mismatch first83- **browser-plus-api** → backend auth/config/runtime evidence before generic client symptoms84- **ci-cascade** → earliest import/config/build/test failure before abort/footer lines85- **structured-json** → group by message family, exception class, request ID, or service before reading raw rows86- **security-signal** → distinguish broad probing from one broken client before escalating8788### Step 4: Isolate the first actionable failure89Use this order:901. **Hard stop** — crash, panic, uncaught exception, process exit, build failure912. **Dependency / environment blocker** — missing config, secret, DNS, file, service, auth, or connection923. **Request / runtime failure** — `500`, timeout, rejected promise, queue poison message, parser failure934. **Fallout** — retries, secondary warnings, repeated health-check failures, broad abort text9495Do **not** report 20 repeated downstream lines as 20 different causes.9697### Step 5: Correlate and classify98If the evidence spans more than one source, correlate instead of concatenating.99100Primary classification buckets:101- `missing-config-or-secret`102- `dependency-or-connection`103- `auth-or-permission`104- `request-or-runtime-error`105- `data-shape-or-validation`106- `resource-or-capacity`107- `browser-network-mismatch`108- `ci-build-test-failure`109- `security-or-suspicious-pattern`110- `unknown-needs-more-context`111112Correlation anchors to prefer:113- timestamp window114- request / trace / correlation ID115- job/build ID or CI step116- service / worker / pod / container name117- route, browser action, or API endpoint118- user / tenant / session identifier when safe to mention119120### Step 6: Return a triage brief121Default response shape:122123```markdown124# Log Triage125126## Source127- Packet: app-runtime | container-runtime | browser-plus-api | ci-cascade | structured-json | security-signal128- Environment: local | CI | staging | production | browser | container | pod129- Confidence: high | medium | low130131## First actionable failure132- Line or excerpt: `...`133- Why it matters: ...134- Why later lines look secondary: ...135136## Pattern / blast radius137- Repeated signature: ...138- Scope: one request | repeated requests | one worker | one deploy window | one environment | broad139140## Classification141- Primary bucket: ...142- Secondary bucket: ...143144## Likely root cause145- 1-3 sentence explanation grounded in the evidence146147## Next read-only checks1481. ...1492. ...1503. ...151152## Route-out153- stay in `log-analysis` | `debugging` | `monitoring-observability` | `pattern-detection` | `game-build-log-triage`154```155156### Step 7: Route out aggressively157Switch when the next job is no longer first-failure log triage:158- **Reproduction, hypotheses, code/config fixes** → `debugging`159- **Dashboards, alerts, ingestion, telemetry coverage, retention** → `monitoring-observability`160- **Repeated signature hunting across many windows or datasets** → `pattern-detection`161- **Unity / Unreal build/editor/package logs** → `game-build-log-triage`162163If the excerpt is too short or starts mid-cascade:1641. mark confidence low1652. ask for the earliest error cluster or 20-80 lines around the first blocker1663. ask for one anchor only if needed: time window, request ID, job/build, pod/container, or browser route1674. do not pretend certainty from a truncated excerpt168169## Examples170171### Example 1: Container dependency failure172**Prompt:**173> `kubectl logs` shows `Error: connect ECONNREFUSED redis:6379` and then dozens of `job retry failed` lines.174175**Good response shape:**176- choose `container-runtime`177- identify the Redis connection failure as the first actionable blocker178- group later retry lines as fallout179- route next to `debugging` or `monitoring-observability` only after the blocker is isolated180181### Example 2: Browser + API mismatch182**Prompt:**183> Browser console says `Failed to fetch`, the network tab shows 401 on `/api/session`, and the server log says `JWT audience invalid`.184185**Good response shape:**186- choose `browser-plus-api`187- identify backend auth validation as the actionable blocker188- treat browser failure as a symptom, not the cause189- route next to `debugging` once the config/code suspect is clear190191### Example 3: CI cascade192**Prompt:**193> CI ends with `test suite aborted`, but earlier there is `ModuleNotFoundError: No module named 'dotenv'`.194195**Good response shape:**196- choose `ci-cascade`197- isolate the earliest import failure198- treat the abort/footer text as fallout199- route next to `debugging` after the failing dependency path is known200201### Example 4: Automation/webhook JSON logs202**Prompt:**203> These JSON webhook logs show repeated `status=429` retries after one `invalid API key` response. What actually matters?204205**Good response shape:**206- choose `structured-json` or `security-signal` depending on whether auth abuse or one bad credential is the primary job207- isolate the first credential/auth failure208- summarize retry volume separately209- route repeated pattern hunting to `pattern-detection` only if the user wants broader anomaly work210211## Best practices2121. Choose the **smallest packet** that can answer the question.2132. Lead with the **earliest blocker**, not the loudest line.2143. Group repeated fallout into one signature or blast-radius summary.2154. Correlate browser/network/app evidence instead of summarizing each source independently.2165. Keep all suggested checks **read-only** inside this skill.2176. Treat engine-specific logs as a hard specialist boundary.2187. Route out as soon as the work becomes debugging, observability design, or anomaly hunting.219220## References221- `references/intake-packets-and-route-outs.md`222- `references/triage-playbook.md`223- `references/source-boundaries.md`