1
0
Files
DiAL/README.md

24 KiB
Raw Blame History

DiAL

轻量级多类型拨测监控工具

基于 Bun + TypeScript 构建 · YAML 配置驱动 · 内置 Dashboard


DiAL 是一个自托管的拨测监控工具,支持 HTTP命令行数据库TCPUDPICMPLLM 多种拨测类型。通过 YAML 配置文件定义拨测目标,后端定时并发执行拨测并将结果持久化到本地 SQLite前端 Dashboard 展示各目标的实时状态、可用率和耗时趋势。

功能亮点:

  • 多种拨测类型HTTPGET/POST/PUT 等、Cmd命令行执行、DBPostgreSQL/MySQL/SQLite、TCP端口可达性 + Banner 探测、UDP自定义 payload 请求-响应、ICMP存活检测、延迟、丢包率、LLM大模型服务应用层健康检查
  • 丰富的校验规则状态码、响应头、JSONPath、CSS 选择器、XPath、正则匹配、数值比较等
  • 结构化观测数据:检查结果保留按需读取的 HTTP body 预览、TCP/UDP 响应摘要、ICMP 丢包率、CMD 输出预览、LLM token 用量等 observation便于排障和后续分析
  • 响应式 Dashboard实时状态、可用率统计、耗时趋势图、手动/自动刷新、版本号展示
  • 多主题支持:系统、明亮、黑暗三种主题模式
  • 零外部依赖:数据存储使用 SQLite无需额外数据库服务

版本管理

DiAL 使用 package.json.version 作为唯一版本源Dashboard Header 展示当前运行实例版本号(如 v0.1.0)。

版本升迁命令:

bun run version:patch  # 升迁 patch 版本0.1.0 -> 0.1.1
bun run version:minor  # 升迁 minor 版本0.1.0 -> 0.2.0
bun run version:major  # 升迁 major 版本0.1.0 -> 1.0.0
bun run version:set 0.2.0  # 显式设置版本

版本升迁仅更新 package.json,不自动创建 git commit、tag 或 changelog。

应用截图

亮色 暗色
主页 index-light index-dark
详情页 detail-light detail-dark

快速开始

前置条件: Bun >= 1.0

ICMP checker 依赖系统 ping 命令。精简容器镜像需额外安装,例如 Alpine 可安装 iputils-ping

# 克隆仓库
git clone https://github.com/your-org/DiAL.git
cd DiAL

# 安装依赖
bun install

# 复制示例配置并按需修改
cp probes.example.yaml probes.yaml

# 启动开发服务器
bun run dev probes.yaml

