Gắn monitor bằng SDK Belvador
withMonitor, captureCheckIn và heartbeat cho TanStack Start và Cloudflare Workers; tạo monitor trong Belvador hoặc từ code.
Từ @belvador/* 0.3.0, các gói phía máy chủ báo việc chạy ngầm bằng ba hàm. Chúng không bao giờ ném lỗi, không đổi giá trị job trả về, và không làm gì khi SDK tắt.
| Hàm | Dùng khi |
|---|---|
withMonitor(slug, fn, options?) | Bọc một lượt chạy: lúc bắt đầu, lúc xong, lỗi và thời lượng được báo giúp bạn |
captureCheckIn(checkIn, config?) | Tự báo lúc bắt đầu hoặc kết thúc, khi việc không nằm gọn trong một lần gọi hàm |
heartbeat(slug) | Báo "vẫn còn sống" cho monitor theo chu kỳ |
Các hàm có trong @belvador/tanstack-start/server và @belvador/cloudflare. Gói trình duyệt không có: check-in gửi từ trình duyệt bị từ chối.
Bọc job bằng withMonitor#
TanStack Start#
import { createFileRoute } from "@tanstack/react-router";import { withMonitor } from "@belvador/tanstack-start/server";// Call this route from your scheduler; the run is reported even if it throws.export const Route = createFileRoute("/api/jobs/nightly-invoices")({ server: { handlers: { POST: async () => { const result = await withMonitor("nightly-invoices", async (run) => { // Your job. Nothing to do? run.skip("nothing_due") return { done: true }; }, { schedule: { type: "crontab", value: "0 2 * * *" }, timezone: "UTC" }); return Response.json(result); }, }, },});Gọi route này từ trình lập lịch của bạn (dịch vụ cron, cron trigger của Workers, GitHub Actions). Bảo vệ nó như mọi endpoint nội bộ.
Cloudflare Workers#
import { withBelvador, withMonitor } from "@belvador/cloudflare";export default withBelvador((env: Env) => ({ release: env.BELVADOR_RELEASE }), { async scheduled(controller, env, ctx) { await withMonitor("nightly-invoices", async (run) => { // Your job. Nothing to do? run.skip("nothing_due") }, { schedule: { type: "crontab", value: "0 2 * * *" }, timezone: "UTC" }); },});Mỗi lượt chạy diễn ra như sau:
Gửi
in_progresskhifnbắt đầu.Khi
fntrả về (hoặc promise hoàn tất), gửiokkèm thời lượng.Khi
fnném lỗi, lỗi được ghi như một issue bình thường — liên kết với lượt này — và gửierror. Sau đó chính lỗi ấy được ném lại cho code của bạn, không đổi.
Cho Belvador biết lượt chạy đã làm gì#
fn nhận một tham số run:
run.skip("nothing_due")— job có chạy nhưng không có việc. Lượt chạy là Bỏ qua, tính là khoẻ.run.unknown("provider_timeout")— job kết thúc nhưng không biết việc đã có hiệu lực chưa. Lượt chạy thành Chưa rõ kết quả và monitor Cần xem lại.
Lý do là mã ngắn: chữ thường, số, ., _, -, tối đa 64 ký tự. Đừng bao giờ đưa dữ liệu khách hàng vào.
Thử lại#
Hàng đợi tự thử lại; Belvador chỉ cần biết những lần thử nào thuộc cùng một lượt:
await withMonitor("sync-orders", async () => syncOrders(message), { runId: message.id, // cùng một id ở mọi lần thử attempt: message.attempts, // 1 cho lần đầu willRetry: (error) => message.attempts < 5,});Lần thử lỗi mà willRetry là true hiện là Sẽ thử lại và không mở sự cố; kết quả cuối của lượt mới quyết định. Belvador không bao giờ tự chạy lại việc của bạn.
Lỗi của mỗi lần thử hỏng cũng được gửi thành một event của issue, để lượt chạy cho thấy từng lần thử gặp lỗi gì. Ba lần thử của cùng một lỗi là một issue với ba event, và một message chạy được ở lần thứ ba vẫn để lại hai. Khi số event quan trọng hơn (điều kiện archive theo số event, ngưỡng escalating, quota), chỉ báo lần hỏng cuối (SDK 0.5.3):
await withMonitor("sync-orders", async () => syncOrders(message), { runId: message.id, attempt: message.attempts, willRetry: (error) => message.attempts < 5, reportRetries: false, // lần thử còn được thử lại chỉ gửi check-in, không gửi event lỗi});Lỗi được gửi mang số lần thử trong context monitor.
Tạo monitor#
Có hai cách; cả hai cho ra cùng một monitor.
Trong Belvador. Mở Monitor → Tạo monitor, chọn project, tên, lịch và giới hạn, rồi dùng slug trong code. Lịch và giới hạn sau đó sửa trong Belvador.
Từ code. Truyền lịch trong options như các ví dụ trên. Check-in đầu tiên tạo monitor, có nhãn Định nghĩa trong code; các check-in sau cập nhật nó. Lịch và giới hạn bị khoá trong Belvador — hãy sửa trong code. Tên và môi trường theo dõi vẫn sửa được trong Belvador.
Các tuỳ chọn định nghĩa monitor từ code:
| Tuỳ chọn | Kiểu | Mặc định |
|---|---|---|
schedule | { type: "crontab", value: "0 2 * * *" } hoặc { type: "interval", value: 15, unit: "minute" } | — (không có thì không tạo gì từ code) |
timezone | tên IANA, ví dụ "Asia/Ho_Chi_Minh" | "UTC" |
checkinMargin | phút | 5 |
maxRuntime | phút, tối đa 10080 | 30 |
failureIssueThreshold | số lượt liên tiếp | 1 |
recoveryThreshold | số lượt liên tiếp | 1 |
environment | môi trường của lượt chạy này | environment của SDK |
Phát hiện từ code#
Project có thể tắt Cho tạo monitor từ code (Cài đặt project → Quan sát). Khi đó slug mới hiện ở Monitor → Phát hiện từ code; Duyệt biến nó thành monitor với cấu hình code đã gửi, Bỏ qua ẩn nó 30 ngày. Danh sách này cũng nhận các slug vượt quá 20 monitor mới mỗi project mỗi giờ. Monitor đã xoá không được tạo lại từ code trong 30 ngày.
captureCheckIn và heartbeat#
Khi lúc bắt đầu và lúc kết thúc nằm ở hai nơi — job chia thành hai hàm, hoặc tiến trình chạy nhiều ngày — hãy tự báo:
const checkInId = captureCheckIn({ monitorSlug: "import-catalog", status: "in_progress" });// … sau đó, có thể trong hàm khác …captureCheckIn({ monitorSlug: "import-catalog", status: "ok", checkInId, duration: 42 });duration tính bằng giây. Với monitor theo chu kỳ chỉ cần dấu hiệu còn sống, gọi heartbeat("queue-worker") ở mỗi vòng lặp.
Kiểm tra#
Chạy job một lần.
Mở Monitor trong Belvador: lượt chạy hiện sau vài giây, kèm kết quả và thời lượng.
Cố ý cho job ném lỗi một lần: lượt chạy ghi Lỗi và có liên kết tới issue.
Không thấy gì? Với debug: true SDK ghi chẩn đoán ra console; BLV_MONITOR_INVALID_SLUG nghĩa là slug không khớp ^[a-z0-9][a-z0-9_-]{0,63}$. Xem Khắc phục sự cố.
Bài viết về chủ đề này
Tất cả bài viếtThấy chỗ sai hoặc thiếu? Gửi cho chúng tôi: hello@belvador.dev