跳轉到

監控與可觀測性

平台中的每個元件都會發出指標、日誌和追蹤。監控堆疊完全建構在 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 告警

告警流程

flowchart TB Sources["ECS + Lambda + SQS + RDS + 自訂指標"] --> CW["CloudWatch 指標"] Logs["CloudWatch 日誌"] --> MF["指標篩選器"] --> CW CW --> Alarms["警報"] Alarms -->|ALARM| SNS["SNS"] --> Email["電子郵件"]

SNS 配置

參數
主題名稱 shioaji-alerts
協定 Email
訂閱者 營運團隊通訊群組
投遞重試 3 次,指數退避
加密 SSE 已啟用(AWS 託管金鑰)

告警電子郵件包含:

  • 警報名稱和描述
  • 目前指標值 vs 閾值
  • 狀態變更(OK → ALARM 或 ALARM → OK)
  • 時間戳記(UTC)
  • CloudWatch 主控台的直接連結

稽核日誌

應用層級的稽核日誌記錄每個已驗證的操作,用於合規性、安全監控和事件調查。

記錄的內容

欄位 來源 範例
user_id Session / JWT 42
action 應用程式碼 webhook.order_executedauth.loginaccount.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 進行成本效益的查詢。


監控資料流

flowchart LR subgraph sources["來源"] App["API + Worker + Lambda"] end subgraph cloudwatch["CloudWatch"] Logs["日誌"] Metrics["指標"] Alarms["警報"] end subgraph alerting["告警"] SNS["SNS"] --> Email["電子郵件"] end App --> Logs --> Metrics --> Alarms --> SNS App -->|"log_audit()"| DB["audit_logs 資料表"]

指標來源:Container Insights(CPU、記憶體、網路)、Lambda 指標(呼叫次數、錯誤、持續時間)、SQS 指標(深度、年齡、DLQ)、RDS 指標(CPU、連線數)、Valkey 指標(ECPU、儲存空間),以及自訂 Shioaji/Maintenance 命名空間。

可觀測性原則

如果它可能故障,就有指標。如果指標可能突破閾值,就有警報。如果警報觸發,就有人收到電子郵件。不允許靜默故障。