log-analysis · v2.1 · 2026-06-16 · sha256 bbfcf252c673c3c7
log-analysis v2.1A
Immutable. This exact content is served forever at /api/v1/blob/bbfcf252c673c3c7.
--- name: log-analysis description: > Route runtime-log requests into one evidence packet before diagnosing anything. Use when the user shares app/server/container/browser/CI/JSON log output and wants the first actionable blocker, repeated signature, likely blast radius, or safest next read-only checks. Choose one packet: app-runtime, container-runtime, browser-plus-api, ci-cascade, structured-json, or security-signal. Triggers on: check the logs, which line matters, real error, first blocker, noisy stack trace, retry storm, browser 401/500, pod logs, worker crash, CI abort, webhook failure. Route engine-specific Unity/Unreal logs to `game-build-log-triage`, observability design to `monitoring-observability`, and remediation/debug hypotheses to `debugging`. allowed-tools: Bash Read Grep Glob compatibility: > Best for repositories, incidents, or pasted excerpts where the main task is read-only log triage rather than observability platform setup or code changes. metadata: tags: logs, triage, debugging, observability, incidents, ci, browser, grep version: "2.1" source: akillness/jeo-skills --- # 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. 1. Normalize the request into **one primary log packet**. 2. Narrow the evidence slice before interpreting it. 3. Isolate the **earliest actionable failure**. 4. Group repeated fallout into a **pattern / blast radius** note. 5. 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/intake-packets-and-route-outs.md) - [references/triage-playbook.md](references/triage-playbook.md) - [references/source-boundaries.md](references/source-boundaries.md) ## Instructions ### Step 1: Normalize the request Convert the prompt into this intake shape first: ```yaml 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: 1. **Hard stop** — crash, panic, uncaught exception, process exit, build failure 2. **Dependency / environment blocker** — missing config, secret, DNS, file, service, auth, or connection 3. **Request / runtime failure** — `500`, timeout, rejected promise, queue poison message, parser failure 4. **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: ```markdown # 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: 1. mark confidence low 2. ask for the earliest error cluster or 20-80 lines around the first blocker 3. ask for one anchor only if needed: time window, request ID, job/build, pod/container, or browser route 4. 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 1. Choose the **smallest packet** that can answer the question. 2. Lead with the **earliest blocker**, not the loudest line. 3. Group repeated fallout into one signature or blast-radius summary. 4. Correlate browser/network/app evidence instead of summarizing each source independently. 5. Keep all suggested checks **read-only** inside this skill. 6. Treat engine-specific logs as a hard specialist boundary. 7. 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`