Scrutiny 0.9.5 配置参数详解
Scrutiny 0.9.5 配置参数逐项详解:scrutiny.yaml 服务端配置(监听/SQLite/InfluxDB/通知)、collector.yaml 采集端配置(设备覆写/白名单/smartctl 参数)、0.9 系列阈值机制现状(内置元数据+运行时设置)、数据存储与升级迁移,全部键位核对官方源码并附实测回显
Scrutiny 0.9.5 配置参数详解
目标:逐项讲清 Scrutiny 0.9.5 的两份配置文件(服务端
scrutiny.yaml、采集端collector.yaml)的全部配置段与默认值,说明 0.9 系列阈值机制的现状(内置元数据 + 运行时设置,不再是 YAML 阈值段),以及数据存储位置与升级迁移要点。所有键位均核对自 v0.9.5 官方源码与示例文件,运行时行为已在 Ubuntu 22.04 实测通过。
一、环境信息
本章列出本篇写作与实测的基准,保证每一项键位说法可追溯。
- 核对版本:Scrutiny v0.9.5(2026-09-30 发布,官方最新稳定版;查询日期 2026-10-18)
- 键位与默认值依据(官方源码与示例,均为 v0.9.5 标签):
- 服务端配置结构:
webapp/backend/pkg/config/config.go(含全部SetDefault默认值与环境变量映射) - 服务端示例配置:
example.scrutiny.yaml - 采集端示例配置:
example.collector.yaml - 运行时设置模型:
webapp/backend/pkg/models/settings.go - 状态枚举:
webapp/backend/pkg/constants.go - 阈值元数据:
webapp/backend/pkg/thresholds/(ata/nvme/scsi 三个文件) - 数据下采样:官方
docs/DOWNSAMPLING.md
- 服务端配置结构:
- 实测环境:Ubuntu 22.04(x86_64)+
ghcr.io/analogj/scrutiny:v0.9.5-omnibus一体化服务,Web 端口8102 → 8080,数据目录/opt/scrutiny-deploy/config/(SQLite)与/opt/scrutiny-deploy/influxdb/(时序数据) - 本地未放配置文件时服务端启动日志的权威回显(实测):
No configuration file found at /opt/scrutiny/config/scrutiny.yaml. Using Defaults.
二、配置体系总览
Scrutiny 0.9.5 的配置分四个层面,作用域与生效方式各不相同,先建立全局图景再逐项展开:
| 层面 | 载体 | 作用对象 | 生效方式 |
|---|---|---|---|
| 服务端文件配置 | scrutiny.yaml | web 进程(监听/数据库/InfluxDB/通知) | 启动时读取,改后需重启 |
| 采集端文件配置 | collector.yaml | collector 进程(设备/上报地址/smartctl 参数) | 每轮采集启动时读取 |
| 环境变量 | SCRUTINY_ / COLLECTOR_ 前缀 | 分别覆盖服务端/采集端对应键 | 启动时注入 |
| 运行时设置 | 面板 Settings 页 / /api/settings | 面板行为与通知级别(存 SQLite) | 保存即生效,无需重启 |
三个关键认知:
其一,配置文件是可选的。服务端与采集端都内置完整默认值(源码 config.go 逐项 SetDefault),无文件时打印上面的实测日志并全按默认运行——omnibus 形态零配置可用的原因就在此。
其二,配置键大小写不敏感且统一转小写。官方示例文件头部原话:「When this file is parsed by Scrutiny, all configuration file keys are lowercased automatically. As such, Configuration keys are case-insensitive, and should be lowercase in this file to be consistent with usage.」
其三,0.9 系列移除了 YAML 阈值段。0.8 时代 scrutiny.yaml 中有 thresholds(含 temp、attribute、metadata 等段)与独立的 thresholds.yaml;v0.9 起阈值改为两层——代码内置的真实故障率元数据(不可通过配置文件修改)+ 面板运行时设置(/api/settings)。升级时残留旧键会导致服务拒绝启动(见第七章 Q3)。这正是本篇第五章用整章篇幅重讲「阈值」的原因:找错地方配阈值是 0.8 → 0.9 升级最常见的坑。
2.1 配置文件加载路径
两份配置文件的默认查找路径都在 /opt/scrutiny/config/ 下(omnibus 与手动安装一致):
- 服务端:启动命令
scrutiny-web start --config /opt/scrutiny/config/scrutiny.yaml显式指定; - 采集端:默认
/opt/scrutiny/config/collector.yaml(官方示例文件头注明)。
服务端配置结构体(config.go)同时定义了环境变量映射规则(源码实测节选):
c.SetEnvPrefix("SCRUTINY")
c.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))
即任意文件配置键都可用环境变量覆盖:点号换下划线、加 SCRUTINY_ 前缀,例如 web.listen.port → SCRUTINY_WEB_LISTEN_PORT。采集端同理使用 COLLECTOR_ 前缀(COLLECTOR_API_ENDPOINT、COLLECTOR_HOST_ID 等,与采集器 --help 实测回显一致,见《Scrutiny Docker Compose 部署指南》第七章)。
三、scrutiny.yaml 服务端配置详解
以下按 v0.9.5 官方示例 example.scrutiny.yaml 的段落顺序逐项讲解,默认值取自源码 config.go 的 SetDefault 调用(逐行核对)。先给一个可直接落地的最小生产配置骨架,再分小节展开:
version: 1
web:
listen:
port: 8080
host: 0.0.0.0
basepath: ''
database:
location: /opt/scrutiny/config/scrutiny.db
src:
frontend:
path: /opt/scrutiny/web
influxdb:
scheme: http
host: localhost
port: 8086
token: scrutiny-default-admin-token
org: scrutiny
bucket: metrics
retention_policy: true
log:
file: ''
level: INFO
notify:
urls: []
3.1 version
version: 1
配置文件结构版本号,不是 Scrutiny 程序版本号。官方注释原话:「version specifies the version of this configuration file schema, not the scrutiny binary. There is only 1 version available at the moment」。当前固定写 1。
3.2 web.listen(监听地址与端口)
| 键 | 默认值 | 说明 |
|---|---|---|
web.listen.port | 8080 | HTTP 监听端口 |
web.listen.host | 0.0.0.0 | 监听地址;0.0.0.0 表示全部网卡 |
web.listen.basepath | 空 | 反向代理子路径前缀 |
basepath 用于「把 Scrutiny 挂在网站子路径下」的场景:官方注释给出示例——配置 /scrutiny 后通过 http://example.com/scrutiny/* 访问,而非常规的 http://example.com:8080。官方提示反向代理配置细节见 docs/TROUBLESHOOTING_REVERSE_PROXY.md。
3.3 web.database(SQLite 设备库)
web:
database:
location: /opt/scrutiny/config/scrutiny.db
| 键 | 默认值 | 说明 |
|---|---|---|
web.database.location | /opt/scrutiny/config/scrutiny.db | SQLite 文件路径,存设备清单、设置等元数据 |
官方注释说明该值「can also set absolute path here」——可指向任意绝对路径。这是唯一需要持久化备份的服务端元数据文件(时序数据在 InfluxDB,见第六章)。
3.4 web.src.frontend(前端静态文件)
web:
src:
frontend:
path: /opt/scrutiny/web
| 键 | 默认值 | 说明 |
|---|---|---|
web.src.frontend.path | /opt/scrutiny/web | 前端 JS/CSS 静态文件目录 |
默认值面向手动安装形态(前端解压到 /opt/scrutiny/web);omnibus 一体化发行包内已按相同布局就位,无需改动。手动安装时若前端解压后出现多余的 dist 层级(即路径形如 /opt/scrutiny/web/dist),官方文档明确要求展平,否则面板 404。
3.5 web.influxdb(时序库连接)
这是服务端配置中信息量最大的一段。v0.9.5 全部键与默认值(源码 config.go 逐行核对):
| 键 | 默认值 | 说明 |
|---|---|---|
web.influxdb.scheme | http | 连接协议,外置实例启用 TLS 时改 https |
web.influxdb.host | localhost | InfluxDB 主机;omnibus 内为本机 |
web.influxdb.port | 8086 | InfluxDB 端口 |
web.influxdb.org | scrutiny | InfluxDB 组织名 |
web.influxdb.bucket | metrics | 主数据桶名 |
web.influxdb.init_username | admin | 自动初始化 InfluxDB 时创建的管理员账号 |
web.influxdb.init_password | password12345 | 上述管理员初始密码 |
web.influxdb.token | scrutiny-default-admin-token | API Token(omnibus 初始化时使用默认值) |
web.influxdb.tls.insecure_skip_verify | false | 是否跳过 TLS 证书校验 |
web.influxdb.retention_policy | true | 是否由 Scrutiny 创建/管理保留策略 |
官方注释对 token/org/bucket 的语义划分(原文翻译):全新 InfluxDB 实例无需提供这三项——Scrutiny 会自动执行 InfluxDB 初始化(setup)并把信息写回配置文件;复用已有 InfluxDB 实例时才需要显式提供 token。
⚠️ 注意:
init_password与token的默认值是公开的(写死在源码里)。omnibus 内嵌 InfluxDB 的管理端口(默认 8086)映射到宿主时,等于把时序库管理面暴露在内网——本次实测为排障演示临时映射了8103:8086,安全加固建议:不映射该端口,或改用强随机 token 并同步更新web.influxdb.token。本篇文档不落真实凭据,接入真实通知渠道时同理。
外置 InfluxDB 场景的改法示例(官方示例文件同构):
web:
influxdb:
scheme: https
host: influxdb.example.internal
port: 8086
token: <your-existing-token>
org: ops
bucket: metrics
tls:
insecure_skip_verify: false
💡 技术拓展:为什么自建时序库而不复用 SQLite?设备元数据(几十行记录)用 SQLite 足够,但指标历史是「每盘 18+ 属性 × 每日 1 点 × 多年」的时间序列,需要按时间范围聚合、降采样与保留策略管理,这正是 InfluxDB 的领域。Scrutiny 的四个桶(metrics/metrics_weekly/metrics_monthly/metrics_yearly)本质是把「原始点 + 三级聚合」分层存放:查最近几天直接读原始桶,查多年趋势读聚合桶,兼顾精度与库体积(详见第六章)。
3.6 log(日志)
| 键 | 默认值 | 说明 |
|---|---|---|
log.file | 空(输出 STDOUT) | 日志落盘路径,绝对/相对路径均可,官方示例 web.log |
log.level | INFO | 日志级别 |
omnibus 形态日志由服务进程 STDOUT 承接,一般无需改 log.file;手动安装 + systemd 托管时 journald 同样承接 STDOUT,log.file 主要用于调试期落盘分析。
3.7 notify(通知渠道)
notify:
urls:
- "telegram://<token>@telegram?chats=<chat-id>"
| 键 | 默认值 | 说明 |
|---|---|---|
notify.urls | [] | Shoutrrr URL 列表,可同时配置多个渠道 |
urls 是数组:一条 URL 一个渠道,多渠道并行通知。v0.9.5 官方示例列出的全部 URL 形态(原文照录,配置时按需取一行改凭据):
discord://token@id[?thread_id=threadid]
googlechat://chat.googleapis.com/v1/spaces/FOO/messages?key=bar&token=baz
hangouts://chat.googleapis.com/v1/spaces/FOO/messages?key=bar&token=baz
lark://host/token?secret=secret&title=title&link=url
matrix://username:password@host:port/[?rooms=!roomID1[,roomAlias2]]
mattermost://[username@]mattermost-host/token[/channel]
rocketchat://[username@]rocketchat-host/token[/channel|@recipient]
signal://[user[:password]@]host[:port]/source_phone/recipient1[,recipient2,...]
slack://[botname@]token-a/token-b/token-c
teams://group@tenant/altId/groupOwner?host=organization.webhook.office.com
telegram://token@telegram?chats=@channel-1[,chat-id-1,chat-id-2:message-thread-id,...]
wecom://key
zulip://bot-mail:bot-key@zulip-domain/?stream=name-or-id&topic=name
bark://devicekey@host
gotify://gotify-host/token
ifttt://key/?events=event1[,event2,...]&value1=value1&value2=value2&value3=value3
join://shoutrrr:api-key@join/?devices=device1[,device2, ...][&icon=icon][&title=title]
ntfy://username:password@ntfy.sh/topic
pushbullet://api-token[/device/#channel/email]
pushover://shoutrrr:apiToken@userKey/?devices=device1[,device2, ...]
opsgenie://host/token?responders=responder1[,responder2]
pagerduty://[host[:port]]/integration-key[?query-parameters]
smtp://username:password@host:port/?fromaddress=fromAddress&toaddresses=recipient1[,recipient2,...][&additional_params]
官方注释两点提醒(原文翻译):URL 中含特殊字符的账号密码需 URL 编码(示例:用户名 myname@example.com、密码 124@34$1 的 SMTP URL 写作 smtp://myname%40example%2Ecom:124%4034%241@ms.my.domain.com:587);服务级参数详见 Shoutrrr 文档(https://shoutrrr.nickfedor.com/services/overview/)。
通知级别、重复策略等「何时通知」的行为不在本段配置,属于运行时设置(第五章)。配置好渠道后可立即自检:
curl -s -i -X POST http://127.0.0.1:8102/api/health/notify | tail -3
实测回显(未配置任何渠道时):
HTTP/1.1 500 Internal Server Error
Content-Type: application/json; charset=utf-8
Date: Sat, 18 Oct 2026 09:47:57 GMT
Content-Length: 16
{"success":false}
服务端日志同步输出(实测):No notification endpoints configured. Skipping failure notification.——配置 notify.urls 后重试,返回 200 即表示测试通知已发出(需要真实凭据,本篇不落值)。
四、collector.yaml 采集端配置详解
采集端配置文件默认路径 /opt/scrutiny/config/collector.yaml,同样可缺省(全默认运行)。以下段落与键位全部取自 v0.9.5 官方 example.collector.yaml。
4.1 host.id(主机分组标签)
host:
id: ""
官方注释原话翻译:用于标识「同一台主机上的一组磁盘」的标签,主要用于 Hub/Spoke 部署形态(多台主机的采集器向同一中心上报时区分来源);一体化发行包部署可留空。采集器也支持等价环境变量 COLLECTOR_HOST_ID。
4.2 devices(设备类型覆写与忽略)
这是采集端最常动的段落:当 smartctl --scan 自动探测的类型不对(RAID 卡后的物理盘、USB 桥接、虚拟盘)或需要跳过某块盘时,在这里显式声明。官方示例注释提供的全部形态(原文结构照录):
devices:
# 强制单盘设备类型
- device: /dev/sda
type: 'sat'
# 使用 -d sat,auto(方括号列表写法,官方注明这是 issue #418 的规避写法)
- device: /dev/sda
type: ['sat,auto']
# 忽略特定设备
- device: /dev/sda
ignore: true
# 强制识别 RAID 阵列内虚拟盘(megaraid 系列)
- device: /dev/bus/0
type:
- megaraid,14
- megaraid,15
- megaraid,18
- megaraid,19
- megaraid,20
- megaraid,21
# 3ware 系列同理
- device: /dev/twa0
type:
- 3ware,0
- 3ware,1
- 3ware,2
- 3ware,3
- 3ware,4
- 3ware,5
# 按设备覆写 smartctl 命令参数
- device: /dev/sda
commands:
metrics_info_args: '--info --json -T permissive'
metrics_smart_args: '--xall --json -T permissive'
| 键 | 类型 | 说明 |
|---|---|---|
devices[].device | 字符串 | 设备路径,与 smartctl --scan 输出一致 |
devices[].type | 字符串或列表 | 传给 smartctl 的 -d/--device 类型参数 |
devices[].ignore | 布尔 | 置 true 跳过该设备 |
devices[].commands.* | 字符串 | 按设备覆写 smartctl 命令行 |
type 取值对应 smartctl 手册的「--device=TYPE」一节(官方注释给出参考链接 https://linux.die.net/man/8/smartctl),常见值:sat(SATA 经 SAT 层)、nvme、scsi、sat,auto、megaraid,N、3ware,N。
4.3 allow_listed_devices(采集白名单)
allow_listed_devices:
- /dev/sda
- /dev/sdb
官方注释原话翻译:仅对列出的设备采集指标;省略或留空时,对 smartctl --scan 探测到的全部设备采集。与 devices[].ignore 的区别:白名单是「只采这些」,ignore 是「跳过某个」——设备数量固定且明确时白名单更直观,偶尔排除一块盘时 ignore 更省事。
4.4 log 与 api(日志与上报地址)
log:
file: ''
level: INFO
api:
endpoint: 'http://localhost:8080'
| 键 | 默认值 | 说明 |
|---|---|---|
log.file | 空 | 采集器日志落盘路径 |
log.level | INFO | 日志级别 |
api.endpoint | http://localhost:8080 | 上报目标,即服务端地址 |
api.endpoint 支持带路径后缀以适配反向代理子路径部署(官方注释给出 http://localhost:8080/custombasepath 示例并指向 docs/TROUBLESHOOTING_REVERSE_PROXY.md)。Hub/Spoke 形态下被监控机只需把这里指向中心机地址。等价环境变量:COLLECTOR_API_ENDPOINT。
4.5 commands(smartctl 全局参数覆写)
commands:
metrics_smartctl_bin: 'smartctl'
metrics_scan_args: '--scan --json'
metrics_info_args: '--info --json'
metrics_smart_args: '--xall --json'
metrics_smartctl_wait: 0
| 键 | 默认值 | 说明 |
|---|---|---|
commands.metrics_smartctl_bin | smartctl | 自定义 smartctl 可执行文件路径 |
commands.metrics_scan_args | --scan --json | 设备探测参数 |
commands.metrics_info_args | --info --json | 设备信息读取参数(注册用) |
commands.metrics_smart_args | --xall --json | SMART 数据读取参数 |
commands.metrics_smartctl_wait | 0 | 相邻两块盘查询间隔秒数 |
典型用途:RAID 卡超时或总线繁忙时给 metrics_smart_args 加 -T permissive;多盘大阵列时设置 metrics_smartctl_wait 间隔减轻瞬时 IO 压力。metrics_smartctl_wait 的调度间隔本身由 COLLECTOR_CRON_SCHEDULE 控制(omnibus 默认每日 0 点,详见部署篇第七章)。
4.6 预留特性段(collect)
官方示例文件末尾用醒目注释标注了「FEATURES COMING SOON」的 collect 段(长/短自检调度):
collect:
long:
enable: false
command: ''
short:
enable: false
command: ''
这是官方预告的未发布特性,当前版本写了也不生效——列在这里仅供识别,避免误以为可配置自检计划。
五、阈值与运行时设置(v0.9.5 现状)
本章把「阈值」在 0.9.5 中的真实位置讲透:哪些可配、在哪配、怎么配。
5.1 阈值的两层结构与存放位置
第一层:厂商 SMART 阈值。来自硬盘固件,随 smartctl 数据上报(每属性的 thresh 与 when_failed 字段),不可配置。设备整体 smart_status.passed=false 时置 DeviceStatusFailedSmart。
第二层:Scrutiny 观察阈值。代码内置的属性元数据,按「属性值区间 → 年化故障率」建模,文件位于源码 webapp/backend/pkg/thresholds/(v0.9.5 实测大小:ata_attribute_metadata.go 54147 字节、nvme_attribute_metadata.go 7869 字节、scsi_attribute_metadata.go 9240 字节)。判定常量(源码 constants.go 实录):
const (
AttributeStatusPassed AttributeStatus = 0
AttributeStatusFailedSmart AttributeStatus = 1
AttributeStatusWarningScrutiny AttributeStatus = 2
AttributeStatusFailedScrutiny AttributeStatus = 4
)
const (
DeviceStatusPassed DeviceStatus = 0
DeviceStatusFailedSmart DeviceStatus = 1
DeviceStatusFailedScrutiny DeviceStatus = 2
)
判定规则的数值线(关键属性年化故障率 ≥10% 判失败、非关键 ≥20% 判失败/≥10% 告警)由元数据文件内建,0.9.5 不提供配置文件入口——「调阈值」的正确姿势只有两个:改运行时设置(5.2),或走面板设置页(同一个存储)。
与 0.8 时代的对应关系:旧版 scrutiny.yaml 的 thresholds.attribute(如 critical/warning 修饰)、thresholds.temp(高温阈值)等键已整体移除;温度阈值相关行为现由内置元数据与面板设置共同决定。升级前先删干净旧键(见第七章 Q3)。
5.2 运行时设置:/api/settings 全解
运行时设置存 SQLite(SettingEntry 表),面板 Settings 页保存即生效。读取接口 GET /api/settings,本机实测完整回显(未做任何修改时的默认状态):
{
"settings": {
"theme": "",
"layout": "",
"dashboard_display": "",
"dashboard_sort": "",
"temperature_unit": "",
"file_size_si_units": false,
"line_stroke": "",
"powered_on_hours_unit": "",
"collector": {
"discard_sct_temp_history": false
},
"metrics": {
"notify_level": 4,
"status_filter_attributes": 0,
"status_threshold": 4,
"repeat_notifications": true
}
},
"success": true
}
逐项语义(枚举值取自源码 constants.go 与 settings.go 模型):
| 键 | 默认值 | 说明 |
|---|---|---|
theme | 空 | 面板主题 |
layout | 空 | 布局形态 |
dashboard_display | 空 | Dashboard 卡片展示模式 |
dashboard_sort | 空 | 设备卡片排序(如失败置顶) |
temperature_unit | 空 | 温度单位(空=摄氏,fahrenheit=华氏) |
file_size_si_units | false | 容量单位:false=二进制(GiB/TiB),true=十进制 SI(GB/TB) |
line_stroke | 空 | 图表线条样式 |
powered_on_hours_unit | 空 | 通电时间显示格式(空=小时,humanize=年天时分) |
collector.discard_sct_temp_history | false | 是否丢弃 SCT 温度历史(部分盘该日志异常时置 true) |
metrics.notify_level | 4 | 通知触发级别(按位:1=Warn 告警,2=Fail 失败,3=两者,4=默认策略) |
metrics.status_filter_attributes | 0 | 属性过滤:0=全部,1=仅关键属性 |
metrics.status_threshold | 4 | 状态展示阈值(按位:1=厂商判定,2=Scrutiny 判定,3=两者,4=默认) |
metrics.repeat_notifications | true | 失败持续时是否重复通知 |
源码 constants.go 中相关枚举实录(与上表对应):
type MetricsNotifyLevel int64
const (
MetricsNotifyLevelWarn MetricsNotifyLevel = 1
MetricsNotifyLevelFail MetricsNotifyLevel = 2
)
type MetricsStatusFilterAttributes int64
const (
MetricsStatusFilterAttributesAll MetricsStatusFilterAttributes = 0
MetricsStatusFilterAttributesCritical MetricsStatusFilterAttributes = 1
)
type MetricsStatusThreshold int64
const (
MetricsStatusThresholdSmart MetricsStatusThreshold = 1
MetricsStatusThresholdScrutiny MetricsStatusThreshold = 2
//shortcut
MetricsStatusThresholdBoth MetricsStatusThreshold = 3
)
5.3 保存设置的实测(含一个真实的坑)
POST /api/settings 的请求体是顶层 Settings 对象本身——不包 settings 键。这个不对称坑是本篇实测真实踩到的:先看正确写法与实测回显。
正确写法(先 GET 取全量对象,原样 POST 回去只改目标键):
curl -s -X POST -H 'Content-Type: application/json' \
-d @settings-restore.json http://127.0.0.1:8102/api/settings
实测回显(成功保存,响应回显所存对象):
{"settings":{"theme": "", "layout": "", "dashboard_display": "", "dashboard_sort": "", "temperature_unit": "", "file_size_si_units": false, "line_stroke": "", "powered_on_hours_unit": "", "collector": {"discard_sct_temp_history": false}, "metrics": {"notify_level": 4, "status_filter_attributes": 0, "status_threshold": 4, "repeat_notifications": true}}, "success": true}
再次 GET /api/settings 验证持久化成功:
settings.metrics: {'notify_level': 4, 'status_filter_attributes': 0, 'status_threshold': 4, 'repeat_notifications': True}
⚠️ 坑(实测复现):把
{"settings":{...}}(GET 响应的包裹形态)原样 POST 回去,服务端会把未知外层键忽略、按空对象保存全部设置——实测结果为notify_level: 0、status_threshold: 0、repeat_notifications: false,且POST仍返回success: true。原因:服务端处理函数直接c.BindJSON(&settings)绑定顶层对象(源码webapp/backend/pkg/web/handler/save_settings.go),多余的settings包裹键被丢弃。恢复方法:按正确形态重发完整对象。操作建议:改设置前必先 GET 取全量,改完再 GET 验证。
5.4 阈值行为的实测佐证
阈值两层机制的真实行为已在部署篇第五章实测闭环(官方样例数据 + 上报 API):属性 5 raw=999 触发 Scrutiny 判定(设备状态 0→2,属性状态位 4,附 Observed Failure Rate for Critical Attribute is greater than 10% 判定原因与 failure_rate: 0.5677 年化故障率);smart_status.passed=false 触发厂商判定(0→1);恢复健康数据后状态复位为 0。本章不再重复回显,请参见《Scrutiny Docker Compose 部署指南》5.3 节。
六、数据存储与升级迁移
6.1 SQLite(元数据)
- 位置:
web.database.location,默认/opt/scrutiny/config/scrutiny.db; - 内容:设备清单(含 Scrutiny UUID)、运行时设置(SettingEntry 表)、任务记录等;
- 特点:单文件、随配置目录整体备份;删除后服务重建会重新自动注册设备(时序数据不在此库,删除它不清指标历史)。
6.2 InfluxDB(指标时序)
Scrutiny 自动管理四个桶并按计划下采样(官方 docs/DOWNSAMPLING.md 原表照录):
| 桶名 | 保留期 | 下采样范围 | 聚合窗口 | 下采样计划 |
|---|---|---|---|---|
metrics | 15 天 | -2w -1w | 1w | 主桶,每周日 01:00 |
metrics_weekly | 9 周 | -2mo -1mo | 1mo | 每月首日 01:30 |
metrics_monthly | 25 个月 | -2y -1y | 1y | 每年首日 02:00 |
metrics_yearly | 永久 | - | - | - |
官方注释的机制说明(原文翻译):Scrutiny 采集的数据量会无限增长,短期需要精确数据、长期趋势只需要聚合数据,因此按计划自动下采样,在保留历史可比性的同时控制库体积。文档同时给出量化预期:单盘运行 5 个月后 metrics 桶约 15 个数据点、metrics_weekly 约 9 个、metrics_monthly 约 3 个。
6.3 升级与迁移
版本升级路径(omnibus 形态):更新版本标签并重建服务(升级命令与实测回显见《Scrutiny Docker Compose 部署指南》第十一章),SQLite 与 InfluxDB 数据目录不变即自动保留。
大版本迁移的两个实测相关事实:
其一,v0.9.0 设备标识迁移:设备主键从 WWN 改为 Scrutiny UUID(由 WWN、型号、序列号生成的 UUIDv5),升级时 SQLite 与 InfluxDB 存量数据自动迁移(Release Notes 说明)。升级后设备 UUID 形态变化属正常现象。
其二,配置键废弃清理:0.9 起删除了 thresholds 配置段等旧键,且服务端对已废弃键采取拒绝启动策略而非静默忽略。升级前对照本篇第三章删除不再存在的键段。
InfluxDB 版本对应关系:omnibus 一体化发行包内嵌 InfluxDB v2.2.0(实测回显见部署篇 4.5 节 health 检查 version: v2.2.0);手动安装外置 InfluxDB 时官方要求 v2.8.0+(官方 README 前置条件)。
七、常见问题
以下问题均为本篇实测真实遇到或源码实证,附证据与解法。
Q1:改了 scrutiny.yaml 为什么没生效?
排查三步:① 文件是否放在服务进程实际读取的路径(omnibus 内为 /opt/scrutiny/config/scrutiny.yaml,对应宿主挂载的 ./config/scrutiny.yaml);② 启动日志确认加载状态——Loading configuration file: ... 为已加载,No configuration file found ... Using Defaults. 为未加载(实测回显见第一章);③ 改后是否重启服务(文件配置仅启动时读取;只有 /api/settings 运行时设置保存即生效)。
Q2:POST /api/settings 返回 success 但设置全变零值?
真实踩坑:请求体误用了 GET 响应的包裹形态。GET /api/settings 返回 {"settings": {...}, "success": true},而 POST 要求请求体直接就是 Settings 对象(不包 settings 键)。带包裹键 POST 会被服务端按空对象保存且不报错(源码 save_settings.go 直接 c.BindJSON)。修复:按第五章 5.3 节的正确形态重发全量对象,GET 验证恢复。
Q3:升级后服务起不来,报配置校验错误?
0.9 系列对已废弃键(如 thresholds 段、notify.level)拒绝启动并输出配置校验错误。按第三章、第四章的键位表清理 scrutiny.yaml/collector.yaml 中不再存在的键段后重启即可。这也是 0.8 → 0.9 升级的第一动作。
Q4:环境变量与配置文件同时存在时谁赢?
环境变量优先(viper 的绑定顺序:环境变量覆盖文件配置)。服务端前缀 SCRUTINY_(如 SCRUTINY_WEB_LISTEN_PORT),采集端前缀 COLLECTOR_(如 COLLECTOR_API_ENDPOINT、COLLECTOR_CRON_SCHEDULE)。适合不落盘的临时覆盖;正式调整建议仍写配置文件,语义清晰可审计。
Q5:内嵌 InfluxDB 的默认凭据安全吗?
不安全,默认值公开写在源码中(init_password: password12345、token: scrutiny-default-admin-token)。内网部署至少做到:不把 8086 管理端口映射到宿主;外置 InfluxDB 或公网暴露场景必须改 token 并同步 web.influxdb.token。本篇文档与实测环境均未映射生产凭据。
Q6:/api/health/notify 测试通知返回 500?
实测回显 {"success":false},日志 No notification endpoints configured. Skipping failure notification.——原因是 notify.urls 为空(默认 [])。配置至少一条 Shoutrrr URL 后重试即返回 200。若仍 500,检查 URL 凭据中的特殊字符是否已 URL 编码(官方示例见第三章 3.7 节)。
Q7:运行时设置和 scrutiny.yaml 里的 notify 有什么区别?
scrutiny.yaml 的 notify.urls 管「发到哪里」(渠道凭据,重启生效);运行时设置的 metrics.notify_level、metrics.repeat_notifications 管「何时发、是否重复」(面板保存即生效)。两层各管一半,配置通知时缺一不可。
八、参考链接
- 服务端示例配置(本篇第三章依据):https://github.com/AnalogJ/scrutiny/blob/v0.9.5/example.scrutiny.yaml
- 采集端示例配置(本篇第四章依据):https://github.com/AnalogJ/scrutiny/blob/v0.9.5/example.collector.yaml
- 服务端配置源码(默认值与环境变量映射):https://github.com/AnalogJ/scrutiny/blob/v0.9.5/webapp/backend/pkg/config/config.go
- 运行时设置模型与状态枚举:https://github.com/AnalogJ/scrutiny/blob/v0.9.5/webapp/backend/pkg/models/settings.go 、https://github.com/AnalogJ/scrutiny/blob/v0.9.5/webapp/backend/pkg/constants.go
- 阈值元数据目录(ATA/NVMe/SCSI):https://github.com/AnalogJ/scrutiny/tree/v0.9.5/webapp/backend/pkg/thresholds
- 数据下采样说明:https://github.com/AnalogJ/scrutiny/blob/v0.9.5/docs/DOWNSAMPLING.md
- 反向代理子路径排障:https://github.com/AnalogJ/scrutiny/blob/v0.9.5/docs/TROUBLESHOOTING_REVERSE_PROXY.md
- Shoutrrr 服务文档(notify.urls 写法):https://shoutrrr.nickfedor.com/services/overview/
- v0.9.0 Release Notes(UUID 迁移说明):https://github.com/AnalogJ/scrutiny/releases/tag/v0.9.0