1
0

docs: 重构文档体系

This commit is contained in:
2026-05-24 20:18:18 +08:00
parent 483cdc596b
commit a6504d5a62
28 changed files with 2030 additions and 2155 deletions

View File

@@ -0,0 +1,37 @@
# Checker 参考
Checker 是 DiAL 的拨测执行单元。每个 target 通过 `type` 选择一个 checker并配置对应的专属字段和 `expect` 规则。
## 支持的类型
| 类型 | 用途 | 文档 |
| ------ | -------------------------------------- | --------------- |
| `http` | HTTP/HTTPS 应用层健康检查 | [HTTP](http.md) |
| `cmd` | 执行本地命令或脚本 | [Cmd](cmd.md) |
| `db` | PostgreSQL/MySQL/SQLite 连接和查询检查 | [DB](db.md) |
| `tcp` | TCP 端口可达性和 banner 探测 | [TCP](tcp.md) |
| `udp` | UDP payload 请求-响应检查 | [UDP](udp.md) |
| `icmp` | 基于系统 `ping` 的存活、延迟、丢包检查 | [ICMP](icmp.md) |
| `dns` | 本机解析或指定 DNS server 协议级检查 | [DNS](dns.md) |
| `llm` | 大模型服务应用层健康检查 | [LLM](llm.md) |
## 选择建议
| 目标 | 推荐 checker |
| ---------------------------------- | ------------ |
| Web API、网页、HTTP 状态码或响应体 | `http` |
| 本机脚本、外部命令、CLI 工具 | `cmd` |
| 数据库连接或查询结果 | `db` |
| 端口是否可连接、服务 banner | `tcp` |
| UDP 服务响应或简单心跳 | `udp` |
| 主机可达性、延迟、丢包率 | `icmp` |
| 域名解析值、DNS RCODE、TTL、flags | `dns` |
| LLM API 是否可用、输出是否符合预期 | `llm` |
## 通用字段
所有 checker 都共享 target 通用字段,见 [配置文件](../configuration.md#targets-通用字段)。
## 通用断言模型
各 checker 的 `expect` 字段复用 `ValueMatcher``ContentExpectations``KeyedExpectations`。详情见 [校验规则](../expectations.md)。

38
docs/user/checkers/cmd.md Normal file
View File

@@ -0,0 +1,38 @@
# Cmd Checker
`type: cmd` 用于执行本地命令或脚本并校验退出码、stdout、stderr 和耗时。
## 配置项
| 字段 | 说明 | 必填 | 默认值 |
| ---------- | ------------------------------------ | ---- | ------ |
| `cmd.exec` | 可执行文件名或路径 | 是 | 无 |
| `cmd.args` | 命令行参数列表 | 否 | `[]` |
| `cmd.env` | 环境变量覆盖,继承进程环境变量并合并 | 否 | 无 |
| `cmd.cwd` | 工作目录,相对于配置文件所在目录 | 否 | 无 |
## expect 校验项
| 字段 | 说明 | 必填 | 默认值 |
| ------------ | --------------------------------------------- | ---- | ------ |
| `exitCode` | 可接受的退出码列表 | 否 | `[0]` |
| `stdout` | 标准输出校验,使用 `ContentExpectations` 数组 | 否 | 无 |
| `stderr` | 标准错误校验,使用 `ContentExpectations` 数组 | 否 | 无 |
| `durationMs` | 完整执行耗时校验,使用 `ValueMatcher` | 否 | 无 |
## 示例
```yaml
- id: "bun-script"
name: "Bun 脚本检查"
type: cmd
cmd:
exec: "bun"
args: ["-e", "console.log('ok')"]
expect:
exitCode: [0]
stdout:
- contains: "ok"
```
Docker 官方镜像不内置常见外部命令。容器内使用 CMD checker 时,按需通过派生镜像安装依赖命令。

38
docs/user/checkers/db.md Normal file
View File

@@ -0,0 +1,38 @@
# DB Checker
`type: db` 用于数据库连接和查询结果检查,支持 PostgreSQL、MySQL 和 SQLite。
## 配置项
| 字段 | 说明 | 必填 | 默认值 |
| ---------- | ------------------------------------------------------------- | ---- | ------ |
| `db.url` | 数据库连接字符串,支持 `postgres://``mysql://``sqlite://` | 是 | 无 |
| `db.query` | SQL 查询语句,不配置时仅测试连接 | 否 | 无 |
## expect 校验项
| 字段 | 说明 | 必填 | 默认值 |
| ------------ | ----------------------------------------------------------------------- | ---- | ------ |
| `rowCount` | 查询返回行数校验,使用 `ValueMatcher` | 否 | 无 |
| `rows` | 查询结果逐行校验,数组内每行为列名到 `KeyedExpectations` 的映射 | 否 | 无 |
| `result` | 完整查询结果 `{ rows, rowCount }` 校验,使用 `ContentExpectations` 数组 | 否 | 无 |
| `durationMs` | 完整执行耗时校验,使用 `ValueMatcher` | 否 | 无 |
## 示例
```yaml
- 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
```

104
docs/user/checkers/dns.md Normal file
View File

@@ -0,0 +1,104 @@
# DNS Checker
`type: dns` 支持两种解析模式:本机解析器检查和指定 DNS server 协议级检查。
## resolver 模式
| 模式 | 说明 |
| -------- | ----------------------------------------------------------------------------- |
| `system` | 使用本机 DNS 解析器检查域名是否能解析到预期地址 |
| `server` | 直接向指定 DNS server 发起 UDP/TCP 深度拨测,检查 RCODE、TTL、flags、记录值等 |
## `dns.resolver: system` 配置项
| 字段 | 说明 | 必填 | 默认值 |
| -------------- | ----------------------------- | ---- | -------- |
| `dns.resolver` | 解析模式 | 是 | `system` |
| `dns.name` | 待解析域名 | 是 | 无 |
| `dns.family` | 地址族:`any``ipv4``ipv6` | 否 | `any` |
### 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"
name: "api.example.com"
recordType: A
expect:
rcode: ["NOERROR"]
values:
include:
- "203.0.113.10"
ttlMin:
gte: 60
durationMs:
lte: 200
```
## 注意事项
- 未配置 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"`SRV 为 `"10 60 443 server.example.com"`

View File

@@ -0,0 +1,48 @@
# HTTP Checker
`type: http` 用于 HTTP/HTTPS 应用层健康检查。
## 配置项
| 字段 | 说明 | 必填 | 默认值 |
| ------------------- | ------------------- | ---- | ------- |
| `http.url` | 目标 URL | 是 | 无 |
| `http.method` | HTTP 方法 | 否 | `GET` |
| `http.headers` | 请求头 | 否 | 无 |
| `http.body` | 请求体 | 否 | 无 |
| `http.ignoreSSL` | 忽略 HTTPS 证书校验 | 否 | `false` |
| `http.maxRedirects` | 最大重定向跟随次数 | 否 | `0` |
## expect 校验项
| 字段 | 说明 | 必填 | 默认值 |
| ------------ | -------------------------------------------------- | ---- | ------- |
| `status` | 可接受的状态码列表,支持精确码和范围(如 `"2xx"` | 否 | `[200]` |
| `headers` | 响应头校验,使用 `KeyedExpectations` | 否 | 无 |
| `body` | 响应体校验,使用 `ContentExpectations` 数组 | 否 | 无 |
| `durationMs` | 完整执行耗时校验,使用 `ValueMatcher` | 否 | 无 |
## 示例
```yaml
- 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
```
HTTP checker 的 `durationMs` 覆盖完整执行,包括重定向、按需响应体读取、解码和 expect 校验。未配置 body expectation、status 失败或 headers 失败时不会读取 body。

View File

@@ -0,0 +1,45 @@
# ICMP Checker
`type: icmp` 使用系统 `ping` 命令执行 ICMP 探测,支持 Linux、macOS 和 Windows 输出解析。
## 配置项
| 字段 | 说明 | 必填 | 默认值 |
| ----------------- | ------------------------- | ---- | ------ |
| `icmp.host` | 目标主机地址 | 是 | 无 |
| `icmp.count` | ICMP 包数量,范围 `1-100` | 否 | `3` |
| `icmp.packetSize` | ICMP 包大小bytes | 否 | `56` |
## expect 校验项
| 字段 | 说明 | 必填 | 默认值 |
| ------------------- | --------------------------------------------------- | ---- | ------ |
| `alive` | 期望主机可达性 | 否 | `true` |
| `packetLossPercent` | 丢包率百分比校验,范围 `0-100`,使用 `ValueMatcher` | 否 | 无 |
| `avgLatencyMs` | 平均延迟校验,使用 `ValueMatcher` | 否 | 无 |
| `maxLatencyMs` | 最大单次延迟校验,使用 `ValueMatcher` | 否 | 无 |
| `durationMs` | 完整执行耗时校验,使用 `ValueMatcher` | 否 | 无 |
## 示例
```yaml
- 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
```
容器中运行 ICMP checker 通常需要 `--cap-add=NET_RAW`,详情见 [部署文档](../deployment.md#icmp-权限)。

53
docs/user/checkers/llm.md Normal file
View File

@@ -0,0 +1,53 @@
# LLM Checker
`type: llm` 用于大模型服务应用层健康检查。
## 配置项
| 字段 | 说明 | 必填 | 默认值 |
| --------------------- | ----------------------------------------------------- | ---- | ------- |
| `llm.provider` | 模型提供方:`openai``openai-responses``anthropic` | 是 | 无 |
| `llm.url` | API base URL | 是 | 无 |
| `llm.model` | 模型名称 | 是 | 无 |
| `llm.prompt` | 单轮 prompt | 是 | 无 |
| `llm.mode` | 调用模式:`http``stream` | 否 | `http` |
| `llm.key` | API key支持 `${VAR}` 变量替换 | 否 | `""` |
| `llm.authToken` | Bearer token`anthropic` provider`key` 互斥 | 否 | 无 |
| `llm.headers` | 附加请求头 | 否 | 无 |
| `llm.ignoreSSL` | 忽略 HTTPS 证书校验 | 否 | `false` |
| `llm.options` | 生成选项 | 否 | 无 |
| `llm.providerOptions` | Provider 专属选项 | 否 | 无 |
`llm.options` 支持 `maxOutputTokens`(默认 `16`)、`temperature`(默认 `0`)、`topP``topK``presencePenalty``frequencyPenalty``stopSequences``seed`
## expect 校验项
| 字段 | 说明 | 必填 | 默认值 |
| ----------------- | --------------------------------------------------------------------------- | ---- | ------- |
| `status` | 可接受的状态码列表,支持精确码和范围(如 `"2xx"` | 否 | `[200]` |
| `headers` | 响应头校验,使用 `KeyedExpectations` | 否 | 无 |
| `output` | 模型输出校验,使用 `ContentExpectations` 数组 | 否 | 无 |
| `finishReason` | finish reason 校验,使用 `ValueMatcher` | 否 | 无 |
| `rawFinishReason` | 原始 finish reason 校验,使用 `ValueMatcher` | 否 | 无 |
| `usage` | Token usage 校验,支持 `inputTokens``outputTokens``totalTokens` matcher | 否 | 无 |
| `stream` | 流式断言,支持 `completed``firstTokenMs` matcher`mode: stream` | 否 | 无 |
| `durationMs` | 完整执行耗时校验,使用 `ValueMatcher` | 否 | 无 |
## 示例
```yaml
- 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"
```

35
docs/user/checkers/tcp.md Normal file
View File

@@ -0,0 +1,35 @@
# TCP Checker
`type: tcp` 用于 TCP 端口可达性和可选 banner 探测。
## 配置项
| 字段 | 说明 | 必填 | 默认值 |
| ----------------------- | --------------------------------------------- | ---- | ------- |
| `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` | 否 | 无 |
## 示例
```yaml
- id: "redis-port"
name: "Redis 端口可达"
type: tcp
tcp:
host: "127.0.0.1"
port: 6379
expect:
durationMs:
lte: 3000
```

43
docs/user/checkers/udp.md Normal file
View File

@@ -0,0 +1,43 @@
# UDP Checker
`type: udp` 用于 UDP payload 请求-响应检查。
## 配置项
| 字段 | 说明 | 必填 | 默认值 |
| ---------------------- | ------------------------------------------ | ---- | ------ |
| `udp.host` | 目标主机地址 | 是 | 无 |
| `udp.port` | 目标端口,范围 `1-65535` | 是 | 无 |
| `udp.payload` | 发送数据 | 否 | `""` |
| `udp.encoding` | payload 编码:`text``hex``base64` | 否 | `text` |
| `udp.responseEncoding` | 响应解码:`text``hex``base64` | 否 | `text` |
| `udp.maxResponseBytes` | 响应最大字节数,支持 `KB``MB``GB` 单位 | 否 | `4KB` |
## expect 校验项
| 字段 | 说明 | 必填 | 默认值 |
| -------------- | --------------------------------------------- | ---- | ------ |
| `responded` | 期望是否收到响应 | 否 | `true` |
| `response` | 响应内容校验,使用 `ContentExpectations` 数组 | 否 | 无 |
| `responseSize` | 响应字节数校验,使用 `ValueMatcher` | 否 | 无 |
| `sourceHost` | 响应来源地址校验,使用 `ValueMatcher` | 否 | 无 |
| `sourcePort` | 响应来源端口校验,使用 `ValueMatcher` | 否 | 无 |
| `durationMs` | 完整执行耗时校验,使用 `ValueMatcher` | 否 | 无 |
## 示例
```yaml
- 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
```

135
docs/user/configuration.md Normal file
View File

@@ -0,0 +1,135 @@
# 配置文件
DiAL 通过 YAML 配置文件定义运行参数和拨测目标。完整可运行示例参见 [`../../probes.example.yaml`](../../probes.example.yaml)。配置 JSON Schema 位于 [`../../probe-config.schema.json`](../../probe-config.schema.json)。
## 配置结构
```yaml
# yaml-language-server: $schema=./probe-config.schema.json
server:
listen:
host: "127.0.0.1"
port: "${server_port}"
storage:
dataDir: "/tmp/probes_data"
retention: "${retention}"
logging:
level: "${log_level|info}"
file:
path: "<dataDir>/logs/dial.log"
probes:
execution:
maxConcurrentChecks: "${max_checks}"
variables:
server_port: 3000
retention: "7d"
max_checks: 20
default_interval: "30s"
default_timeout: "10s"
targets:
- id: "baidu-home"
name: "Baidu"
type: http
interval: "${default_interval}"
timeout: "${default_timeout}"
http:
url: "https://www.baidu.com"
expect:
status: [200]
```
## server.listen
| 字段 | 说明 | 必填 | 默认值 |
| ------ | -------- | ---- | ----------- |
| `host` | 监听地址 | 否 | `127.0.0.1` |
| `port` | 监听端口 | 否 | `3000` |
## server.storage
| 字段 | 说明 | 必填 | 默认值 |
| ----------- | ---------------------------------------------------- | ---- | -------- |
| `dataDir` | 数据目录,相对路径基于配置文件所在目录解析 | 否 | `./data` |
| `retention` | 历史数据保留时长,支持 `ms``s``m``h``d` 单位 | 否 | `7d` |
## probes.execution
| 字段 | 说明 | 必填 | 默认值 |
| --------------------- | -------------- | ---- | ------ |
| `maxConcurrentChecks` | 最大并发拨测数 | 否 | `20` |
## server.logging
| 字段 | 说明 | 必填 | 默认值 |
| ---------------------------------------- | ---------------------------------------------- | ---- | ------------------------- |
| `server.logging.level` | 全局日志等级console 和 file 未指定时继承此值 | 否 | `info` |
| `server.logging.console.level` | 控制台日志等级 | 否 | 继承 `level` |
| `server.logging.file.level` | 文件日志等级 | 否 | 继承 `level` |
| `server.logging.file.path` | 日志文件路径,相对路径基于配置文件目录解析 | 否 | `<dataDir>/logs/dial.log` |
| `server.logging.file.rotation.size` | 按大小滚动,支持 `KB``MB``GB` 单位 | 否 | `50MB` |
| `server.logging.file.rotation.frequency` | 按时间滚动:`hourly``daily``weekly` | 否 | `daily` |
| `server.logging.file.rotation.maxFiles` | 保留的归档文件数量,不含活跃日志 | 否 | `14` |
日志等级支持:`trace``debug``info``warn``error``fatal`
控制台始终输出 pretty 格式,文件始终输出 JSONL 格式并支持滚动。`rotation.size``rotation.frequency` 任一条件触发即滚动。
## 内置默认值
| 字段 | 默认值 |
| ---------- | ------ |
| `interval` | `30s` |
| `timeout` | `10s` |
各 checker 专属默认值见 [Checker 参考](checkers/README.md)。
## variables
`variables` 是顶层动态键值表key 必须符合 `[a-zA-Z_][a-zA-Z0-9_]*`value 仅支持 string、number、boolean。`server``probes``targets` 中的字符串值可引用变量。
| 语法 | 说明 |
| --------- | ------------------------- | ------------------------------------------ |
| `${key}` | 引用 variables 或环境变量 |
| `${key | default}` | variables 和环境变量都不存在时使用默认值 |
| `${key | }` | variables 和环境变量都不存在时使用空字符串 |
| `$${key}` | 转义输出字面量 `${key}` |
解析优先级为 `variables -> process.env -> 默认值`。三者均不存在时配置校验失败。字段值完整等于单个变量引用时会保留 number、boolean、string 类型;部分拼接时统一转为字符串。
变量替换作用于 `server``probes``targets`,不作用于 `variables` 段自身,且不会替换 `targets[].id``targets[].type` 字段;对象 key 不参与替换。
## 配置加载形态
配置加载内部区分三层形态:
| 形态 | 说明 |
| ----------------- | ------------------------------------------------------------------------------------- |
| Authoring Config | 用户 YAML 可书写形态,允许变量引用和 expect 简写 |
| Normalized Config | `normalizeAuthoringConfig()` 完成变量替换、expect 简写展开并移除 `variables` 后的形态 |
| ResolvedConfig | checker `resolve()` 补默认值并解析 duration、size、路径和运行期环境后的形态 |
根目录 `probe-config.schema.json` 面向 Authoring Config因此 VSCode 校验会接受 `server.listen.port: "${server_port|3000}"``http.maxRedirects: "${MAX|5}"``expect.durationMs: 5000` 这类写法。
## targets 通用字段
| 字段 | 说明 | 必填 | 默认值 |
| ------------- | ------------------------------------------------------------------------------------ | ---- | --------- |
| `id` | 目标唯一标识,最长 30 字符,支持字母数字、下划线、连字符,不参与变量替换 | 是 | 无 |
| `name` | 展示名称,最长 30 字符,支持变量替换,可省略或显式 null前端展示时 null 回退到 `id` | 否 | 无 |
| `description` | 目标描述,最长 500 字符,支持变量替换,可省略或显式 null允许空字符串 | 否 | 无 |
| `type` | 目标类型:`http``cmd``db``tcp``udp``dns``icmp``llm` | 是 | 无 |
| `group` | 分组名称 | 否 | `default` |
| `interval` | 拨测间隔 | 否 | `30s` |
| `timeout` | 超时时间 | 否 | `10s` |
## Checker 专属配置
每个 target 必须根据 `type` 配置对应的 checker 专属字段。详情见 [Checker 参考](checkers/README.md)。
## 校验规则
`expect` 字段按 checker 类型不同而变化。通用断言模型见 [校验规则](expectations.md)。

109
docs/user/deployment.md Normal file
View File

@@ -0,0 +1,109 @@
# 部署
本文档说明如何构建、运行、容器化和发布 DiAL。开发环境运行见 [README 快速开始](../../README.md#快速开始)。
## 生产构建和运行
```bash
bun run build
./dist/dial-server ./probes.yaml
```
构建产物为独立可执行文件,只需要一个 YAML 配置文件即可运行。
启动后:
| 地址 | 行为 |
| ------------------------------ | ------------------ |
| `http://127.0.0.1:3000/` | 返回前端 Dashboard |
| `http://127.0.0.1:3000/api/*` | 返回后端 API |
| `http://127.0.0.1:3000/health` | 返回健康检查 |
## Docker 部署
DiAL 提供基于 Alpine 的多阶段镜像。构建阶段使用 Bun 生成 musl 目标单可执行文件,运行阶段只包含 `dial-server`、基础证书、`ping`、Bun musl executable 必需运行库、时区数据和容器运行目录。
```bash
docker build -t dial:alpine .
docker run --rm -p 3000:3000 -v dial-data:/data/dial dial:alpine
```
容器默认读取 `/etc/dial/probes.yaml`,推荐将数据卷挂载到 `/data/dial`
使用自定义配置文件:
```bash
docker run --rm -p 3000:3000 \
-v "$PWD/docker/probes.yaml:/etc/dial/probes.yaml:ro" \
-v dial-data:/data/dial \
dial:alpine
```
容器专用示例配置位于 [`../../docker/probes.yaml`](../../docker/probes.yaml),默认监听 `0.0.0.0:3000`,并将 SQLite 数据和日志写入 `/data/dial`
## ICMP 权限
如需在容器中运行 ICMP checker除镜像内置 `iputils-ping` 外,还需要授予 `NET_RAW` capability
```bash
docker run --rm --cap-add=NET_RAW -p 3000:3000 -v dial-data:/data/dial dial:alpine
```
## CMD checker 额外命令
官方镜像不内置 `bun``node``curl``dig``psql``mysql``redis-cli` 等 CMD checker 可能需要的额外命令。需要这些命令时请使用派生镜像自行安装:
```dockerfile
FROM dial:alpine
USER root
RUN apk add --no-cache curl bind-tools postgresql-client
USER dial
```
## 多架构镜像
```bash
docker buildx build --platform linux/amd64,linux/arm64 -t dial:alpine .
```
Dockerfile 通过 Docker 提供的 `TARGETARCH` 选择 Bun compile target。
| `TARGETARCH` | `BUN_TARGET` |
| ------------ | ---------------------- |
| `amd64` | `bun-linux-x64-musl` |
| `arm64` | `bun-linux-arm64-musl` |
## 跨平台发布包
```bash
bun run release
bun run release --target linux-x64
bun run release --target linux-x64,windows-x64,darwin-arm64
```
支持的目标平台:
| CLI 参数 | Bun CompileTarget |
| ------------------ | ---------------------- |
| `linux-x64` | `bun-linux-x64` |
| `linux-arm64` | `bun-linux-arm64` |
| `linux-x64-musl` | `bun-linux-x64-musl` |
| `linux-arm64-musl` | `bun-linux-arm64-musl` |
| `windows-x64` | `bun-windows-x64` |
| `darwin-x64` | `bun-darwin-x64` |
| `darwin-arm64` | `bun-darwin-arm64` |
产出物结构:
```text
dist/release/
├── binaries/
│ ├── dial-server-0.1.0-linux-x64
│ └── dial-server-0.1.0-windows-x64.exe
└── packages/
├── dial-server_0.1.0_linux_x64.tar.gz
└── dial-server_0.1.0_linux_x64.tar.gz.sha256
```
压缩包内含可执行文件、`probes.example.yaml``LICENSE`,解压后可直接使用。

104
docs/user/expectations.md Normal file
View File

@@ -0,0 +1,104 @@
# 校验规则
`expect` 描述拨测结果必须满足的条件。不同 checker 暴露不同字段,但共享三类基础断言模型:`ValueMatcher``ContentExpectations``KeyedExpectations`
## ContentExpectations
`body``stdout``stderr``banner``response``output``result` 等返回内容字段均使用数组。
| 规则 | 说明 |
| ---------- | ------------------------------------------------------ |
| `contains` | 内容包含指定文本 |
| `regex` | 正则匹配,启动期会拒绝存在 ReDoS 风险的模式 |
| `json` | JSONPath 提取值比较,`path` 必填 |
| `css` | CSS 选择器提取 HTML 元素,`selector` 必填,`attr` 可选 |
| `xpath` | XPath 提取 XML/HTML 节点,`path` 必填 |
示例:
```yaml
expect:
body:
- contains: "ok"
- json:
path: "$.status"
equals: "ready"
```
ContentExpectations 数组按顺序快速失败。数组项可以是直接 matcher也可以是 `json``css``xpath` 提取器规则。一条规则不能混用直接 matcher 和 extractor多个 extractor 也不能共存。Extractor 未配置 matcher 时等价于 `exists: true`
## ValueMatcher
`ValueMatcher` 用于单个标量值、数字指标和字符串元数据。
| 字段 | 说明 |
| ---------- | ------------------------------- |
| `equals` | 精确匹配,支持 JSON 深度相等 |
| `contains` | 字符串包含 |
| `regex` | 正则匹配,固定使用无 flags 正则 |
| `empty` | 判断是否为空 |
| `exists` | 判断是否存在 |
| `gte` | 大于等于 |
| `lte` | 小于等于 |
| `gt` | 大于 |
| `lt` | 小于 |
一个 matcher 对象内多个字段为 AND 语义。`exists: false` 不能和其他 matcher 组合。
ValueMatcher expect 字段可直接写 string、number、boolean 或 null等价于 `{ equals: value }`。数组和对象必须显式写成 `{ equals: ... }`
```yaml
expect:
durationMs:
lte: 5000
finishReason: "stop"
```
## KeyedExpectations
`headers`、DB `rows[]` 中的列值等动态键值对象使用 `KeyedExpectations`。每个键的值支持 `ValueMatcher` 的全部字段,字面量值自动等价于 `{ equals: value }`
```yaml
expect:
headers:
Content-Type:
contains: "application/json"
```
## 大小和时长格式
| 类型 | 示例 |
| ---- | -------------------------------- |
| 大小 | `4KB``10MB``1GB`、直接数字 |
| 时长 | `500ms``30s``5m``2h``7d` |
`maxBodyBytes``maxOutputBytes``maxResponseBytes``maxBannerBytes` 等大小字段支持 `KB``MB``GB` 单位。
## 快速失败顺序
| Checker | 顺序 |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| HTTP | `status -> headers -> body -> durationMs` |
| Cmd | `exitCode -> durationMs -> stdout -> stderr` |
| DB | `durationMs -> rowCount -> rows -> result` |
| TCP | `connected -> banner -> durationMs` |
| UDP | `responded -> responseSize -> response -> sourceHost -> sourcePort -> durationMs` |
| ICMP | `alive -> packetLossPercent -> avgLatencyMs -> maxLatencyMs -> durationMs` |
| DNS system | `values -> valueCount -> durationMs` |
| DNS server | `responded -> rcode -> values -> valueCount -> answerCount -> ttlMin -> ttlMax -> authoritative -> recursionAvailable -> truncated -> authenticatedData -> result -> durationMs` |
| LLM http | `status -> headers -> output -> finishReason -> rawFinishReason -> usage -> durationMs` |
| LLM stream | `status -> headers -> stream.completed -> stream.firstTokenMs -> output -> finishReason -> rawFinishReason -> usage -> durationMs` |
## JSON Schema
仓库根目录导出 `probe-config.schema.json`。在 YAML 文件顶部添加以下注释可在编辑器中获得提示和校验:
```yaml
# yaml-language-server: $schema=./probe-config.schema.json
```
## 已移除字段
旧字段 `maxDurationMs``maxPacketLoss``maxAvgLatencyMs``maxMaxLatencyMs` 和旧正则字段 `match` 已移除,请分别改用 `durationMs`、ICMP matcher 字段和 `regex`
非法配置会阻止启动并输出错误信息。除动态键值表(`headers``env``variables`)外,未知字段会导致启动失败,请使用 YAML 注释表达说明。

48
docs/user/status-model.md Normal file
View File

@@ -0,0 +1,48 @@
# 目标状态判定
DiAL 使用单层状态模型。
| 状态 | 含义 |
| ------ | ---------------------------------------- |
| `UP` | 拨测结果符合 `expect` 规则 |
| `DOWN` | 拨测结果不符合 `expect` 规则,或执行失败 |
执行失败(网络错误、超时、进程崩溃)和 expect 不匹配都统一为 `DOWN`,通过 `failure.kind` 区分原因。
| `failure.kind` | 含义 |
| -------------- | ---------------------------------------- |
| `error` | 网络、超时、进程、协议解析或内部执行错误 |
| `mismatch` | 拨测完成,但结果不满足 expect |
## API 结果字段
API 返回的检查结果包含 `detail``observation`
| 字段 | 说明 |
| ------------- | ------------------------------------------------------------ |
| `detail` | 后端按 checker 类型从结构化 observation 动态生成的人可读摘要 |
| `observation` | 保存该次检查的结构化观测数据 |
| `failure` | 保存首个错误或不匹配原因 |
| `matched` | 是否符合 expect |
| `durationMs` | 本次检查耗时 |
| `timestamp` | 本次检查时间 |
`detail` 不写入 SQLite。存储层仅持久化 `observation` JSON、`failure` JSON、匹配状态、耗时和时间戳。
## observation 示例
不同 checker 的 observation 字段不同,常见信息包括:
| Checker | observation 内容示例 |
| ------- | ------------------------------------------------------------------ |
| HTTP | 状态码、响应头、按需读取的 body 预览 |
| Cmd | exit code、stdout/stderr 预览 |
| TCP | 连接结果、banner 摘要 |
| UDP | 响应内容、来源地址、响应大小 |
| ICMP | 存活结果、丢包率、平均延迟、最大延迟 |
| DNS | RCODE、记录值、TTL、flags、CNAME 链 |
| LLM | HTTP 状态、模型输出、finish reason、token usage、流式首 token 时间 |
## 趋势与统计
Dashboard 基于存储的检查结果计算实时状态、可用率、耗时趋势、P95、状态条和故障段等指标。指标语义由后端应用层实现SQLite 主要负责存储、筛选、排序、分页和基础聚合。

View File

@@ -0,0 +1,73 @@
# 故障排查
本文档记录常见运行问题和排查入口。
## 配置校验失败
DiAL 启动时会校验 YAML 配置。除动态键值表(`headers``env``variables`)外,未知字段会导致启动失败。
排查顺序:
1. 在 YAML 顶部添加 `# yaml-language-server: $schema=./probe-config.schema.json`
2. 对照 [配置文件](configuration.md) 检查顶层结构和通用字段。
3. 对照 [Checker 参考](checkers/README.md) 检查 checker 专属字段。
4. 对照 [校验规则](expectations.md) 检查 expect 写法。
## 变量无法解析
变量解析优先级为 `variables -> process.env -> 默认值`。如果三者均不存在,配置校验会失败。
常见修复:
| 问题 | 修复 |
| -------------- | ----------------------------------- | --------- |
| 环境变量未设置 | 设置环境变量或在 `variables` 中声明 |
| 希望允许空值 | 使用 `${key | }` |
| 希望提供默认值 | 使用 `${key | default}` |
| 希望输出字面量 | 使用 `$${key}` |
## ICMP checker 无法运行
ICMP checker 依赖系统 `ping` 命令。
| 环境 | 处理 |
| ------------------- | -------------------------------------- |
| Alpine 或精简镜像 | 安装 `iputils-ping` |
| Docker 容器 | 运行容器时增加 `--cap-add=NET_RAW` |
| Windows/macOS/Linux | 确认系统 `ping` 可执行且输出格式受支持 |
Docker 示例:
```bash
docker run --rm --cap-add=NET_RAW -p 3000:3000 -v dial-data:/data/dial dial:alpine
```
## CMD checker 找不到命令
官方 Docker 镜像不内置 `bun``node``curl``dig``psql``mysql``redis-cli` 等额外命令。需要这些命令时请使用派生镜像安装。
```dockerfile
FROM dial:alpine
USER root
RUN apk add --no-cache curl bind-tools postgresql-client
USER dial
```
## Docker 数据或日志丢失
推荐将数据卷挂载到 `/data/dial`,并在配置中使用该目录作为 storage dataDir。
```bash
docker run --rm -p 3000:3000 -v dial-data:/data/dial dial:alpine
```
容器示例配置位于 [`../../docker/probes.yaml`](../../docker/probes.yaml)。
## HTTP 或 LLM 证书问题
HTTP 和 LLM checker 支持 `ignoreSSL`。该选项适合内网、自签名证书或测试环境;生产环境应优先修复证书链。
## 正则规则被拒绝
`regex` 启动期会执行 ReDoS 风险检测。被拒绝时应改写为更明确、回溯风险更低的表达式。