Bỏ qua tới nội dung
Mục lục

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.

Bản Markdown
Trong bài này

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àmDù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#

src/routes/api/jobs/nightly-invoices.ts
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#

src/index.ts
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:

  1. Gửi in_progress khi fn bắt đầu.

  2. Khi fn trả về (hoặc promise hoàn tất), gửi ok kèm thời lượng.

  3. Khi fn né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ửi error. 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:

TypeScript
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):

TypeScript
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ọnKiểuMặ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)
timezonetên IANA, ví dụ "Asia/Ho_Chi_Minh""UTC"
checkinMarginphút5
maxRuntimephút, tối đa 1008030
failureIssueThresholdsố lượt liên tiếp1
recoveryThresholdsố lượt liên tiếp1
environmentmôi trường của lượt chạy nàyenvironment 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:

TypeScript
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#

  1. Chạy job một lần.

  2. 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.

  3. 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ết

Thấy chỗ sai hoặc thiếu? Gửi cho chúng tôi: hello@belvador.dev