feat: DNS checker,自研 codec/transport,支持 system/server 双模式,UDP/TCP + TC fallback
This commit is contained in:
127
README.md
127
README.md
@@ -10,11 +10,11 @@
|
||||
|
||||
---
|
||||
|
||||
DiAL 是一个自托管的拨测监控工具,支持 **HTTP**、**命令行**、**数据库**、**TCP**、**UDP**、**ICMP** 和 **LLM** 多种拨测类型。通过 YAML 配置文件定义拨测目标,后端定时并发执行拨测并将结果持久化到本地 SQLite,前端 Dashboard 展示各目标的实时状态、可用率和耗时趋势。
|
||||
DiAL 是一个自托管的拨测监控工具,支持 **HTTP**、**命令行**、**数据库**、**TCP**、**UDP**、**DNS**、**ICMP** 和 **LLM** 多种拨测类型。通过 YAML 配置文件定义拨测目标,后端定时并发执行拨测并将结果持久化到本地 SQLite,前端 Dashboard 展示各目标的实时状态、可用率和耗时趋势。
|
||||
|
||||
**功能亮点:**
|
||||
|
||||
- 多种拨测类型:HTTP(GET/POST/PUT 等)、Cmd(命令行执行)、DB(PostgreSQL/MySQL/SQLite)、TCP(端口可达性 + Banner 探测)、UDP(自定义 payload 请求-响应)、ICMP(存活检测、延迟、丢包率)、LLM(大模型服务应用层健康检查)
|
||||
- 多种拨测类型:HTTP(GET/POST/PUT 等)、Cmd(命令行执行)、DB(PostgreSQL/MySQL/SQLite)、TCP(端口可达性 + Banner 探测)、UDP(自定义 payload 请求-响应)、DNS(本机解析检查 + DNS server 深度拨测)、ICMP(存活检测、延迟、丢包率)、LLM(大模型服务应用层健康检查)
|
||||
- 丰富的校验规则:状态码、响应头、JSONPath、CSS 选择器、XPath、正则匹配、数值比较等
|
||||
- 结构化观测数据:检查结果保留按需读取的 HTTP body 预览、TCP/UDP 响应摘要、ICMP 丢包率、CMD 输出预览、LLM token 用量等 observation,便于排障和后续分析
|
||||
- 响应式 Dashboard:实时状态、可用率统计、动态粒度趋势图(avg/P95 + 状态条)、手动/自动刷新、版本号展示
|
||||
@@ -269,7 +269,7 @@ targets: # 拨测目标列表(必填)
|
||||
| `id` | 目标唯一标识,最长 30 字符,支持字母数字、下划线、连字符,不参与变量替换 | 是 | |
|
||||
| `name` | 展示名称,最长 30 字符,支持变量替换,可省略或显式 null;前端展示时 null 回退到 `id` | 否 | |
|
||||
| `description` | 目标描述,最长 500 字符,支持变量替换,可省略或显式 null,允许空字符串 | 否 | |
|
||||
| `type` | 目标类型:`http`、`cmd`、`db`、`tcp`、`udp`、`icmp`、`llm` | 是 | |
|
||||
| `type` | 目标类型:`http`、`cmd`、`db`、`tcp`、`udp`、`dns`、`icmp`、`llm` | 是 | |
|
||||
| `group` | 分组名称 | 否 | `default` |
|
||||
| `interval` | 拨测间隔,未配置时使用内置默认值 `30s` | 否 | `30s` |
|
||||
| `timeout` | 超时时间,未配置时使用内置默认值 `10s` | 否 | `10s` |
|
||||
@@ -523,6 +523,127 @@ ICMP checker 通过系统 `ping` 命令执行 ICMP 探测,支持 Linux、macOS
|
||||
|
||||
---
|
||||
|
||||
### DNS Checker(`type: dns`)
|
||||
|
||||
DNS Checker 支持两种解析模式,通过 `dns.resolver` 字段区分:
|
||||
|
||||
- **`system` 模式**:使用本机 DNS 解析器检查域名是否能解析到预期地址,输出有限 observation。
|
||||
- **`server` 模式**:直接向指定 DNS server 发起 UDP/TCP 深度拨测,检查 DNS 协议级响应(RCODE、TTL、flags、记录值等)。
|
||||
|
||||
#### `dns.resolver: system` 配置项
|
||||
|
||||
| 字段 | 说明 | 必填 | 默认值 |
|
||||
| -------------- | ---------- | ---- | -------- |
|
||||
| `dns.resolver` | 解析模式 | 是 | `system` |
|
||||
| `dns.name` | 待解析域名 | 是 | |
|
||||
| `dns.family` | 地址族 | 否 | `any` |
|
||||
|
||||
`family` 可选值:`any`(返回 IPv4 和 IPv6)、`ipv4`(仅 IPv4)、`ipv6`(仅 IPv6)。
|
||||
|
||||
**system 模式 expect 校验项**
|
||||
|
||||
| 字段 | 说明 | 断言模型 |
|
||||
| ------------ | -------------------- | --------------------------------- |
|
||||
| `values` | 解析结果地址集合断言 | DNS 集合(include/exclude/exact) |
|
||||
| `valueCount` | 解析结果数量 | ValueMatcher |
|
||||
| `durationMs` | 解析耗时 | ValueMatcher |
|
||||
|
||||
**示例**:
|
||||
|
||||
```yaml
|
||||
- id: "dns-system-api"
|
||||
name: "本机 DNS 解析"
|
||||
type: dns
|
||||
dns:
|
||||
resolver: system
|
||||
name: "api.example.com"
|
||||
family: any
|
||||
expect:
|
||||
values:
|
||||
exact:
|
||||
- "203.0.113.10"
|
||||
durationMs:
|
||||
lte: 500
|
||||
```
|
||||
|
||||
#### `dns.resolver: server` 配置项
|
||||
|
||||
| 字段 | 说明 | 必填 | 默认值 |
|
||||
| ---------------------- | --------------------------------- | ---- | -------- |
|
||||
| `dns.resolver` | 解析模式 | 是 | `server` |
|
||||
| `dns.server` | DNS server 地址 | 是 | |
|
||||
| `dns.name` | 查询域名 | 是 | |
|
||||
| `dns.port` | DNS server 端口 | 否 | `53` |
|
||||
| `dns.protocol` | 传输协议:`udp` / `tcp` | 否 | `udp` |
|
||||
| `dns.recordType` | DNS 记录类型 | 否 | `A` |
|
||||
| `dns.recursionDesired` | 是否设置 RD flag | 否 | `true` |
|
||||
| `dns.tcpFallback` | UDP 响应 TC=1 时是否 TCP fallback | 否 | `true` |
|
||||
| `dns.maxResponseBytes` | 响应最大字节数 | 否 | `4KB` |
|
||||
|
||||
`recordType` 可选值:`A`、`AAAA`、`CNAME`、`NS`、`MX`、`TXT`、`SOA`、`SRV`、`CAA`、`PTR`。
|
||||
|
||||
**server 模式 expect 校验项**
|
||||
|
||||
| 字段 | 说明 | 断言模型 |
|
||||
| -------------------- | ---------------------------------- | --------------------------------- |
|
||||
| `responded` | 是否收到 DNS response | boolean |
|
||||
| `rcode` | 期望 RCODE 列表(如 `NOERROR`) | string[] |
|
||||
| `values` | 目标类型记录值集合断言 | DNS 集合(include/exclude/exact) |
|
||||
| `valueCount` | 目标类型记录数量 | ValueMatcher |
|
||||
| `answerCount` | answer section 总记录数 | ValueMatcher |
|
||||
| `ttlMin` | answer 中最小 TTL | ValueMatcher |
|
||||
| `ttlMax` | answer 中最大 TTL | ValueMatcher |
|
||||
| `authoritative` | AA flag | boolean |
|
||||
| `recursionAvailable` | RA flag | boolean |
|
||||
| `truncated` | TC flag | boolean |
|
||||
| `authenticatedData` | AD flag | boolean |
|
||||
| `result` | 完整结构化响应的 JSONPath 兜底断言 | ContentExpectations |
|
||||
| `durationMs` | 完整查询耗时 | ValueMatcher |
|
||||
|
||||
**示例**:
|
||||
|
||||
```yaml
|
||||
- id: "dns-server-api"
|
||||
name: "Cloudflare DNS A 记录"
|
||||
type: dns
|
||||
dns:
|
||||
resolver: server
|
||||
server: "1.1.1.1"
|
||||
port: 53
|
||||
protocol: udp
|
||||
name: "api.example.com"
|
||||
recordType: A
|
||||
expect:
|
||||
rcode: ["NOERROR"]
|
||||
values:
|
||||
include:
|
||||
- "203.0.113.10"
|
||||
ttlMin:
|
||||
gte: 60
|
||||
durationMs:
|
||||
lte: 200
|
||||
|
||||
- id: "dns-nxdomain-check"
|
||||
name: "负向 DNS 检查"
|
||||
type: dns
|
||||
dns:
|
||||
resolver: server
|
||||
server: "1.1.1.1"
|
||||
name: "nxdomain.example.com"
|
||||
recordType: A
|
||||
expect:
|
||||
rcode: ["NXDOMAIN"]
|
||||
```
|
||||
|
||||
**Notes**:
|
||||
|
||||
- 未配置 expect 时,`system` 模式默认要求解析成功且 `valueCount > 0`,`server` 模式默认要求 `NOERROR + valueCount > 0`。
|
||||
- 显式配置非 `NOERROR` rcode(如 `NXDOMAIN`)时,不自动要求 `valueCount > 0`。
|
||||
- `values.exact` 忽略返回顺序(集合匹配);对 A/AAAA 查询,CNAME 链不计入 `values`,单独放入 `cnameChain`
|
||||
- `values` 按记录类型规范化为字符串,格式:MX=`"10 mail.example.com"`、SOA=空格分隔字段、SRV=`"10 60 443 server.example.com"`、CAA=`"0 issue letsencrypt.org"` 等。
|
||||
|
||||
---
|
||||
|
||||
### LLM Checker(`type: llm`)
|
||||
|
||||
**配置项**
|
||||
|
||||
Reference in New Issue
Block a user