1
0
Files
DiAL/README.md
lanyuanxiaoyao f48e39a615 refactor: 全面重构前端 Dashboard 为 TDesign + TanStack Query 分组表格布局
- 卡片式布局改为分组 PrimaryTable,Modal 改为 Drawer
- 手写 hooks 替换为 TanStack Query(轮询/缓存/条件查询)
- CSS 607行精简至73行,颜色迁移至 TDesign tokens
- 可用率进度条颜色按 10% 一档红→绿渐变
- 新增纯函数测试 34 项全通过(排序/筛选/色阶阈值)
- 同步更新主 specs 并归档变更文档
2026-05-12 01:06:53 +08:00

9.2 KiB
Raw Blame History

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 组件表格、分组、Drawer、状态条等
    constants/      常量定义(列配置、类型映射、排序/筛选/颜色阈值函数)
    hooks/          TanStack Query 数据层useTargetDetail 集成轮询/条件查询)
    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.1
    • port: 监听端口,默认 3000
    • dataDir: 数据目录,默认 ./data
  • runtime: 运行时配置
    • maxConcurrentChecks: 最大并发拨测数,默认 20
  • defaults: 全局默认值(均可省略)
    • interval: 拨测间隔,默认 30s
    • timeout: 超时时间,默认 10s
    • http: HTTP 类型默认值
      • method: HTTP 方法,默认 GET
      • maxBodyBytes: 响应体最大字节数,默认 100MB
    • command: Command 类型默认值
      • maxOutputBytes: 输出最大字节数,默认 100MB
  • targets: 拨测目标列表(必填)
    • name: 目标名称(必填,唯一)
    • type: 目标类型,httpcommand(必填)
    • group: 分组名称(可选,默认 "default"
    • http: HTTP 拨测配置type 为 http 时必填)
      • url: 目标 URL
      • methodheadersbody: 请求参数
    • command: 命令行拨测配置type 为 command 时必填)
      • exec: 可执行文件名或路径
      • args: 命令行参数列表
      • env: 环境变量覆盖(可选,继承进程环境变量并合并覆盖)
      • cwd: 工作目录(可选,相对于配置文件所在目录解析,默认 .
    • intervaltimeout: 覆盖全局默认值
    • expect: 期望校验
      • status: 可接受的状态码列表HTTP
      • exitCode: 可接受的退出码列表Command
      • headers: 响应头校验HTTP支持 equalscontains 等操作符)
      • maxDurationMs: 最大耗时阈值(毫秒)
      • body: HTTP 响应体校验(数组,可组合使用)
        • contains: 响应体包含的文本
        • match: 响应体匹配的正则表达式
        • json: JSONPath 提取值比较(path + 比较操作符)
        • css: CSS 选择器提取 HTML 元素比较
        • xpath: XPath 提取 XML/HTML 节点比较
      • stdout / stderr: Command 输出校验(数组,同 body 格式)
      • 比较操作符:equals(默认)、containsmatch(正则)、emptyexistsgteltegtlt

大小说明:maxBodyBytesmaxOutputBytes 支持单位 KBMBGB,也可直接使用数字(字节数)。

时长格式支持:30s5m500ms

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: totalupdownlastCheckTime

TargetStatus: idnametypehttp/commandtargetURL 或命令摘要)、groupintervallatestCheckstatsrecentSamples

RecentSample: timestampdurationMsup

CheckResult: timestampmatcheddurationMsstatusDetailfailure

CheckFailure: kinderror/mismatchphasepathexpectedactualmessage

TargetStats: totalChecksavailability

TrendPoint: houravgDurationMsavailabilitytotalChecks

HistoryResponse: itemsCheckResult[])、totalpagepageSize

错误响应

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 依次运行 typechecklintformat:check 和单元测试。

构建 executable

bun run build

构建流程:

  1. 运行 vite build,输出前端资源到 dist/web
  2. 生成临时 .build/static-assets.ts,嵌入 Vite 产物
  3. 生成临时 .build/server-entry.ts,作为生产入口
  4. 运行 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 环境。