# Monitor

เริ่มต้นตัวตรวจสอบที่ทำงานในเบื้องหลัง ซึ่งสตรีมเหตุการณ์จากสคริปต์ที่ทำงานยาวนาน ทุกบรรทัดของ stdout จะกลายเป็นการแจ้งเตือน — ทำงานต่อไปได้ขณะที่เหตุการณ์ปรากฏในแชท

## เมื่อใดควรใช้

- ติดตามข้อผิดพลาด คำเตือน หรือรูปแบบการล่มสลายในไฟล์บันทึกขณะที่การติดตั้งระบบกำลังดำเนินอยู่
- สำรวจ API ระยะไกล PR หรือ CI pipeline ทุก 30 วินาทีเพื่อตรวจจับเหตุการณ์สถานะใหม่
- เฝ้าดูการเปลี่ยนแปลงในไดเรกทอรีของระบบไฟล์หรือผลลัพธ์การสร้างในแบบเรียลไทม์
- รอเงื่อนไขเฉพาะตลอดการวนซ้ำหลายครั้ง (เช่น จุดสำคัญของขั้นตอนการฝึกโมเดล หรือคิวที่ถูกเคลียร์)
- **ไม่ใช้** สำหรับการ "รอจนเสร็จ" อย่างง่าย — ใช้ `Bash` กับ `run_in_background` แทน ซึ่งจะส่งการแจ้งเตือนเสร็จสิ้นครั้งเดียวเมื่อกระบวนการสิ้นสุด

## พารามิเตอร์

- `command` (สตริง, จำเป็น): คำสั่ง shell หรือสคริปต์ที่จะรัน ทุกบรรทัดที่เขียนไปยัง stdout จะกลายเป็นเหตุการณ์การแจ้งเตือนแยกต่างหาก ตัวตรวจสอบสิ้นสุดเมื่อกระบวนการสิ้นสุด
- `description` (สตริง, จำเป็น): ป้ายกำกับสั้นที่อ่านได้ซึ่งแสดงในทุกการแจ้งเตือน ควรระบุให้เฉพาะเจาะจง — "ข้อผิดพลาดใน deploy.log" ดีกว่า "กำลังดูบันทึก" ป้ายกำกับนี้ระบุว่าตัวตรวจสอบใดถูกเรียกใช้
- `timeout_ms` (ตัวเลข, ค่าเริ่มต้น `300000`, สูงสุด `3600000`): กำหนดเวลาบังคับสิ้นสุดเป็นมิลลิวินาที หลังจากระยะเวลานี้กระบวนการจะถูกยุติ ถูกละเว้นเมื่อ `persistent: true`
- `persistent` (บูลีน, ค่าเริ่มต้น `false`): เมื่อเป็น `true` ตัวตรวจสอบจะทำงานตลอดช่วงเวลาของ session โดยไม่มี timeout หยุดอย่างชัดเจนด้วย `TaskStop`

## ตัวอย่าง

### ตัวอย่างที่ 1: ติดตามไฟล์บันทึกเพื่อหาข้อผิดพลาดและการล่มสลาย

ตัวอย่างนี้ครอบคลุมทุกสถานะสุดท้าย: ตัวบ่งชี้ความสำเร็จ, traceback, คำสำคัญของข้อผิดพลาดทั่วไป, การยุติเนื่องจาก OOM และการออกจากกระบวนการที่ไม่คาดคิด

```bash
tail -F /var/log/deploy.log | grep -E --line-buffered \
  "deployed|Traceback|Error|FAILED|assert|Killed|OOM"
```

ใช้ `grep --line-buffered` ในทุก pipe หากไม่ใช้ OS จะบัฟเฟอร์ผลลัพธ์เป็นบล็อก 4 KB และเหตุการณ์อาจล่าช้าหลายนาที รูปแบบการสลับครอบคลุมทั้งเส้นทางสำเร็จ (`deployed`) และเส้นทางล้มเหลว (`Traceback`, `Error`, `FAILED`, `Killed`, `OOM`) ตัวตรวจสอบที่เฝ้าดูเฉพาะตัวบ่งชี้ความสำเร็จจะเงียบในระหว่างการล่มสลาย — ความเงียบไม่ต่างจาก "ยังคงทำงานอยู่"

### ตัวอย่างที่ 2: สำรวจ API ระยะไกลทุก 30 วินาที

```bash
while true; do
  curl -sf "https://api.example.com/status" || true
  sleep 30
done | grep --line-buffered -E "completed|failed|error"
```

`|| true` ป้องกันไม่ให้ความล้มเหลวของเครือข่ายชั่วคราวยุติลูป ช่วงเวลาการสำรวจ 30 วินาทีขึ้นไปเหมาะสมสำหรับ API ระยะไกลเพื่อหลีกเลี่ยงข้อจำกัดอัตรา ปรับรูปแบบ grep เพื่อจับทั้งการตอบสนองที่สำเร็จและล้มเหลว เพื่อไม่ให้ข้อผิดพลาดฝั่ง API ถูกปิดบังด้วยความเงียบ

## หมายเหตุ

- **ใช้ `grep --line-buffered` ใน pipe เสมอ** หากไม่ใช้ การบัฟเฟอร์ของ pipe จะทำให้เหตุการณ์ล่าช้าหลายนาที เพราะ OS จะรวบรวมผลลัพธ์จนเต็มบล็อก 4 KB `--line-buffered` บังคับให้ล้างบัฟเฟอร์หลังทุกบรรทัด
- **ฟิลเตอร์ต้องครอบคลุมทั้งลายเซ็นของความสำเร็จและความล้มเหลว** ตัวตรวจสอบที่เฝ้าดูเฉพาะตัวบ่งชี้ความสำเร็จจะเงียบเมื่อเกิดการล่มสลาย การค้างหรือการออกที่ไม่คาดคิด ขยายการสลับ: รวม `Error`, `Traceback`, `FAILED`, `Killed`, `OOM` และตัวบ่งชี้สถานะสุดท้ายที่คล้ายกันควบคู่กับคำสำคัญของความสำเร็จ
- **ช่วงเวลาการสำรวจ: 30 วินาทีขึ้นไปสำหรับ API ระยะไกล** การสำรวจบ่อยๆ บนบริการภายนอกเสี่ยงต่อข้อผิดพลาดจำกัดอัตราหรือการบล็อก สำหรับการตรวจสอบระบบไฟล์ในเครื่องหรือกระบวนการ 0.5–1 วินาทีเหมาะสม
- **ใช้ `persistent: true` สำหรับตัวตรวจสอบตลอด session** ค่า `timeout_ms` เริ่มต้น 300,000 มิลลิวินาที (5 นาที) จะยุติกระบวนการ สำหรับตัวตรวจสอบที่ควรทำงานจนกว่าจะหยุดอย่างชัดเจน ให้ตั้ง `persistent: true` และเรียก `TaskStop` เมื่อเสร็จสิ้น
- **หยุดอัตโนมัติเมื่อเหตุการณ์ล้นหลาม** ทุกบรรทัดของ stdout คือข้อความสนทนา หากฟิลเตอร์กว้างเกินไปและสร้างเหตุการณ์มากเกินไป ตัวตรวจสอบจะหยุดอัตโนมัติ รีสตาร์ทด้วยรูปแบบ `grep` ที่แคบกว่า บรรทัดที่มาถึงภายใน 200 มิลลิวินาทีจะถูกรวมเป็นการแจ้งเตือนเดียว
