performance-investigation
Use for Zava Learning incidents where the platform is reachable but a compute tier is degraded — elevated 5xx from the APIs, slow quiz responses, exceptions, an API with no healthy instances, or a back-office batch job failing on the reporting-worker VM (e.g. nightly grade exports). Diagnoses from Application Insights / Log Analytics / Syslog and remediates the application or worker tier.
- License 许可
- MIT
- 最近更新
- 2026-11-10
- Stars
- ★ 188
- Forks
- 198
01 前言 Front Matter
- name
- performance-investigation
- tools
- [ "RunAzCliReadCommands", "RunAzCliWriteCommands", "GetAzCliHelp", "SearchMemory", "ExecutePythonCode", "microsoft-learn_microsoft_docs_search", "microsoft-learn_microsoft_docs_fetch" ]
- metadata
- { "kind": "Skill", "api_version": "azuresre.ai/v2" }
- description
- Use for Zava Learning incidents where the platform is reachable but a compute tier is degraded — elevated 5xx from the APIs, slow quiz responses, exceptions, an API with no healthy instances, or a back-office batch job failing on the reporting-worker VM (e.g. nightly grade exports). Diagnoses from Application Insights / Log Analytics / Syslog and remediates the application or worker tier.
03 SKILL.md 正文
Zava Learning — Application Incident Runbook
Resource Group: @@RG@@. Services (Container Apps): learner-portal, course-api, assessment-api.
Quiz launch path: portal -> assessment-api -> course-api.
Confirm the network/edge is healthy first (App Gateway backend healthy, NSG clean) so you don't misattribute an app fault. Then:
- Query App Insights failures/exceptions filtered by the failing
cloud_RoleName. - Check Container App revision health and replica counts — an API with zero replicas serves no
requests and surfaces as quiz launch / 502 failures with a clean network path. A revision can hit
zero replicas two ways: scaled to zero, OR the active revision was deactivated (an inactive
revision runs zero replicas).
az containerapp revision listshows only ACTIVE revisions, so a deactivated lane looks like it has "no revisions" — list with--alland inspectproperties.active/properties.latestRevisionName. The latent cause is often a scale floor of zero in IaC (appLaneMinReplicas: 0); the durable fix restores a non-zero minimum. - Inspect recent revisions/config changes.
- For LATENCY regressions (slow quiz responses / the latency alert) on a clean network path: pull assessment-api request durations from Log Analytics console logs (each request logs
ms=<duration>), find the step-change in latency and align it to the most recent assessment-api revision/image deployment, then inspectsrc/assessment-api/server.jsfor expensive synchronous work added on the request path (e.g. a synchronous KDF/crypto call). This is a code regression — mitigate live by rolling back to the prior revision, then fix durably with a code PR.
Reporting-worker grade-export failures
If the symptom is the nightly grade-export job failing (no quiz/portal impact — this is a back-office
batch job on a dedicated VM vm-zava-reporting-*):
- Query Log Analytics
SyslogforProcessName == "zava-export"— the worker logs a heartbeat on success and aFAILEDline plus the raw OS error (export write error: ...) on failure. Read the raw error to identify the failure mode. - Correlate with disk telemetry: the
Perftable carries Logical Disk% Used SpaceandFree Megabytesfor the worker. A data volume (/data) at ~100% used / near-zero free is the signal that the export writes are failing for lack of space. - Confirm on the VM with a read command (
az vm run-command invoke ... --scripts "df -h /data"). - Mitigate live: free space on the worker's data disk (remove the accumulated backlog file under
/data/exports) viaaz vm run-command. Re-check that the next export run logs a success heartbeat. - Durable fix: the worker's export retention/rotation lives in
src/reporting-worker/cloud-init.yaml— a PR that enforces retention (or grows the data disk ininfra/modules/vm.bicep) is the lasting fix.
Database-backed quiz lanes (slow loading / errors under load / auth failures)
The quiz lanes read PostgreSQL on the request path, so a DB fault produces app-shaped symptoms on a
clean edge + healthy replicas. Do NOT stop at "the DB looks slow" and report root cause unknown —
identify WHICH database surface — log-first, confirm from the lane's error detail, then optionally
verify in the database:
- Read the quiz service's console logs (
ContainerAppConsoleLogs_CLfor the failingquiz-*app /assessment-api) for the request shape: a slowms=<duration>on/quiz/*→ index/latency; a burst ofstatus=500on/quiz/*(and anypool error:lines) → a backend DB failure. - Get the EXACT backend error straight from the lane — the service returns the underlying Postgres
error in the response
detailfield (it is NOT written to the logs):curlthe lane's/health(returns503 {"status":"degraded","detail":"<pg error>"}when the DB path is broken) or/quiz/<courseId>(500 {"error":"...","detail":"<pg error>"}). Thedetailnames the cause directly — e.g.password authentication failed(28P01) → bad DB secret;too many connections/remaining connection slots/ connection-limit → pool exhaustion; a slow-but-200/quizwith climbingms=→ missing index. This needs no DB credentials and is the primary confirmation. - Optionally confirm against the database itself with a read-only query (connection recipe in the
knowledge base — server/login from
az postgres flexible-server list, admin password from Key Vaultdb-password, thenaz postgres flexible-server execute --querytext "<SQL>"):- Slow quiz loading (query lane, db
zava_query): check thequestion_bankindexes —SELECT indexname FROM pg_indexes WHERE tablename='question_bank';andSELECT relname,seq_scan,idx_scan FROM pg_stat_user_tables WHERE relname='question_bank';. A missing index onquestion_bankwith seq-scans climbing is the root cause; the durable fix is to (re)build it (REINDEX/CREATE INDEX) — delivered as a PR. - Errors under load (pool lane, db
zava): check the connecting role's connection limit —SELECT rolname,rolconnlimit FROM pg_roles WHERE rolname='app_pool';and live connections inpg_stat_activity. Arolconnlimitof 1 (or far below the pool size) is the root cause; restore a sane limit (ALTER ROLE app_pool CONNECTION LIMIT <n>). - Authentication errors (secret lane): the lane's Key Vault DB secret (
db-password-secretlane) was rotated to an invalid value — confirm the auth-failure log signature; the fix is to restore a valid value INTOdb-password-secretlane(copy it from the baselinedb-passwordsecret withaz keyvault secret set) and then force the lane to re-read it by creating a NEW revision (az containerapp update --set-env-vars FORCE_ROTATE=<timestamp>). A plainaz containerapp revision restartis NOT enough — Container Apps resolve Key Vault secret references at revision-creation time, so a restart reuses the cached (still-invalid) value; only a new revision re-reads the secret. Then re-check the lane returns 200. Do NOT runaz containerapp secret set/ re-assert the secret'sidentityref(unnecessary — the reference is already correct), and do NOT repointpg-passwordto a different Key Vault secret (e.g. the shareddb-password) — that masks the fault and breaks lane isolation; only thedb-password-secretlanevalue should change.
- Slow quiz loading (query lane, db
- Mitigate live with the smallest corrective action (rebuild the index / restore the connection limit / restore the secret), re-check the lane returns 200, then deliver the durable fix as a PR. Base the RCA on the confirmed surface above — DB-internal faults must resolve to a named cause (index, connection limit, or secret), never "root cause unknown."
Permitted autonomous actions
- Restore replica counts / restart a Container Apps revision.
- Reactivate a deactivated revision (
az containerapp revision activate) to bring back zero-replica lanes. - Roll back to the last-known-good revision.
- Free space on the reporting-worker VM's data disk (remove an accumulated backlog file under
/data).
Code fix
If the root cause is in application source, the app code lives under src/ in @@REPO@@. After
the live mitigation (revision rollback/restart), the durable code fix is delivered as a GitHub PR
by the pr-delivery skill and recorded as a Change Request by servicenow-change-management.
Incident communication
PagerDuty acknowledgement, status/summary notes, and resolution are owned by the
pagerduty-incident-update skill.
Verification
Confirm /api/quiz/* returns 200 and the API success rate is back to baseline.
04 同仓库更多 Skills
zava-reporting
Use to package a completed Zava Learning incident analysis for the audience. First present a branded in-thread executive summary (markdown with the before/after visuals inline), then produce the downloadable deliverables — a PowerPoint deck, an HTML email, and a Teams notification — using the Zava corporate template. The calling agent may narrow this to a subset (e.g. only the HTML report). Produces content and artifacts; it does not send them. Assembles the output of rca-analysis, evidence-before-after, recommendations-next-steps, and pr-delivery.
zava-audit-report
Use to package a completed Zava Learning weekly governance audit (NSG / network security, RBAC / least-privilege, or cloud cost) into a single branded, downloadable PowerPoint deck in the Zava house style. The calling audit agent passes its findings (a list of rows with severity) and a short posture summary; this skill renders the deck, applies redaction, and returns the attachment download link. Produces the artifact; it does not send it.
servicenow-change-management
Use whenever a Zava Learning investigation produces a durable fix that needs change management — after a GitHub PR is opened for an Infrastructure-as-Code or application code root cause, raise a ServiceNow Change Request referencing the PR and attach the RCA report. The single owner of ServiceNow Change Request and attachment operations.
redaction-guard
Use whenever you are about to emit operator-visible content — a chat/thread message, a PagerDuty or ServiceNow note, a commit message or pull-request body, or any report artifact (HTML, PowerPoint, Teams card). Deterministically masks secrets, credentials, tokens, private keys, URI-embedded passwords, and PII so they never appear in the thread or in any deliverable. This is a cross-cutting guardrail invoked by the output-producing skills, not a runbook step.
recommendations-next-steps
Use to produce the forward-looking recommendations and next steps for a Zava Learning incident — prioritized preventive, detective, and process actions with owners, target dates, and the risk of inaction. Its output is used in the zava-reporting deliverables.
rca-analysis
Use to produce the root-cause analysis narrative for a resolved or mitigated Zava Learning incident — the incident timeline, the trigger vs. latent root cause (5-Whys), contributing factors, and how to present them. Defines the RCA section format; its output is used in the before/after, recommendations, and reporting deliverables.