監控與可觀測性¶
平台中的每個元件都會發出指標、日誌和追蹤。監控堆疊完全建構在 CloudWatch 上——沒有第三方代理程式,沒有額外的基礎設施需要管理。警報觸發 SNS 通知以供即時處理,集中式儀表板提供系統健康狀態的單一視圖。
運維承諾
P0(交易時段 < 5 分鐘回應): DLQ 訊息、Lambda 錯誤、API 5xx 激增。P1(< 15 分鐘): 高孤立數量、RDS CPU 飽和。P2(下一個工作日): 縮減事件、API CPU 趨勢。所有狀態變更操作均於 PostgreSQL 中稽核,包含完整請求上下文(IP、user-agent、路徑、成功/失敗)。稽核日誌在主資料庫中保留 90 天,歸檔至 S3 以供長期合規。
CloudWatch 指標¶
Container Insights¶
ECS Container Insights 已在叢集上啟用,無需任何應用層級的檢測即可提供逐 Task 和逐服務的指標:
| 指標 | 粒度 | 顯示內容 |
|---|---|---|
| CPU 使用率 | 逐 Task、逐服務 | 處理負載。API Task 應保持 < 70%。Worker Task 通常 < 5%。 |
| 記憶體使用率 | 逐 Task、逐服務 | 記憶體壓力。Worker 超過軟性限制(384 MB)80% 表示券商 SDK 記憶體增長。 |
| 網路 RX/TX | 逐 Task | 流量。突然的尖峰可能表示 Webhook 洪流或券商 API 重試。 |
| Task 數量 | 逐服務 | 運行中、等待中、期望數量。期望值與運行值的差異表示容量問題。 |
| 儲存讀取/寫入 | 逐 Task | 磁碟 I/O。Worker 應接近零(所有狀態在 Redis/RDS 中)。 |
自訂指標 — Shioaji/Maintenance 命名空間¶
維護 Lambda 在每次掃描週期後發佈自訂指標:
| 指標 | 單位 | 描述 |
|---|---|---|
ActiveWorkerCount |
Count | 所有使用者的活躍 Worker 總數 |
OrphanMarksDetected |
Count | 無匹配 ECS Task 的 Redis 鍵 |
OrphanTasksDetected |
Count | 無匹配 Redis 鍵的 ECS Task |
StaleMarksDetected |
Count | 超過 TTL 但未被清理的 Redis 鍵 |
WorkerLaunchLatency |
Milliseconds | 從啟動命令到 Worker 就緒的時間 |
PoolWorkerCount |
Count | 池中可用的預熱 Worker 數 |
MaintenanceScanDuration |
Milliseconds | 完整掃描 + 扇出的總時間 |
ClaimLatency |
Milliseconds | 從認領請求到 Worker 活躍的時間 |
這些指標為編排器儀表板提供資料,並驅動運維異常的警報閾值。
警報¶
| 警報 | 指標 | 閾值 | 週期 | 動作 |
|---|---|---|---|---|
| DLQ 訊息 | DLQ 上的 ApproximateNumberOfMessagesVisible | > 0 | 1 分鐘 | SNS → 電子郵件 |
| Worker-Control Lambda 錯誤 | worker_control 函式的 Errors | 10 分鐘內 > 5 | 5 分鐘 × 2 評估 | SNS → 電子郵件 |
| Maintenance Lambda 錯誤 | maintenance 函式的 Errors | 10 分鐘內 > 3 | 5 分鐘 × 2 評估 | SNS → 電子郵件 |
| 高孤立數量 | OrphanMarksDetected + OrphanTasksDetected | 5 分鐘內 > 10 | 5 分鐘 | SNS → 電子郵件 |
| 縮減 Task | Worker 服務的 RunningTaskCount | 30 分鐘為 0 | 30 分鐘 | 自動擴展(縮減) |
| 縮減 CPU | Worker 叢集的 CPUReservation | 30 分鐘 < 5% | 5 分鐘 × 6 評估 | 自動擴展(縮減) |
| API 高 CPU | API 服務的 CPUUtilization | 5 分鐘 > 80% | 5 分鐘 | 自動擴展(擴展) |
| API 5xx 率 | ALB 上的 HTTPCode_Target_5XX_Count | 5 分鐘內 > 10 | 5 分鐘 | SNS → 電子郵件 |
| RDS CPU | RDS 上的 CPUUtilization | 10 分鐘 > 80% | 10 分鐘 | SNS → 電子郵件 |
DLQ 警報至關重要
死信佇列中的訊息意味著某個 Worker 命令或訂單任務連續失敗了 3 次。這可能表示:Lambda 函式正在當機、Redis 無法連線、ECS 容量耗盡,或券商 API 停機。每條 DLQ 訊息都需要在交易時段幾分鐘內調查。
警報優先級矩陣¶
| 優先級 | 警報 | 回應時間 |
|---|---|---|
| P0 — 立即 | DLQ 訊息、Lambda 錯誤、API 5xx | 交易時段 < 5 分鐘 |
| P1 — 緊急 | 高孤立數量、RDS CPU | < 15 分鐘 |
| P2 — 監控 | 縮減、API 高 CPU | 下一個工作日 |
儀表板¶
CloudWatch 儀表板 orchestrator 提供系統健康狀態的單一視圖:
CloudWatch 儀表板 orchestrator 分為 4 列:
| 列 | Widget | 關鍵指標 |
|---|---|---|
| Lambda 健康 | 呼叫次數、錯誤、持續時間 | 全部 5 個函式;p50/p95/p99 延遲 |
| 佇列健康 | 佇列深度、訊息年齡、DLQ 數量 | worker-control.fifo、order-tasks.fifo |
| ECS 健康 | Task 數量、CPU、記憶體 | 運行中 vs 期望;API + Worker 使用率 |
| 維護 | 活躍 Worker、孤立數、啟動延遲 | Pool claim vs RunTask 時序 |
儀表板 Widget¶
| Widget | 資料來源 | 重新整理 | 用途 |
|---|---|---|---|
| Lambda 呼叫次數 | CloudWatch Logs | 1 分鐘 | 驗證編排器正在運行。零呼叫 = EventBridge 故障。 |
| Lambda 錯誤 | CloudWatch Logs | 1 分鐘 | 任何非零值都需要調查。 |
| Lambda 持續時間 | CloudWatch Logs | 1 分鐘 | maintenance 的 p95 > 30s 表示擴展問題。 |
| SQS 佇列深度 | SQS 指標 | 1 分鐘 | 深度增長 = Lambda 處理不及。擴展並行數。 |
| SQS 訊息年齡 | SQS 指標 | 1 分鐘 | 年齡 > 可見性逾時 = 訊息正在被重新處理。 |
| DLQ 訊息數量 | SQS 指標 | 1 分鐘 | 必須始終為 0。非零 = 處理中斷。 |
| ECS 運行中 Task | ECS 指標 | 1 分鐘 | 與期望值比較。差異 = 容量或排程問題。 |
| 活躍 Worker 數 | 自訂指標 | 1 分鐘 | 追蹤同時在線使用者。與業務指標相關。 |
| 孤立數量 | 自訂指標 | 1 分鐘 | 基線應 < 2。持續 > 5 表示系統性問題。 |
| Worker 啟動延遲 | 自訂指標 | 1 分鐘 | Pool 路徑應 < 1s。RunTask 路徑 < 5s。退化 = Pool 為空。 |
SNS 告警¶
告警流程¶
SNS 配置¶
| 參數 | 值 |
|---|---|
| 主題名稱 | shioaji-alerts |
| 協定 | |
| 訂閱者 | 營運團隊通訊群組 |
| 投遞重試 | 3 次,指數退避 |
| 加密 | SSE 已啟用(AWS 託管金鑰) |
告警電子郵件包含:
- 警報名稱和描述
- 目前指標值 vs 閾值
- 狀態變更(OK → ALARM 或 ALARM → OK)
- 時間戳記(UTC)
- CloudWatch 主控台的直接連結
稽核日誌¶
應用層級的稽核日誌記錄每個已驗證的操作,用於合規性、安全監控和事件調查。
記錄的內容¶
| 欄位 | 來源 | 範例 |
|---|---|---|
user_id |
Session / JWT | 42 |
action |
應用程式碼 | webhook.order_executed、auth.login、account.credentials_updated |
ip_address |
X-Forwarded-For 標頭 | 203.0.113.42 |
user_agent |
User-Agent 標頭 | Mozilla/5.0... |
request_path |
Request 物件 | /api/v1/webhook/tradingview |
request_method |
Request 物件 | POST |
success |
應用邏輯 | true / false |
error_message |
例外處理器 | null 或 "Invalid webhook token" |
details |
上下文相關 JSON | {"order_id": "abc123", "symbol": "2330"} |
created_at |
伺服器時間戳記 | 2025-02-27T09:15:32.841Z |
儲存¶
稽核日誌儲存在 audit_logs PostgreSQL 表中:
CREATE TABLE audit_logs (
id BIGSERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
action VARCHAR(100) NOT NULL,
ip_address INET,
user_agent TEXT,
request_path VARCHAR(500),
request_method VARCHAR(10),
success BOOLEAN DEFAULT true,
error_message TEXT,
details JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_audit_user_action ON audit_logs (user_id, action, created_at);
CREATE INDEX idx_audit_created ON audit_logs (created_at);
稽核使用案例¶
| 使用案例 | 查詢模式 |
|---|---|
| 安全調查 | 在時間視窗內按 IP 地址 + 失敗操作篩選 |
| 合規報告 | 某使用者在日期範圍內的所有操作 |
| 攻擊偵測 | 按 IP 分組的失敗登入嘗試 |
| 除錯 | 特定使用者 + 訂單的所有 Webhook 執行紀錄 |
| 使用分析 | 按類型統計隨時間變化的操作數量 |
保留政策
稽核日誌在主資料庫中保留 90 天。在規模化(10K+ 使用者)時,較舊的日誌會以 Parquet 格式歸檔到 S3,用於長期保留和透過 Athena 進行成本效益的查詢。
監控資料流¶
指標來源:Container Insights(CPU、記憶體、網路)、Lambda 指標(呼叫次數、錯誤、持續時間)、SQS 指標(深度、年齡、DLQ)、RDS 指標(CPU、連線數)、Valkey 指標(ECPU、儲存空間),以及自訂 Shioaji/Maintenance 命名空間。
可觀測性原則
如果它可能故障,就有指標。如果指標可能突破閾值,就有警報。如果警報觸發,就有人收到電子郵件。不允許靜默故障。