Files

375 lines
13 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
$ uv run tools/flow.py push answers/76-lab02-challenge-alert.json
! unpublished '76 Intake · DLQ + error workflow (reference, Lab 02 example 2)' (w01376519d41c1ce): it used the same webhook path
✔ pushed '76 Intake · alert on handled failures (answer, Lab 02 task 1)' (id w82959c505ef75f7)
POST http://localhost:5678/webhook/my-intake
$ uv run tools/flow.py test cases/lab02-challenge.json -v
✔ before: POST http://localhost:8800/tickets-reset · HTTP 200 · 0.0s · {"cleared": 3}
→ request POST http://localhost:8800/tickets-reset
{}
← response HTTP 200
{
"cleared": 3
}
✔ before: POST http://localhost:8800/dlq-clear · HTTP 200 · 0.0s · {"cleared": 2}
→ request POST http://localhost:8800/dlq-clear
{}
← response HTTP 200
{
"cleared": 2
}
✔ before: POST http://localhost:8800/alerts-clear · HTTP 200 · 0.0s · {"cleared": 0}
→ request POST http://localhost:8800/alerts-clear
{}
← response HTTP 200
{
"cleared": 0
}
✔ before: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "ok", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 8}
→ request POST http://localhost:8800/admin/fault
{
"faq": "ok",
"tickets": "ok",
"prompts": "ok",
"usage": "ok",
"dlq": "ok"
}
← response HTTP 200
{
"faq": "ok",
"tickets": "ok",
"prompts": "ok",
"usage": "ok",
"dlq": "ok",
"slow_seconds": 8
}
POST http://localhost:5678/webhook/my-intake · 6 case(s) × 1
✔ before: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "error", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 8}
→ request POST http://localhost:8800/admin/fault
{
"tickets": "error"
}
← response HTTP 200
{
"faq": "ok",
"tickets": "error",
"prompts": "ok",
"usage": "ok",
"dlq": "ok",
"slow_seconds": 8
}
✔ API가 멈춤 → DLQ · 4.3s
→ request POST /webhook/my-intake
{
"requests": [
{
"id": "R-301",
"user": "정우성",
"text": "사내 위키 로그인이 안 돼요"
},
{
"id": "R-302",
"user": "이준호",
"text": "노트북 배터리가 금방 닳아요"
}
]
}
← response HTTP 200
{
"total": 2,
"created": 0,
"failed": 2,
"rejected": 0,
"duplicates": 0,
"unclassified": 0,
"results": [
{
"id": "R-301",
"status": "failed",
"reason": "500 - \"{\\\"error\\\": \\\"tickets service is failing (fault switch)\\\"}\""
},
{
"id": "R-302",
"status": "failed",
"reason": "500 - \"{\\\"error\\\": \\\"tickets service is failing (fault switch)\\\"}\""
}
],
"dlq_saved": true,
"alert": "sent"
}
✔ after: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "ok", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 8}
→ request POST http://localhost:8800/admin/fault
{
"faq": "ok",
"tickets": "ok",
"prompts": "ok",
"usage": "ok",
"dlq": "ok"
}
← response HTTP 200
{
"faq": "ok",
"tickets": "ok",
"prompts": "ok",
"usage": "ok",
"dlq": "ok",
"slow_seconds": 8
}
✔ 처리한 실패도 알림 (high · 개수) · 0.0s
→ request POST http://localhost:8800/alerts/latest
{}
← response HTTP 200
{
"workflow": "intake",
"node": "Send to DLQ",
"severity": "high",
"reason": "dlq",
"count": 2,
"message": "2 request(s) could not be created and wait in the DLQ",
"execution_id": "10120",
"at": 1793250965.2341518
}
✔ 실패가 없으면 알림 없음 · 2.9s
→ request POST /webhook/my-intake
{
"requests": [
{
"id": "R-101",
"user": "이준호",
"text": "VPN이 아침부터 계속 끊겨서 고객 미팅을 못 하고 있어요"
},
{
"id": "R-102",
"user": "박서연",
"text": "새 모니터를 하나 더 받을 수 있을까요?"
},
{
"id": "R-103",
"user": "최유진",
"text": "엑셀 라이선스가 만료됐다고 나와요"
}
]
}
← response HTTP 200
{
"total": 3,
"created": 3,
"failed": 0,
"rejected": 0,
"duplicates": 0,
"unclassified": 0,
"results": [
{
"id": "R-101",
"status": "created",
"ticket_id": "T-2001",
"duplicate": false,
"category": "네트워크",
"priority": "높음"
},
{
"id": "R-102",
"status": "created",
"ticket_id": "T-2002",
"duplicate": false,
"category": "장비",
"priority": "낮음"
},
{
"id": "R-103",
"status": "created",
"ticket_id": "T-2003",
"duplicate": false,
"category": "소프트웨어",
"priority": "높음"
}
],
"alert": "none"
}
✔ 알림은 그대로 1개 · 0.0s
→ request POST http://localhost:8800/alerts/list
{}
← response HTTP 200
{
"count": 1,
"alerts": [
{
"workflow": "intake",
"node": "Send to DLQ",
"severity": "high",
"reason": "dlq",
"count": 2,
"message": "2 request(s) could not be created and wait in the DLQ",
"execution_id": "10120",
"at": 1793250965.2341518
}
]
}
✔ before: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "error", "prompts": "ok", "usage": "ok", "dlq": "error", "slow_seconds": 8}
→ request POST http://localhost:8800/admin/fault
{
"tickets": "error",
"dlq": "error"
}
← response HTTP 200
{
"faq": "ok",
"tickets": "error",
"prompts": "ok",
"usage": "ok",
"dlq": "error",
"slow_seconds": 8
}
✔ DLQ도 멈추면 critical · 2.4s
→ request POST /webhook/my-intake
{
"requests": [
{
"id": "R-201",
"user": "한지훈",
"text": "프린터 용지가 걸려요"
},
{
"id": "R-202",
"user": "한지훈",
"text": ""
},
{
"id": "R-203",
"user": "김민지",
"text": "메일 첨부가 안 열려요"
}
]
}
← response HTTP 200
{
"total": 3,
"created": 0,
"failed": 2,
"rejected": 1,
"duplicates": 0,
"unclassified": 0,
"results": [
{
"id": "R-201",
"status": "failed",
"reason": "500 - \"{\\\"error\\\": \\\"tickets service is failing (fault switch)\\\"}\""
},
{
"id": "R-203",
"status": "failed",
"reason": "500 - \"{\\\"error\\\": \\\"tickets service is failing (fault switch)\\\"}\""
},
{
"id": "R-202",
"status": "rejected",
"reason": "text is required"
}
],
"dlq_saved": false,
"alert": "sent"
}
✔ after: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "ok", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 8}
→ request POST http://localhost:8800/admin/fault
{
"faq": "ok",
"tickets": "ok",
"prompts": "ok",
"usage": "ok",
"dlq": "ok"
}
← response HTTP 200
{
"faq": "ok",
"tickets": "ok",
"prompts": "ok",
"usage": "ok",
"dlq": "ok",
"slow_seconds": 8
}
✔ 잃어버린 id를 알림에 · 0.0s
→ request POST http://localhost:8800/alerts/latest
{}
← response HTTP 200
{
"workflow": "intake",
"node": "Send to DLQ",
"severity": "critical",
"reason": "dlq_down",
"count": 2,
"message": "DLQ save failed: dlq service is failing (fault switch) · lost ids R-201, R-203",
"execution_id": "10122",
"ids": [
"R-201",
"R-203"
],
"at": 1793250970.5394928
}
Passed 6/6
report: runs/lab02-challenge-20261029-141610.json
✔ after: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "ok", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 8}
→ request POST http://localhost:8800/admin/fault
{
"faq": "ok",
"tickets": "ok",
"prompts": "ok",
"usage": "ok",
"dlq": "ok"
}
← response HTTP 200
{
"faq": "ok",
"tickets": "ok",
"prompts": "ok",
"usage": "ok",
"dlq": "ok",
"slow_seconds": 8
}
$ uv run tools/flow.py test cases/lab02-nets.json
✔ before: POST http://localhost:8800/tickets-reset · HTTP 200 · 0.0s · {"cleared": 3}
✔ before: POST http://localhost:8800/dlq-clear · HTTP 200 · 0.0s · {"cleared": 2}
✔ before: POST http://localhost:8800/alerts-clear · HTTP 200 · 0.0s · {"cleared": 2}
✔ before: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "ok", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 8}
POST http://localhost:5678/webhook/my-intake · 7 case(s) × 1
✔ 1 · 잘못된 항목 → 결과에만 (rejected) · 2.1s
✔ before: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "error", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 8}
✔ 2 · API 오류 → failed · 2.9s
✔ 3 · failed는 DLQ에 · 0.0s
✔ 4 · 버그 → 500 · 0.1s
… before: wait 3s
✔ 5 · Error Workflow → critical 알림 · 0.0s
✔ before: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "error", "prompts": "ok", "usage": "ok", "dlq": "error", "slow_seconds": 8}
✔ 6 · DLQ마저 멈추면 결과가 알려야 · 3.7s
✔ 7 · DLQ가 멈춘 것을 누가 아나 (critical · dlq_down) · 0.0s
Passed 7/7
report: runs/lab02-nets-20261029-141622.json
✔ after: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "ok", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 8}
$ uv run tools/flow.py test cases/lab02.json
✔ before: POST http://localhost:8800/tickets-reset · HTTP 200 · 0.0s · {"cleared": 2}
✔ before: POST http://localhost:8800/dlq-clear · HTTP 200 · 0.0s · {"cleared": 2}
✔ before: POST http://localhost:8800/alerts-clear · HTTP 200 · 0.0s · {"cleared": 3}
✔ before: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "ok", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 8}
POST http://localhost:5678/webhook/my-intake · 4 case(s) × 1
✔ before: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "error", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 8}
✔ 예제 1 · API가 멈추면 실패로 표시 · 200 · 2.7s
✔ after: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "ok", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 8}
✔ 예제 1 · 실패한 2건은 DLQ에 · 0.0s
✔ 예제 2 · 예상 못 한 오류 (nightly-report) · 0.0s
… before: wait 3s
✔ 예제 2 · Error Workflow가 알림을 남김 · 0.0s
Passed 4/4
report: runs/lab02-20261029-141628.json
✔ after: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "ok", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 8}
$ uv run tools/flow.py ops
fault switch: all ok
created tickets: 0
DLQ: 2 (parked 0)
D-1 R-301 attempts 1 parked False 500 - "{\"error\": \"tickets service is failing (f
D-2 R-302 attempts 1 parked False 500 - "{\"error\": \"tickets service is failing (f
alerts: 2
[high] intake · dlq · Send to DLQ · count 2 · 2 request(s) could not be created and wait in the DLQ
[critical] 76 Nightly report (provided, has a bug) · unexpected · Count by category · rows is not iterable [line 4]