1
0
Files
DiAL/README.md
lanyuanxiaoyao bce0f8e7a8 feat: 增强 HTTP checker 鲁棒性 — 严格配置校验、完整耗时、流式body、重定向与编码完善
启动期校验: 新增 validate.ts 对 HTTP config/expect/body rule/operator 全方位严格校验
执行语义: body 改为 Web Stream 流式超限中止,durationMs 覆盖完整执行
错误归属: status/header 失败不读 body,phase 分层 request/body,early duration skip body
重定向: 跟随前释放 body,POST/303 改 GET 清理 header,跨 origin 剥离敏感 header
编码: 支持 quoted charset,未知编码返回结构化解码错误
文档: README match→regex+durationMs,DEVELOPMENT 执行流程与错误归属
测试: +63 测试覆盖全部新增场景,325 pass 0 fail
规格: 同步 probe-config/probe-engine/expect-body-checkers 3 个 delta spec
2026-05-13 08:00:05 +08:00

205 lines
7.5 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
基于 Bun + TypeScript 的多类型拨测监控工具。通过 YAML 配置文件定义 HTTP 和命令行拨测目标,后端按配置定时并发拨测,结果持久化到本地 SQLite前端 Dashboard 展示各目标实时状态、可用率、耗时趋势等。
## 快速开始
```bash
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`
也可以分别运行:
```bash
bun run dev:server probes.yaml
bun run dev:web
```
## 配置文件
程序通过 YAML 配置文件定义所有运行参数:
```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`,支持 `GET``HEAD``POST``PUT``PATCH``DELETE``OPTIONS`
- `maxBodyBytes`: 响应体最大字节数,默认 `100MB`
- `command`: Command 类型默认值
- `maxOutputBytes`: 输出最大字节数,默认 `100MB`
- **targets**: 拨测目标列表(必填)
- `name`: 目标名称(必填,唯一)
- `type`: 目标类型,`http``command`(必填)
- `group`: 分组名称(可选,默认 `"default"`
- `http`: HTTP 拨测配置type 为 http 时必填)
- `url`: 目标 URL
- `method``headers``body`: 请求参数
- `ignoreSSL`: 是否忽略 HTTPS 证书校验,默认 `false`,用于自签名或私有证书服务
- `maxRedirects`: 最大重定向跟随次数,默认 `0`(不跟随重定向)
- `command`: 命令行拨测配置type 为 command 时必填)
- `exec`: 可执行文件名或路径
- `args`: 命令行参数列表
- `env`: 环境变量覆盖(可选,继承进程环境变量并合并覆盖)
- `cwd`: 工作目录(可选,相对于配置文件所在目录解析,默认 `.`
- `interval``timeout`: 覆盖全局默认值
- `expect`: 期望校验
- `status`: 可接受的状态码列表HTTP支持精确状态码和范围模式`"2xx"`)混合配置
- `exitCode`: 可接受的退出码列表Command
- `headers`: 响应头校验HTTP支持 `equals``contains` 等操作符)
- `maxDurationMs`: 最大耗时阈值毫秒HTTP 类型覆盖完整执行(含重定向、响应体读取和 expect 校验)
- `body`: HTTP 响应体校验(数组,可组合使用)
- `contains`: 响应体包含的文本
- `regex`: 响应体匹配的正则表达式
- `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` 格式:
```json
{ "error": "描述信息", "status": 400 }
```
| 状态码 | 触发场景 |
| ------ | ----------------------------------------------------------------------- |
| 400 | 参数格式错误(无效 ID、from/to 缺失或格式错误、page/pageSize 非正整数) |
| 404 | 目标不存在、API 路由未匹配 |
| 405 | 非 GET 方法请求 API 路由 |
## 运行参数
CLI 只接受一个参数YAML 配置文件路径。
```bash
./dist/dial-server ./probes.yaml
```
## 目标状态判定
单层判定模型,适用于 HTTP 和 Command 两种类型:
- **matched**: 是否符合 expect 规则HTTP 无 expect 时默认检查 status 200
- **UP** = matched
- **DOWN** = NOT matched
执行失败(网络错误、超时、进程崩溃)和 expect 不匹配都统一为 `matched=false`,通过 `failure.kind` 区分(`"error"` vs `"mismatch"`)。
---
> 开发相关文档(项目结构、构建、测试、代码规范等)请参阅 [DEVELOPMENT.md](DEVELOPMENT.md)。