1
0
Files
DiAL/README.md
lanyuanxiaoyao 31fd3a2a43 refactor: 统一 target name/description 可空语义,前端展示 fallback 到 id
- schema: name/description 允许省略或显式 null,TypeBox Union([Null, String])
- 类型: RawTargetConfig/ResolvedTargetBase/子类型/StoredTarget/TargetStatus name 改为 string | null
- checker resolve: name: t.name ?? null,不再 fallback 到 id
- 语义校验: 拒绝空字符串和纯空白 name
- SQLite: targets.name 列改为可空 TEXT
- 前端: 新增 getTargetDisplayName(target) 展示 name ?? id
- 测试: 覆盖 name/description null 全场景,查找改为按 id
- 文档: 更新 README/DEVELOPMENT 和 6 个 openspec specs
2026-05-17 20:12:39 +08:00

268 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DiAL
<p align="center">
<strong>轻量级多类型拨测监控工具</strong>
</p>
<p align="center">
基于 Bun + TypeScript 构建 · YAML 配置驱动 · 内置 Dashboard
</p>
---
DiAL 是一个自托管的拨测监控工具,支持 **HTTP**、**命令行** 和 **数据库** 三种拨测类型。通过 YAML 配置文件定义拨测目标,后端定时并发执行拨测并将结果持久化到本地 SQLite前端 Dashboard 展示各目标的实时状态、可用率和耗时趋势。
**功能亮点:**
- 多种拨测类型HTTPGET/POST/PUT 等、Cmd命令行执行、DBPostgreSQL/MySQL/SQLite
- 丰富的校验规则状态码、响应头、JSONPath、CSS 选择器、XPath、正则匹配、数值比较等
- 响应式 Dashboard实时状态、可用率统计、耗时趋势图、手动/自动刷新
- 多主题支持:系统、明亮、黑暗三种主题模式
- 零外部依赖:数据存储使用 SQLite无需额外数据库服务
## 快速开始
**前置条件:** [Bun](https://bun.sh/) >= 1.0
```bash
# 克隆仓库
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。
## 生产部署
```bash
# 构建
bun run build
# 运行
./dist/dial-server ./probes.yaml
```
构建产物为独立可执行文件,只需一个 YAML 配置文件即可运行。
## 配置文件
程序通过 YAML 配置文件定义所有运行参数,完整示例参见 [`probes.example.yaml`](probes.example.yaml)。
```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"
api_token: "Bearer demo-token"
sqlite_url: "sqlite:///path/to/db.sqlite"
defaults:
interval: "30s"
timeout: "10s"
http:
maxBodyBytes: "10MB"
cmd:
maxOutputBytes: "1MB"
targets:
- id: "baidu-home"
name: "Baidu"
type: http
http:
url: "https://www.baidu.com"
expect:
status: [200]
maxDurationMs: 10000
- id: "json-api"
name: "${env_name} JSON API 示例"
type: http
http:
url: "${base_url}/json"
headers:
Authorization: "${api_token|Bearer fallback-token}"
expect:
status: [200]
headers:
Content-Type:
contains: "application/json"
body:
- json:
path: "$.slideshow.title"
equals: "Sample Slide Show"
- id: "bun-script"
name: "Bun 脚本检查"
type: cmd
cmd:
exec: "bun"
args: ["-e", "console.log('ok')"]
expect:
exitCode: [0]
stdout:
- contains: "ok"
- id: "sqlite-active-users"
name: "SQLite 数据库检查"
type: db
db:
url: "${sqlite_url}"
query: "SELECT COUNT(*) as cnt FROM users WHERE status = 'active'"
expect:
maxDurationMs: 5000
rowCount: { gte: 1 }
rows:
- cnt: { gte: 0 }
```
### 配置说明
#### 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` |
| `http.maxBodyBytes` | 响应体最大字节数 | `100MB` |
| `http.headers` | 默认请求头target 中的 headers 会合并覆盖同名头) | — |
| `cmd.maxOutputBytes` | 输出最大字节数 | `100MB` |
| `cmd.cwd` | 默认工作目录(相对于配置文件所在目录) | `.` |
#### 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`,且不会替换 `id``type` 字段。
#### targets — 拨测目标列表(必填)
每个 target 的通用字段:
| 字段 | 说明 | 必填 |
| ------------- | ------------------------------------------------------------------------------------ | -------------------- |
| `id` | 目标唯一标识,最长 30 字符,支持字母数字、下划线、连字符,不参与变量替换 | 是 |
| `name` | 展示名称,最长 30 字符,支持变量替换,可省略或显式 null前端展示时 null 回退到 `id` | 否 |
| `description` | 目标描述,最长 500 字符,支持变量替换,可省略或显式 null允许空字符串 | 否 |
| `type` | 目标类型:`http``cmd``db` | 是 |
| `group` | 分组名称 | 否,默认 `"default"` |
| `interval` | 覆盖全局拨测间隔 | 否 |
| `timeout` | 覆盖全局超时时间 | 否 |
**HTTP 类型** (`type: http`)
| 字段 | 说明 |
| ------------------- | --------------------------------------- |
| `http.url` | 目标 URL |
| `http.method` | HTTP 方法(覆盖 defaults |
| `http.headers` | 请求头(与 defaults.http.headers 合并) |
| `http.body` | 请求体 |
| `http.ignoreSSL` | 忽略 HTTPS 证书校验,默认 `false` |
| `http.maxRedirects` | 最大重定向跟随次数,默认 `0`(不跟随) |
**Cmd 类型** (`type: cmd`)
| 字段 | 说明 |
| ---------- | -------------------------------------- |
| `cmd.exec` | 可执行文件名或路径 |
| `cmd.args` | 命令行参数列表 |
| `cmd.env` | 环境变量覆盖(继承进程环境变量并合并) |
| `cmd.cwd` | 工作目录(相对于配置文件所在目录) |
**DB 类型** (`type: db`)
| 字段 | 说明 |
| ---------- | ------------------------------------------------------------- |
| `db.url` | 数据库连接字符串,支持 `postgres://``mysql://``sqlite://` |
| `db.query` | SQL 查询语句(不配置时仅测试连接) |
#### expect — 期望校验
| 字段 | 适用类型 | 说明 |
| ------------------- | -------- | ---------------------------------------------------------------- |
| `status` | HTTP | 可接受的状态码列表,支持精确码和范围(如 `"2xx"`);默认 `[200]` |
| `exitCode` | Cmd | 可接受的退出码列表;未指定时不校验 |
| `headers` | HTTP | 响应头校验 |
| `maxDurationMs` | 全部 | 最大耗时阈值(毫秒) |
| `body` | HTTP | 响应体校验(数组,可组合使用,见下方) |
| `stdout` / `stderr` | Cmd | 输出校验(数组,每项一个操作符对象) |
| `rowCount` | DB | 查询返回行数校验(操作符对象) |
| `rows` | DB | 查询结果逐行校验(数组,列名→操作符映射) |
**body 校验项**(数组中可混合使用):
- `contains` — 响应体包含指定文本
- `regex` — 正则匹配(启动期会拒绝存在 ReDoS 风险的模式)
- `json` — JSONPath 提取值比较(`path` 必填,如 `$.slideshow.title`
- `css` — CSS 选择器提取 HTML 元素(`selector` 必填,`attr` 可选提取属性)
- `xpath` — XPath 提取 XML/HTML 节点(`path` 必填,如 `/html/body/h1/text()`
**比较操作符**`equals`(默认)、`contains``match`(正则)、`empty``exists``gte``lte``gt``lt`
**大小说明**`maxBodyBytes``maxOutputBytes` 支持 `KB``MB``GB` 单位,也可直接使用数字。
**时长格式**`500ms``30s``5m``2h``7d`
**JSON Schema**:仓库根目录导出 `probe-config.schema.json`,在 YAML 文件顶部添加 `# yaml-language-server: $schema=./probe-config.schema.json` 即可在编辑器中获得提示和校验。
> **注意:** 配置校验在启动时执行,非法配置会阻止启动并输出错误信息。除动态键值表(`headers`、`env`、`variables`)外,未知字段会导致启动失败,请使用 YAML 注释。
## 目标状态判定
采用单层判定模型:
- **UP** = 拨测结果符合 expect 规则
- **DOWN** = 拨测结果不符合 expect 规则
执行失败(网络错误、超时、进程崩溃)和 expect 不匹配都统一为 DOWN通过 `failure.kind` 区分原因(`"error"` vs `"mismatch"`)。
## 开发
```bash
bun run check # schema:check + typecheck + lint + test
bun run verify # check + build
```
开发相关文档(项目结构、构建、测试、代码规范等)请参阅 [DEVELOPMENT.md](DEVELOPMENT.md)。
## License
MIT