bun run dev 会同时启动 Vite 开发服务器(http://127.0.0.1:5173)和 API 服务器(http://127.0.0.1:3000),访问前端地址即可使用 Dashboard。

生产部署

# 构建
bun run build

# 运行
./dist/dial-server ./probes.yaml

构建产物为独立可执行文件,只需一个 YAML 配置文件即可运行。

配置文件

程序通过 YAML 配置文件定义所有运行参数,完整示例参见 probes.example.yaml

配置文件结构

# yaml-language-server: $schema=./probe-config.schema.json

server: # 服务配置(均可省略)
  host: "127.0.0.1"
  port: 3000
  dataDir: "/tmp/probes_data"

runtime: # 运行时配置
  maxConcurrentChecks: 20
  retention: "7d"

variables: # 配置变量(可省略)
  env_name: "生产"
  base_url: "https://api.example.com"

defaults: # 全局默认值(均可省略)
  interval: "30s"
  timeout: "10s"
  # http: ...
  # cmd: ...
  # llm: ...

targets: # 拨测目标列表(必填)
  - id: "baidu-home"
    name: "Baidu"
    type: http
    http:
      url: "https://www.baidu.com"
    expect:
      # ...
  - id: "my-cmd"
    name: "脚本检查"
    type: cmd
    cmd:
      # ...
    expect:
      # ...
  # ... 更多 targets

server — 服务配置

字段 说明 必填 默认值
host 监听地址 127.0.0.1
port 监听端口 3000
dataDir 数据目录,相对路径基于配置文件所在目录解析 ./data

runtime — 运行时配置

字段 说明 必填 默认值
maxConcurrentChecks 最大并发拨测数 20
retention 历史数据保留时长,支持 ms/s/m/h/d 单位 7d

defaults — 全局默认值

字段 说明 必填 默认值
interval 拨测间隔 30s
timeout 超时时间 10s

各 checker 专属的默认配置见对应章节。

variables — 配置变量

variables 是顶层动态键值表key 必须符合 [a-zA-Z_][a-zA-Z0-9_]*value 仅支持 string、number、boolean。target 中的字符串值可引用变量:

  • ${key}:引用 variables 或环境变量
  • ${key|default}:变量和环境变量都不存在时使用默认值,第一个 | 后的内容为默认值
  • $${key}:转义输出字面量 ${key}

解析优先级为 variables -> process.env -> 默认值。字段值完整等于单个变量引用时会保留 number/boolean/string 类型;部分拼接时统一转为字符串。变量替换仅作用于 targets,且不会替换 idtype 字段。

targets — 拨测目标列表(必填)

每个 target 的通用字段:

字段 说明 必填 默认值
id 目标唯一标识,最长 30 字符,支持字母数字、下划线、连字符,不参与变量替换
name 展示名称,最长 30 字符,支持变量替换,可省略或显式 null前端展示时 null 回退到 id
description 目标描述,最长 500 字符,支持变量替换,可省略或显式 null允许空字符串
type 目标类型:httpcmddbtcpudpicmpllm
group 分组名称 default
interval 覆盖全局拨测间隔
timeout 覆盖全局超时时间

HTTP Checkertype: http

全局默认值(defaults.http

字段 说明 必填 默认值
maxBodyBytes 响应体最大字节数 100MB
headers 默认请求头target 中的 headers 会合并覆盖同名头)

配置项

字段 说明 必填 默认值
http.url 目标 URL
http.method HTTP 方法 GET
http.headers 请求头(与 defaults.http.headers 合并)
http.body 请求体
http.ignoreSSL 忽略 HTTPS 证书校验 false
http.maxRedirects 最大重定向跟随次数 0

expect 校验项

字段 说明 必填 默认值
status 可接受的状态码列表,支持精确码和范围(如 "2xx" [200]
headers 响应头校验,使用动态键名和 KeyedExpectations
body 响应体校验,使用 ContentExpectations 数组
durationMs 完整执行耗时校验,使用 ValueMatcher

配置示例

- id: "json-api"
  name: "JSON API 示例"
  type: http
  http:
    url: "https://httpbin.org/json"
    headers:
      Authorization: "Bearer token"
  expect:
    status: [200]
    headers:
      Content-Type:
        contains: "application/json"
    body:
      - json:
          path: "$.slideshow.title"
          equals: "Sample Slide Show"
    durationMs:
      lte: 10000

Cmd Checkertype: cmd

全局默认值(defaults.cmd

字段 说明 必填 默认值
maxOutputBytes 输出最大字节数 100MB
cwd 默认工作目录(相对于配置文件所在目录) .

配置项

字段 说明 必填 默认值
cmd.exec 可执行文件名或路径
cmd.args 命令行参数列表 []
cmd.env 环境变量覆盖(继承进程环境变量并合并)
cmd.cwd 工作目录(相对于配置文件所在目录)

expect 校验项

字段 说明 必填 默认值
exitCode 可接受的退出码列表 [0]
stdout 标准输出校验,使用 ContentExpectations 数组
stderr 标准错误校验,使用 ContentExpectations 数组
durationMs 完整执行耗时校验,使用 ValueMatcher

配置示例

- id: "bun-script"
  name: "Bun 脚本检查"
  type: cmd
  cmd:
    exec: "bun"
    args: ["-e", "console.log('ok')"]
  expect:
    exitCode: [0]
    stdout:
      - contains: "ok"

DB Checkertype: db

配置项

字段 说明 必填 默认值
db.url 数据库连接字符串,支持 postgres://mysql://sqlite://
db.query SQL 查询语句,不配置时仅测试连接

expect 校验项

字段 说明 必填 默认值
rowCount 查询返回行数校验,使用 ValueMatcher
rows 查询结果逐行校验,数组内每行为列名到 KeyedExpectations 的映射
result 完整查询结果 { rows, rowCount } 校验,使用 ContentExpectations 数组
durationMs 完整执行耗时校验,使用 ValueMatcher

配置示例

- id: "sqlite-query"
  name: "SQLite 数据库检查"
  type: db
  db:
    url: "sqlite:///path/to/db.sqlite"
    query: "SELECT COUNT(*) as cnt FROM users WHERE status = 'active'"
  expect:
    durationMs:
      lte: 5000
    rowCount: { gte: 1 }
    rows:
      - cnt: { gte: 0 }

TCP Checkertype: tcp

配置项

字段 说明 必填 默认值
tcp.host 目标主机地址
tcp.port 目标端口1-65535
tcp.readBanner 是否读取服务端 banner false
tcp.bannerReadTimeout banner 读取超时(毫秒) 2000
tcp.maxBannerBytes banner 最大字节数,支持 KB/MB/GB 单位 4KB

expect 校验项

字段 说明 必填 默认值
connected 期望连接结果,true 可达或 false 期望不可达 true
banner Banner 内容校验,使用 ContentExpectations 数组,需开启 tcp.readBanner
durationMs 完整执行耗时校验,使用 ValueMatcher

配置示例

- id: "redis-port"
  name: "Redis 端口可达"
  type: tcp
  tcp:
    host: "127.0.0.1"
    port: 6379
  expect:
    durationMs:
      lte: 3000

UDP Checkertype: udp

全局默认值(defaults.udp

字段 说明 必填 默认值
encoding payload 编码 text
responseEncoding 响应解码 text
maxResponseBytes 响应最大字节数,支持 KB/MB/GB 单位 4KB

配置项

字段 说明 必填 默认值
udp.host 目标主机地址
udp.port 目标端口1-65535
udp.payload 发送数据 ""
udp.encoding payload 编码:texthexbase64 text
udp.responseEncoding 响应解码:texthexbase64 text
udp.maxResponseBytes 响应最大字节数,支持 KB/MB/GB 单位 4KB

expect 校验项

字段 说明 必填 默认值
responded 期望是否收到响应 true
response 响应内容校验,使用 ContentExpectations 数组
responseSize 响应字节数校验,使用 ValueMatcher
sourceHost 响应来源地址校验,使用 ValueMatcher
sourcePort 响应来源端口校验,使用 ValueMatcher
durationMs 完整执行耗时校验,使用 ValueMatcher

配置示例

- id: "udp-heartbeat"
  name: "UDP 心跳检测"
  type: udp
  udp:
    host: "127.0.0.1"
    port: 9000
    payload: "PING"
  expect:
    responded: true
    response:
      - contains: "PONG"
    durationMs:
      lte: 100

ICMP Checkertype: icmp

配置项

字段 说明 必填 默认值
icmp.host 目标主机地址
icmp.count ICMP 包数量,范围 1-100 3
icmp.packetSize ICMP 包大小bytes 56

ICMP checker 通过系统 ping 命令执行 ICMP 探测,支持 Linux、macOS 和 Windows 输出解析。

expect 校验项

字段 说明 必填 默认值
alive 期望主机可达性 true
packetLossPercent 丢包率百分比校验,范围 0-100,使用 ValueMatcher
avgLatencyMs 平均延迟校验,使用 ValueMatcher
maxLatencyMs 最大单次延迟校验,使用 ValueMatcher
durationMs 完整执行耗时校验,使用 ValueMatcher

配置示例

- id: "gateway-icmp"
  name: "网关 ICMP 可达"
  type: icmp
  icmp:
    host: "10.0.0.1"
    count: 3
    packetSize: 56
  expect:
    alive: true
    packetLossPercent:
      lte: 10
    avgLatencyMs:
      lte: 100
    maxLatencyMs:
      lte: 300
    durationMs:
      lte: 5000

LLM Checkertype: llm

全局默认值(defaults.llm

字段 说明 必填 默认值
mode 调用模式
headers 默认请求头
ignoreSSL 忽略 HTTPS 证书校验 false
options 生成选项
providerOptions Provider 专属选项

不支持 providerurlmodelkeyauthTokenprompt

配置项

字段 说明 必填 默认值
llm.provider 模型提供方:openaiopenai-responsesanthropic
llm.url API base URL
llm.model 模型名称
llm.prompt 单轮 prompt
llm.mode 调用模式:http(非流式)或 stream(流式) http
llm.key API key支持 ${VAR} 变量替换 ""
llm.authToken Bearer tokenanthropic providerkey 互斥)
llm.headers 附加请求头(与 defaults.llm.headers 合并)
llm.ignoreSSL 忽略 HTTPS 证书校验 false
llm.options 生成选项(与 defaults.llm.options 合并)
llm.providerOptions Provider 专属选项(与 defaults.llm.providerOptions 合并)

llm.options 支持 maxOutputTokens(默认 16)、temperature(默认 0)、topPtopKpresencePenaltyfrequencyPenaltystopSequencesseed

expect 校验项

字段 说明 必填 默认值
status 可接受的状态码列表,支持精确码和范围(如 "2xx" [200]
headers 响应头校验,使用动态键名和 KeyedExpectations
output 模型输出校验,使用 ContentExpectations 数组
finishReason finish reason 校验,使用 ValueMatcher
rawFinishReason 原始 finish reason 校验,使用 ValueMatcher
usage Token usage 校验(inputTokens/outputTokens/totalTokens matcher
stream 流式断言(completedfirstTokenMs matchermode: stream
durationMs 完整执行耗时校验,使用 ValueMatcher

配置示例

- id: "llm-openai-probe"
  name: "OpenAI 健康检查"
  type: llm
  llm:
    provider: openai
    url: "https://api.openai.com/v1"
    model: "gpt-4o-mini"
    prompt: "Say OK"
    key: "${OPENAI_API_KEY}"
  expect:
    status: [200]
    finishReason: "stop"
    output:
      - contains: "OK"

通用校验规则

ContentExpectations 校验项

bodystdoutstderrbannerresponseoutputresult 均使用数组:

  • contains — 响应体包含指定文本
  • regex — 正则匹配(启动期会拒绝存在 ReDoS 风险的模式)
  • json — JSONPath 提取值比较(path 必填,如 $.slideshow.title
  • css — CSS 选择器提取 HTML 元素(selector 必填,attr 可选提取属性)
  • xpath — XPath 提取 XML/HTML 节点(path 必填,如 /html/body/h1/text()

ValueMatcher

equalscontainsregexemptyexistsgteltegtltequals 支持 JSON 深度相等;regex 固定使用无 flags 正则;提取器未配置 matcher 时等价于 exists: true。ValueMatcher expect 字段也可直接写 string、number、boolean 或 null等价于 { equals: value };数组和对象必须显式写成 { equals: ... }

KeyedExpectations

headersrows 中每行使用的校验结构,支持 ValueMatcher 的全部字段。

补充说明

  • 大小说明maxBodyBytesmaxOutputBytesmaxResponseBytesmaxBannerBytes 支持 KBMBGB 单位,也可直接使用数字
  • 时长格式500ms30s5m2h7d
  • JSON Schema:仓库根目录导出 probe-config.schema.json,在 YAML 文件顶部添加 # yaml-language-server: $schema=./probe-config.schema.json 即可在编辑器中获得提示和校验
  • 旧字段移除maxDurationMsmaxPacketLossmaxAvgLatencyMsmaxMaxLatencyMs 和旧正则字段 match 已移除,请分别改用 durationMs、ICMP matcher 字段和 regex

注意: 配置校验在启动时执行,非法配置会阻止启动并输出错误信息。除动态键值表(headersenvvariables)外,未知字段会导致启动失败,请使用 YAML 注释。

目标状态判定

采用单层判定模型:

  • UP = 拨测结果符合 expect 规则
  • DOWN = 拨测结果不符合 expect 规则

执行失败(网络错误、超时、进程崩溃)和 expect 不匹配都统一为 DOWN通过 failure.kind 区分原因("error" vs "mismatch")。

API 返回的检查结果包含 detailobservationdetail 是后端按 checker 类型从结构化 observation 动态生成的人可读摘要,observation 保存该次检查的结构化观测数据。detail 不写入 SQLite存储层仅持久化 observation JSON、failure JSON、匹配状态、耗时和时间戳。

开发

bun run check   # schema:check + typecheck + lint + test
bun run verify  # check + build

开发相关文档(项目结构、构建、测试、代码规范等)请参阅 DEVELOPMENT.md

License

Apache-2.0