Observability(Webhook)
把請求 Log 即時推送到你的監控或資料系統
Observability 讓工作區的每一筆 Gateway 請求紀錄,在寫入後以 Webhook 推送到你指定的網址,方便串接自家監控、告警或資料分析流程。
設定方式
Console → 工作區 → Observability → Webhook。僅工作區 ADMIN 可管理,MEMBER 只能檢視。
每個工作區最多可設定 10 組 Webhook,每組包含:
- 標題與 Webhook 網址(http/https;不可指向本機或私有網段)
- 簽章密鑰(可選填):設定後每次推送會附上
X-Hakila-Signature - 自訂標頭(可選填,最多 10 個):例如接收端需要的
Authorization、DD-API-KEY - 推送範圍:所有請求,或僅失敗請求(HTTP 狀態碼 ≥ 400)
- 綁定 Hakila API Key:預設不指定(工作區所有 API Key),也可只推送特定幾把的請求
- 附帶 Input/Output 內容:推送完整的 request/response body;需組織已開啟完整記錄 prompt/response 才有內容
儲存後可按「發送測試」立即送出一筆 webhook.test 事件確認設定。設定變更約 30 秒內生效。
推送格式
每筆請求送出一次 POST,Content-Type: application/json:
{
"event": "request.completed",
"sentAt": "2026-09-30T13:00:01.234Z",
"data": {
"requestId": "3f0c2a4e-…",
"timestamp": "2026-09-30T13:00:00.000Z",
"organizationId": "…",
"workspaceId": "…",
"apiKeyId": "…",
"userId": null,
"endpoint": "/v1/chat/completions",
"model": "openai/gpt-4o",
"provider": "openai",
"upstreamModel": "gpt-4o",
"streamed": false,
"statusCode": 200,
"success": true,
"errorMessage": null,
"usage": {
"promptTokens": 120,
"completionTokens": 48,
"totalTokens": 168,
"cachedTokens": null,
"cacheWriteTokens": null
},
"costUsd": 0.00078,
"cacheStatus": null,
"presetSlug": null,
"latencyMs": 1830,
"ttfbMs": 420,
"clientIp": "203.0.113.10",
"input": {
"model": "openai/gpt-4o",
"messages": [{ "role": "user", "content": "你好" }]
},
"output": {
"choices": [
{ "message": { "role": "assistant", "content": "你好!有什麼可以幫你?" } }
]
}
}
}Input/Output
input:呼叫端送來的原始 request body(尚未套用 Preset)。output:完整的 response body;streaming 請求為彙整後的內容。Embeddings 的向量會以維度數取代,TTS 的音訊只記錄格式與大小。- 內容是 JSON 時原樣嵌入,否則為字串。超過 1 MB 的 body 會改成
{ "truncated": true, "length": <位元組數>, "preview": "…" }。
這兩個欄位受兩個開關控制:
| Webhook「附帶 Input/Output」 | 組織「完整記錄 prompt/response」 | 結果 |
|---|---|---|
| 關閉 | 任一 | 不含 input/output 欄位 |
| 開啟 | 關閉 | 欄位存在但為 null |
| 開啟 | 開啟 | 帶完整內容 |
標頭
| 標頭 | 說明 |
|---|---|
X-Hakila-Event | request.completed 或 webhook.test |
X-Hakila-Delivery | 每次推送唯一的 id |
X-Hakila-Timestamp | Unix 秒數,用於簽章 |
X-Hakila-Signature | sha256=<hex>,僅在設定簽章密鑰時出現 |
驗證簽章
簽章為 HMAC_SHA256(密鑰, "{X-Hakila-Timestamp}.{原始 body}") 的十六進位字串。請用原始 body 位元組計算,不要先解析再序列化。
import crypto from "node:crypto";
function verify(secret, timestamp, rawBody, signatureHeader) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));
}建議同時檢查 X-Hakila-Timestamp 與目前時間差距(例如 5 分鐘內),避免重放攻擊。
重試與送達
- 回應 2xx 視為成功;單次逾時 10 秒,不跟隨重新導向。
- 連線失敗、逾時、408、429、5xx 會再重試 2 次(間隔 2 秒、10 秒);其他 4xx 不重試。
- 推送與 Log 寫入分開處理,接收端慢或失敗不影響 Gateway 與 Log。
- 與請求紀錄相同屬於「盡力送達」:服務重啟時尚未送出的事件可能遺失,請勿用於計費對帳。
- 最近一次推送時間、狀態碼與錯誤會顯示在設定頁。