将 gateway-checker/Gateway Checker 统一替换为 dial-server/DiAL - 包名、可执行文件名、API service 标识改为 dial-server - UI 标题改为 DiAL,副标题改为统一拨测平台 - 同步更新测试断言、构建脚本、示例配置和文档
DiAL
基于 Bun + TypeScript 的多类型拨测监控工具。通过 YAML 配置文件定义 HTTP 和命令行拨测目标,后端按配置定时并发拨测,结果持久化到本地 SQLite,前端 Dashboard 展示各目标实时状态、可用率、耗时趋势等。
项目结构
src/
server/
app.ts Bun HTTP 路由(API + 静态资源 + SPA fallback)
config.ts CLI 参数解析
dev.ts 开发期启动入口
server.ts HTTP server 启动
checker/
types.ts 类型定义
config-loader.ts YAML 配置解析与校验
store.ts SQLite 数据存储
fetcher.ts HTTP 拨测执行
command-runner.ts 命令行拨测执行
size.ts 大小单位解析
engine.ts 调度引擎(按 interval 分组、组内并发)
expect/
http.ts HTTP 响应断言
command.ts 命令行输出断言
body.ts HTTP body 断言(JSONPath/XPath/CSS)
failure.ts 失败信息类型
shared/
api.ts 前后端共享 TypeScript 类型
web/ Vite + React 前端 Dashboard
components/ UI 组件(卡片、分组、模态框、状态条等)
constants/ 常量定义(类型映射等)
hooks/ 数据轮询和详情管理 hooks
utils/ 前端工具函数
scripts/ 开发、构建和 smoke test 脚本
tests/ Bun test 测试
openspec/ OpenSpec 变更与规格文档
快速开始
bun install
cp probes.example.yaml probes.yaml
bun run dev probes.yaml
bun run dev 会同时启动 Bun 后端和 Vite 前端。开发期请打开 Vite 前端地址 http://127.0.0.1:5173。
也可以分别运行:
bun run dev:server probes.yaml
bun run dev:web
配置文件
程序通过 YAML 配置文件定义所有运行参数:
server:
host: "127.0.0.1"
port: 3000
dataDir: "/tmp/probes_data"
runtime:
maxConcurrentChecks: 20
defaults:
interval: "5s"
timeout: "10s"
http:
method: GET
maxBodyBytes: "100MB"
command:
maxOutputBytes: "100MB"
targets:
- name: "Baidu"
type: http
http:
url: "https://www.baidu.com"
expect:
status: [200]
maxDurationMs: 10000
- name: "JSON API 示例"
type: http
http:
url: "https://httpbin.org/json"
expect:
status: [200]
headers:
Content-Type:
contains: "application/json"
body:
- contains: "slideshow"
- json:
path: "$.slideshow.title"
equals: "Sample Slide Show"
- name: "HTML 页面示例"
type: http
http:
url: "https://httpbin.org/html"
expect:
status: [200]
body:
- contains: "Moby-Dick"
- xpath:
path: "/html/body/h1/text()"
equals: "Herman Melville - Moby-Dick"
- name: "Nginx 进程检查"
type: command
command:
exec: "pgrep"
args: ["nginx"]
expect:
exitCode: [0]
stdout:
- match: "\\d+"
配置说明
- server: 服务配置(均可省略,使用默认值)
host: 监听地址,默认127.0.0.1port: 监听端口,默认3000dataDir: 数据目录,默认./data
- runtime: 运行时配置
maxConcurrentChecks: 最大并发拨测数,默认20
- defaults: 全局默认值(均可省略)
interval: 拨测间隔,默认30stimeout: 超时时间,默认10shttp: HTTP 类型默认值method: HTTP 方法,默认GETmaxBodyBytes: 响应体最大字节数,默认100MB
command: Command 类型默认值maxOutputBytes: 输出最大字节数,默认100MB
- targets: 拨测目标列表(必填)
name: 目标名称(必填,唯一)type: 目标类型,http或command(必填)group: 分组名称(可选,默认"default")http: HTTP 拨测配置(type 为 http 时必填)url: 目标 URLmethod、headers、body: 请求参数
command: 命令行拨测配置(type 为 command 时必填)exec: 可执行文件名或路径args: 命令行参数列表env: 环境变量覆盖(可选,继承进程环境变量并合并覆盖)cwd: 工作目录(可选,相对于配置文件所在目录解析,默认.)
interval、timeout: 覆盖全局默认值expect: 期望校验status: 可接受的状态码列表(HTTP)exitCode: 可接受的退出码列表(Command)headers: 响应头校验(HTTP,支持equals、contains等操作符)maxDurationMs: 最大耗时阈值(毫秒)body: HTTP 响应体校验(数组,可组合使用)contains: 响应体包含的文本match: 响应体匹配的正则表达式json: JSONPath 提取值比较(path+ 比较操作符)css: CSS 选择器提取 HTML 元素比较xpath: XPath 提取 XML/HTML 节点比较
stdout/stderr: Command 输出校验(数组,同 body 格式)- 比较操作符:
equals(默认)、contains、match(正则)、empty、exists、gte、lte、gt、lt
大小说明:maxBodyBytes 和 maxOutputBytes 支持单位 KB、MB、GB,也可直接使用数字(字节数)。
时长格式支持:30s、5m、500ms
API 端点
| 端点 | 说明 |
|---|---|
GET /health |
健康检查 |
GET /api/summary |
总览统计(total/up/down/lastCheckTime) |
GET /api/targets |
目标列表及最新状态、分组和采样数据 |
GET /api/targets/:id/history?from=ISO&to=ISO&page=1&pageSize=20 |
指定目标的拨测记录(时间范围 + 分页) |
GET /api/targets/:id/trend?from=ISO&to=ISO |
指定目标的按小时聚合趋势 |
响应字段
SummaryResponse: total、up、down、lastCheckTime
TargetStatus: id、name、type(http/command)、target(URL 或命令摘要)、group、interval、latestCheck、stats、recentSamples
RecentSample: timestamp、durationMs、up
CheckResult: timestamp、matched、durationMs、statusDetail、failure
CheckFailure: kind(error/mismatch)、phase、path、expected、actual、message
TargetStats: totalChecks、availability
TrendPoint: hour、avgDurationMs、availability、totalChecks
HistoryResponse: items(CheckResult[])、total、page、pageSize
错误响应
API 错误返回 ApiErrorResponse 格式:
{ "error": "描述信息", "status": 400 }
| 状态码 | 触发场景 |
|---|---|
| 400 | 参数格式错误(无效 ID、from/to 缺失或格式错误、page/pageSize 非正整数) |
| 404 | 目标不存在、API 路由未匹配 |
| 405 | 非 GET 方法请求 API 路由 |
代码质量
bun run lint
bun run format:check
bun run format
bun run check
check依次运行typecheck、lint、format:check和单元测试。
构建 executable
bun run build
构建流程:
- 运行
vite build,输出前端资源到dist/web - 生成临时
.build/static-assets.ts,嵌入 Vite 产物 - 生成临时
.build/server-entry.ts,作为生产入口 - 运行
Bun.build({ compile }),输出dist/dial-server
运行 executable:
./dist/dial-server probes.yaml
运行参数
CLI 只接受一个参数:YAML 配置文件路径。
./dist/dial-server ./probes.yaml
测试
bun run check
bun run verify
check适合日常开发,包含类型检查、lint、格式检查和单元测试。verify先运行check,再重新构建生产 executable 并运行 smoke test。
前后端边界
前端只通过 HTTP 调用后端,API 路径为 /api/*。共享类型放在 src/shared,前端不得 import src/server 的运行时实现。
目标状态判定
单层判定模型,适用于 HTTP 和 Command 两种类型:
- matched: 是否符合 expect 规则(无 expect 时默认为 true)
- UP = matched
- DOWN = NOT matched
执行失败(网络错误、超时、进程崩溃)和 expect 不匹配都统一为 matched=false,通过 failure.kind 区分("error" vs "mismatch")。
已知限制
当前不做告警通知、数据自动清理、拨测目标动态增删、认证鉴权和分布式部署。Command 类型拨测不支持 Windows 环境。