Add read-only svc.sh info report for services, databases, and config snapshots
Why: svc.sh could show a service table (list), per-instance DB names one at a time (db ls), and per-service status, but had no single view answering "what is running, which databases exist, and what is configured" -- the questions asked when inspecting or handing over a machine. Evidence: exercised in the task worktree runtime -- empty-state report; fake agent/static/postgres registrations proving masking (exec DSN password, password=, SVC_TAVILY_KEYS -> ***, non-secret values verbatim; --reveal shows plaintext); a real postgres instance (db create r-pg --port 18901, start, extra orders db, one backup) whose info section lists inner databases with sizes, pgdata size and backup stats; regressions list/history/--help/help lifecycle/make svc-info; info stdout carries the full report (stderr 0 bytes) so it can be redirected as a snapshot. Full log in the task card. Impact: new read-only `scripts/svc.sh info [name] [--tag T] [--reveal]` command (also `make svc-info`): service table + running summary, postgres instances incl. inner databases, per-service svc.env content snapshots plus global .svc.env / --config / exported SVC_* vars, and recent events. Secrets are masked by default. No deploy/lifecycle/db-ops behavior changes; `info` becomes a reserved service name; docs/svc.md gains section 6.2 (former 6.2-6.4 shifted to 6.3-6.5). Refs: task card .task/feature-svc-info.md (same doc as the PR); docs/svc.md
This commit is contained in:
@@ -6,11 +6,29 @@
|
||||
|
||||
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 1263e7f7d10eb4d58fcfc39a7cd4c5c963a30ff6
|
||||
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-svc-info(worktree);分支:feature/svc-info
|
||||
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
|
||||
- 授权与交付终点:实现 `scripts/svc.sh info` 综合信息报告(只读);终点 = PR 合入 main(附 precheck / task-sync / 功能验证三段证据)
|
||||
|
||||
## 目标与非目标
|
||||
|
||||
<预期结果、受影响入口/模块/契约;明确不做什么。>
|
||||
目标:
|
||||
- 新增全局子命令 `scripts/svc.sh info [name] [--tag T] [--reveal]`,一条命令展示本机现场:
|
||||
运行中的服务(list 表格 + 运行汇总)、postgres 实例详情(含运行中实例的**内部数据库
|
||||
列表与大小**、数据目录/备份体量)、配置文件与内容快照(逐服务 svc.env、全局 .svc.env、
|
||||
本次 --config、shell 层 SVC_* 变量)、最近事件。
|
||||
- 敏感值默认掩码(password=、键名含 KEY/PASS/SECRET/TOKEN/DSN、DSN 内密码段),
|
||||
`--reveal` 才显示;报告整体走 stdout 便于整页保存。
|
||||
- 同步更新:usage/usage_short/help(lifecycle、model 保留字补全 update/info)、docs/svc.md
|
||||
(新 §6.2,原 6.2-6.4 顺延 6.3-6.5)、Makefile(svc-info 目标 + help)。
|
||||
|
||||
非目标:不改 deploy/生命周期/db 运维任何行为;不做 JSON 输出;不涉 Web UI。
|
||||
|
||||
## 实现摘要
|
||||
|
||||
- `info` 加入保留字(RESERVED_ENVS 与 help model 文档同步补全)。
|
||||
- 复用与抽取:`registered_names`(global_list 复用)、`history_print_rows`(cmd_history 复用);
|
||||
新增 mask_dsn/mask_kv(掩码)、info_pg_block/info_config_block/info_global_config/
|
||||
info_names_filtered、cmd_info。
|
||||
- main() 分派 `info` 子命令;make svc-info。
|
||||
|
||||
## 同步记录
|
||||
|
||||
@@ -20,6 +38,17 @@
|
||||
|
||||
## 结果与验证(完成后填写)
|
||||
|
||||
- 结果:
|
||||
- 验证:
|
||||
- 影响与剩余项:
|
||||
- 结果:已实现。`svc.sh info`(全景:服务表+汇总/数据库实例+内部库/配置快照/最近事件)、
|
||||
`info <name>`(单服务深度)、`--tag` 过滤、`--reveal` 显示敏感值;退出码:0 成功、2 用法错误。
|
||||
- 验证(worktree runtime 内实测,2026-10-04):
|
||||
- `bash -n` 通过(shellcheck 本机不可用);
|
||||
- 空 runtime:五节报告友好空态,exit 0;
|
||||
- 伪造登记(agent+DSN 密码 / static / postgres 停机 + 备份文件 + .svc.env 含
|
||||
SVC_TAVILY_KEYS):全景报告正确;掩码实测——exec 内 DSN 密码→`***`、`password=***`、
|
||||
`SVC_TAVILY_KEYS=***`、非敏感值原样;`--reveal` 显示明文;
|
||||
- 真实 postgres:`db create r-pg --port 18901` → start → 建额外库 orders → db backup →
|
||||
info 数据库节显示"运行中 pid、内部库 postgres/agent/orders 及大小、pgdata 43M、
|
||||
备份 1 份";`rm r-pg --purge` 回收;测试现场(伪造登记/.svc.env)全部清除;
|
||||
- 回归:`list` / `history` / `--help` / `help lifecycle` / `make svc-info` 均正常;
|
||||
`info` stdout 纯净(stderr 0 字节),可整页重定向。
|
||||
- 影响与剩余项:无行为变更(info 只读);剩余项无。
|
||||
|
||||
@@ -13,7 +13,7 @@ PLUGINS := plugins
|
||||
COMBO := core=$(shell git -C $(CORE) rev-parse --short HEAD 2>/dev/null)+backend=$(shell git -C $(BACKEND) rev-parse --short HEAD 2>/dev/null)+frontend=$(shell git -C $(FRONTEND) rev-parse --short HEAD 2>/dev/null)+ui=$(shell git -C $(UI) rev-parse --short HEAD 2>/dev/null)+agentcmd=$(shell git -C deps/agent-command rev-parse --short HEAD 2>/dev/null)+documents=$(shell git -C modules/documents rev-parse --short HEAD 2>/dev/null)+native=$(shell git -C deps/agent-native rev-parse --short HEAD 2>/dev/null)+squad=$(shell git -C deps/agent-squad rev-parse --short HEAD 2>/dev/null)+intent=$(shell git -C deps/agent-intent rev-parse --short HEAD 2>/dev/null)
|
||||
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null)+$(COMBO)
|
||||
|
||||
.PHONY: help sync status build frontend svc svc-list svc-commits svc-history svc-update test-backend test-frontend test-ui test-core test-agentcmd test-pins test-libs dev pin clean setup precheck task-start task-sync task-close task-finish version
|
||||
.PHONY: help sync status build frontend svc svc-list svc-info svc-commits svc-history svc-update test-backend test-frontend test-ui test-core test-agentcmd test-pins test-libs dev pin clean setup precheck task-start task-sync task-close task-finish version
|
||||
|
||||
version:
|
||||
@echo "agent-system $(VERSION)"
|
||||
@@ -47,6 +47,7 @@ help:
|
||||
@echo "make test 全量测试(boundaries + pins + libs + core + backend + frontend + ui + agent-command)"
|
||||
@echo "make svc 服务级操作:make svc ENV=<name> [ACTION=deploy|start|stop|restart|status|logs] [ARGS='--from dev@<sha> --tag ...']"
|
||||
@echo "make svc-list 服务总览:make svc-list [ARGS='--tag core'];数据库运维:scripts/svc.sh db create|dsn|backup|backups|restore|clone|copy|ls|set"
|
||||
@echo "make svc-info 综合信息报告(只读):make svc-info [ARGS='pg1 --reveal']——运行服务/数据库实例与内部库/配置快照"
|
||||
@echo "make svc-commits 列出可部署提交:make svc-commits SRC=dev|release [N=20]"
|
||||
@echo "make svc-history 事件历史:make svc-history [ENV] [N=20](完整文档:docs/svc.md)"
|
||||
@echo "make svc-update 自动更新过时服务:make svc-update [NAMES='dev pg1'] [ARGS='--check --all']"
|
||||
@@ -128,6 +129,9 @@ svc:
|
||||
svc-list:
|
||||
scripts/svc.sh list $(ARGS)
|
||||
|
||||
svc-info:
|
||||
scripts/svc.sh info $(ARGS)
|
||||
|
||||
svc-commits:
|
||||
@test -n "$(SRC)" || (echo "用法:make svc-commits SRC=dev|release [N=20]"; exit 2)
|
||||
scripts/svc.sh commits $(SRC) $(N)
|
||||
|
||||
+36
-4
@@ -67,6 +67,7 @@ scripts/svc.sh prod deploy --from dev@<sha> \
|
||||
|
||||
# 日常操作
|
||||
scripts/svc.sh list # 全服务总览
|
||||
scripts/svc.sh info # 综合报告:运行服务/数据库/配置快照
|
||||
scripts/svc.sh pg1 restart # 重启(复用上次配置)
|
||||
scripts/svc.sh prod logs 100 # 跟日志
|
||||
scripts/svc.sh history # 事件追溯
|
||||
@@ -87,7 +88,7 @@ scripts/svc.sh update # 自动更新过时且运行
|
||||
|
||||
`^[a-z][a-z0-9-]{0,15}$`(小写字母开头,可含数字与连字符,≤16 位)。保留字不可用作
|
||||
服务名:`status list add set db rm create dsn commits history update deploy stop start
|
||||
restart logs help version`。
|
||||
restart logs help info version`。
|
||||
|
||||
三个名字有默认端口:`dev` = `127.0.0.1:8788`,`prod` = `127.0.0.1:8787`;其余名字按
|
||||
名称哈希在 **8800–9099** 确定性派生端口,与已登记端口或正在监听的端口冲突时自动向后
|
||||
@@ -296,7 +297,38 @@ STATE 的判定:pidfile 存在且 `/proc/<pid>/cmdline` 匹配登记的 `pidch
|
||||
(agent=二进制路径、postgres=pgdata 路径、static=`--directory <目录>`)。进程被人手动
|
||||
杀掉后 STATE 自动落回"未运行",不会误报。
|
||||
|
||||
### 6.2 history(事件追溯)
|
||||
### 6.2 info(综合信息报告,只读)
|
||||
|
||||
```bash
|
||||
scripts/svc.sh info [name] [--tag T] [--reveal]
|
||||
```
|
||||
|
||||
一条命令看全本机现场:**正在运行哪些服务、有哪些数据库(含实例内部库)、每个服务
|
||||
的配置文件与内容快照**。全程只读,不改任何登记、进程与文件。
|
||||
|
||||
| 用法 | 行为 |
|
||||
|---|---|
|
||||
| `info` | 全景报告(下述五节全量) |
|
||||
| `info pg1` | 单服务深度报告:状态详情 +(postgres)实例与内部库 + 配置快照 + 最近事件 |
|
||||
| `info --tag core` | 服务名/数据库/配置/事件均按标签过滤(与 `list --tag` 同语义) |
|
||||
| `info --reveal` | 显示默认掩码的敏感值(DB 密码、API key、DSN 密码) |
|
||||
|
||||
报告分节(整体走 stdout,可直接 `> snapshot.txt` 整页保存):
|
||||
|
||||
1. **服务**——`list` 同款表格 + 汇总行(`N 已登记 / M 运行中(agent a、postgres p、static s)`);
|
||||
2. **数据库**——每个 postgres 实例一屏:运行状态/地址、版本/用户/认证/默认库/来源、
|
||||
数据目录与体量、备份份数与最近一份;**运行中的实例直接列出内部数据库及大小**
|
||||
(未运行则注明内部库不可见);
|
||||
3. **配置**——逐服务 `runtime/<name>/svc.env` 的文件路径、权限与逐行内容快照,加上
|
||||
全局层:`.svc.env`(自动加载层)、本次 `--config/--env` 文件、shell 已导出的
|
||||
`SVC_*` 变量;
|
||||
4. **最近事件**——各服务 history 最近 5 条(完整历史走 `history`)。
|
||||
|
||||
敏感值默认掩码:`password=` 键、键名含 `KEY/PASS/SECRET/TOKEN/DSN` 的值整段掩为
|
||||
`***`,`exec=` 里 DSN 的密码段同样掩码;`--reveal` 才显示明文。掩码规则与
|
||||
`db dsn`(默认掩密码)一致,便于把报告贴进工单/日志而不泄密。
|
||||
|
||||
### 6.3 history(事件追溯)
|
||||
|
||||
```bash
|
||||
scripts/svc.sh history [name] [N] # 默认全部服务、最近 20 条;首参为纯数字时视为条数
|
||||
@@ -305,7 +337,7 @@ scripts/svc.sh history [name] [N] # 默认全部服务、最近 20 条;首
|
||||
合并各服务 `history.jsonl`(按时间排序),字段:时间 / 服务 / kind / 事件 / 结果 /
|
||||
来源 / pid / 详情。事件类型见 §10.2。
|
||||
|
||||
### 6.3 update(自动检索并更新)
|
||||
### 6.4 update(自动检索并更新)
|
||||
|
||||
```bash
|
||||
scripts/svc.sh update [name...] [--check] [--all] [--no-fetch]
|
||||
@@ -341,7 +373,7 @@ scripts/svc.sh update [name...] [--check] [--all] [--no-fetch]
|
||||
任一服务失败不中断其余服务;最终汇总 `成功/失败/跳过`。退出码:0 全部成功或最新;
|
||||
1 有失败;2 用法错误。
|
||||
|
||||
### 6.4 help
|
||||
### 6.5 help
|
||||
|
||||
```bash
|
||||
scripts/svc.sh # 一屏速览(短帮助)
|
||||
|
||||
+269
-8
@@ -6,6 +6,7 @@
|
||||
# ════════════════════ 命令一览 ════════════════════
|
||||
# scripts/svc.sh <name> [action] [参数...] 服务级:deploy(默认)|start|stop|restart|status|logs [N]
|
||||
# scripts/svc.sh list [--tag T] 服务总览(status 等价)
|
||||
# scripts/svc.sh info [name] [--tag T] [--reveal] 综合报告(只读):服务/数据库/配置快照/最近事件
|
||||
# scripts/svc.sh set <name> [--port N --apply] [--tag T] 变更登记(换端口/标签)
|
||||
# scripts/svc.sh rm <name> [--purge] 注销服务(--purge 连数据目录删除)
|
||||
# scripts/svc.sh db create <name> [参数] 创建 PostgreSQL 实例(initdb)
|
||||
@@ -71,6 +72,7 @@
|
||||
# scripts/svc.sh db copy pg1 pg2 --db app # 把 pg1 的 app 库搬到 pg2
|
||||
# scripts/svc.sh db restore pg2 --file <dump> --db app --force
|
||||
# scripts/svc.sh list --tag core && scripts/svc.sh history
|
||||
# scripts/svc.sh info && scripts/svc.sh info pg1 --reveal # 全景报告 / 单服务深度(含掩码值)
|
||||
# scripts/svc.sh pg1 restart && scripts/svc.sh rm tmp1 --purge
|
||||
# make svc ENV=dev ARGS="--env .env.dev --port 9000"
|
||||
#
|
||||
@@ -117,6 +119,7 @@ svc.sh —— 本机服务管理:后端(agent) / 前端(static) / 数据库(po
|
||||
|
||||
常用:
|
||||
scripts/svc.sh list [--tag T] 服务总览
|
||||
scripts/svc.sh info [name] [--tag T --reveal] 综合报告(只读):服务/数据库/配置快照
|
||||
scripts/svc.sh <name> deploy [--from dev@<sha>] 部署并启动(缺省=远端 main 最新)
|
||||
scripts/svc.sh <name> start|stop|restart|logs [N] 生命周期与日志
|
||||
scripts/svc.sh <name> status 服务详情(版本/来源/DSN 等)
|
||||
@@ -159,7 +162,7 @@ EOF
|
||||
|
||||
服务名:^[a-z][a-z0-9-]{0,15}$(小写字母开头,可含数字与连字符,≤16 位)。
|
||||
保留字不可用作服务名:status list add set db rm create dsn commits history
|
||||
deploy stop start restart logs help version。
|
||||
update deploy stop start restart logs help info version。
|
||||
|
||||
目录布局(每个服务自包含,互不串版本):
|
||||
runtime/<name>/
|
||||
@@ -253,6 +256,9 @@ EOF
|
||||
scripts/svc.sh <name> logs [N] 跟随日志(默认 50 行起;如 svc.sh pg1 logs 200)
|
||||
scripts/svc.sh <name> status 单服务详情(kind/状态/地址/来源/版本/标签/DSN/目录)
|
||||
scripts/svc.sh list [--tag T] 全服务表格:NAME KIND STATE PID ADDR SOURCE TAGS
|
||||
scripts/svc.sh info [name] [--tag T --reveal] 综合报告(只读):服务表+运行汇总 /
|
||||
postgres 实例与内部库 / 配置文件内容快照(敏感值默认掩码)/
|
||||
最近事件;带 name 时输出单服务深度报告
|
||||
scripts/svc.sh history [name] [N] 事件历史(首参为纯数字时视为条数)
|
||||
|
||||
变更登记(不动进程,除 --apply):
|
||||
@@ -532,7 +538,7 @@ addr_compose() {
|
||||
}
|
||||
|
||||
# ---- 名称与端口 ----
|
||||
RESERVED_ENVS=" status list add set db rm create dsn commits history update deploy stop start restart logs help version "
|
||||
RESERVED_ENVS=" status list add set db rm create dsn commits history update deploy stop start restart logs help info version "
|
||||
|
||||
# valid_env NAME:服务名合法性(小写字母开头、a-z0-9-、≤16 位;保留字不可用)。
|
||||
valid_env() {
|
||||
@@ -1996,17 +2002,24 @@ svc_pid_state() { # NAME → "alive <pid>" | "dead"
|
||||
return 0
|
||||
}
|
||||
|
||||
global_list() {
|
||||
c_info "服务总览(root: $ROOT)"
|
||||
printf ' %-12s %-9s %-7s %-8s %-20s %-24s %s\n' NAME KIND STATE PID ADDR SOURCE TAGS
|
||||
local names=() d e name kind addr src tags st
|
||||
# registered_names:runtime 下已登记服务名(stdout 每行一个;list/info 共用)。
|
||||
registered_names() {
|
||||
local d e
|
||||
for d in "$RUNTIME"/*/; do
|
||||
[ -f "${d}svc.env" ] || continue
|
||||
e="$(basename "$d")"
|
||||
[ "$e" = ".worktrees" ] && continue
|
||||
valid_env "$e" || continue
|
||||
names+=("$e")
|
||||
printf '%s\n' "$e"
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
global_list() {
|
||||
c_info "服务总览(root: $ROOT)"
|
||||
printf ' %-12s %-9s %-7s %-8s %-20s %-24s %s\n' NAME KIND STATE PID ADDR SOURCE TAGS
|
||||
local names=() d name kind addr src tags st
|
||||
while IFS= read -r name; do names+=("$name"); done < <(registered_names)
|
||||
for name in ${names[@]+"${names[@]}"}; do
|
||||
d="$RUNTIME/$name"
|
||||
kind="$(sed -n 's/^kind=//p' "$d/svc.env" | head -1)"; [ -n "$kind" ] || kind=agent
|
||||
@@ -2079,12 +2092,259 @@ cmd_history() {
|
||||
fi
|
||||
fi
|
||||
c_info "事件历史($([ -n "$env" ] && echo "服务 $env" || echo "全部服务"),最近 $n 条)"
|
||||
cat "${files[@]}" | sort | tail -n "$n" | while IFS= read -r l; do
|
||||
history_print_rows "$n" "${files[@]}"
|
||||
}
|
||||
|
||||
# history_print_rows N FILES...:合并多个 history.jsonl、按时间排序、取最近 N 条打印
|
||||
# (cmd_history 与 info 共用;行格式:时间/服务/kind/事件/结果/来源/pid/详情)。
|
||||
history_print_rows() {
|
||||
local n="$1"; shift
|
||||
cat "$@" | sort | tail -n "$n" | while IFS= read -r l; do
|
||||
[ -n "$l" ] || continue
|
||||
printf ' %s %-10s %-9s %-8s %-6s %-24s %-7s %s\n' \
|
||||
"$(jfield ts "$l")" "$(jfield env "$l")" "$(jfield kind "$l")" "$(jfield event "$l")" \
|
||||
"$(jfield result "$l")" "$(jfield source "$l")" "$(jfield pid "$l")" "$(jfield detail "$l")"
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
# ---- info:综合信息报告(只读) ----
|
||||
# 报告整体走 stdout(区别于提示走 stderr 的惯例)——info 的产物就是报告本身,
|
||||
# 便于整页重定向/保存为快照;敏感值默认掩码,--reveal 才显示。
|
||||
|
||||
# mask_dsn STRING:把 postgres DSN 里的密码掩为 ***(postgresql://user:pass@ → user:***@)。
|
||||
mask_dsn() {
|
||||
printf '%s' "$1" | sed -E 's#(postgres(ql)?://[^:/@[:space:]]+:)[^@[:space:]]+@#\1***@#g'
|
||||
}
|
||||
|
||||
# mask_kv LINE:KEY=VALUE 行的敏感值掩码——password 键与键名含 KEY/PASS/SECRET/
|
||||
# TOKEN/DSN 的值整段掩为 ***;其余行只掩值内 DSN 密码(exec= 里可能带完整连接串)。
|
||||
mask_kv() {
|
||||
local line="$1" k="${1%%=*}"
|
||||
if [ "$k" != "$1" ]; then
|
||||
case "$k" in
|
||||
password|*KEY*|*PASS*|*SECRET*|*TOKEN*|*DSN*)
|
||||
printf '%s=***' "$k"; return 0 ;;
|
||||
esac
|
||||
fi
|
||||
mask_dsn "$line"
|
||||
}
|
||||
|
||||
# info_section TITLE:stdout 分节标题。
|
||||
info_section() { printf '\n────── %s ──────\n' "$*"; }
|
||||
|
||||
# info_du PATH:目录/文件大小(du -sh;不存在或失败回 '-')。
|
||||
info_du() {
|
||||
local s=""
|
||||
[ -e "$1" ] && s="$(du -sh "$1" 2>/dev/null | cut -f1)"
|
||||
printf '%s' "${s:--}"
|
||||
}
|
||||
|
||||
# info_file_mode PATH:八进制权限(不存在回 '-')。
|
||||
info_file_mode() {
|
||||
local m=""
|
||||
[ -f "$1" ] && m="$(stat -c %a "$1" 2>/dev/null || true)"
|
||||
printf '%s' "${m:--}"
|
||||
}
|
||||
|
||||
# env_kv_of NAME KEY:读 runtime/<name>/svc.env 单键首个值(不依赖 ENV_* 全局,
|
||||
# info 遍历多服务时使用;无则空)。
|
||||
env_kv_of() {
|
||||
[ -f "$RUNTIME/$1/svc.env" ] || return 0
|
||||
sed -n "s/^$2=//p" "$RUNTIME/$1/svc.env" | head -1
|
||||
}
|
||||
|
||||
# info_snapshot_lines FILE:逐行打印 KEY=VALUE 内容快照(按 CLI_REVEAL 决定掩码)。
|
||||
info_snapshot_lines() {
|
||||
local line
|
||||
while IFS= read -r line || [ -n "$line" ]; do
|
||||
[ -n "$line" ] || continue
|
||||
if [ "$CLI_REVEAL" = 1 ]; then printf ' %s\n' "$line"
|
||||
else printf ' %s\n' "$(mask_kv "$line")"; fi
|
||||
done < "$1"
|
||||
return 0
|
||||
}
|
||||
|
||||
# info_pg_block NAME:postgres 实例详情块——登记信息、数据目录与备份体量;
|
||||
# 运行中则列出实例内部数据库(含大小,按大小降序)。
|
||||
info_pg_block() {
|
||||
local name="$1" d="$RUNTIME/$1"
|
||||
local addr user db auth ver pgdata src st pass rows
|
||||
addr="$(env_kv_of "$name" addr)"
|
||||
user="$(env_kv_of "$name" user)"
|
||||
db="$(env_kv_of "$name" dbname)"
|
||||
auth="$(env_kv_of "$name" authmode)"
|
||||
ver="$(env_kv_of "$name" version)"
|
||||
pgdata="$(env_kv_of "$name" pgdata)"
|
||||
src="$(env_kv_of "$name" source)"
|
||||
st="$(svc_pid_state "$name")"
|
||||
if [ "${st%% *}" = alive ]; then
|
||||
printf ' [%s] postgres 运行中 pid=%s → %s\n' "$name" "${st#alive }" "$addr"
|
||||
else
|
||||
printf ' [%s] postgres 未运行(内部库不可见,start 后可列出) → %s\n' "$name" "${addr:--}"
|
||||
fi
|
||||
printf ' 版本 %s 用户 %s 认证 %s 默认库 %s 来源 %s\n' \
|
||||
"${ver:--}" "${user:--}" "${auth:--}" "${db:--}" "${src:--}"
|
||||
[ -n "$pgdata" ] && printf ' 数据目录 %s(%s)\n' "$pgdata" "$(info_du "$pgdata")"
|
||||
local nb=0 bsize="" latest="" f
|
||||
if [ -d "$d/backups" ]; then
|
||||
for f in "$d/backups"/*.dump; do
|
||||
[ -f "$f" ] || continue
|
||||
nb=$((nb + 1))
|
||||
latest="$f"
|
||||
done
|
||||
[ "$nb" -gt 0 ] && bsize="$(info_du "$d/backups")"
|
||||
fi
|
||||
if [ "$nb" -gt 0 ]; then
|
||||
printf ' 备份 %d 份(合计 %s,最近 %s)\n' "$nb" "$bsize" "$(basename "$latest")"
|
||||
else
|
||||
printf ' 备份 0 份\n'
|
||||
fi
|
||||
if [ "${st%% *}" = alive ]; then
|
||||
pass="$(env_kv_of "$name" password)"
|
||||
rows="$(pg_run "${addr%:*}" "${addr##*:}" "$user" "$pass" postgres \
|
||||
"SELECT datname || '|' || pg_size_pretty(pg_database_size(datname)) FROM pg_database WHERE NOT datistemplate ORDER BY pg_database_size(datname) DESC" tA)" || rows=""
|
||||
if [ -n "$rows" ]; then
|
||||
printf ' 内部库:\n'
|
||||
printf '%s\n' "$rows" | while IFS='|' read -r dn ds; do
|
||||
printf ' %-24s %s\n' "$dn" "$ds"
|
||||
done
|
||||
else
|
||||
printf ' 内部库:查询失败(psql 连接异常)\n'
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# info_config_block NAME:单服务 svc.env 内容快照(文件路径+权限+逐行内容)。
|
||||
info_config_block() {
|
||||
local name="$1" f="$RUNTIME/$1/svc.env"
|
||||
printf ' [%s] %s(权限 %s,kind=%s)\n' "$name" "$f" "$(info_file_mode "$f")" "$(svc_kind "$name")"
|
||||
info_snapshot_lines "$f"
|
||||
return 0
|
||||
}
|
||||
|
||||
# info_global_config:全局配置层快照——$ROOT/.svc.env(自动加载层)、本次 --config
|
||||
# 文件、shell 层已导出的 SVC_* 变量;值同掩码规则。
|
||||
info_global_config() {
|
||||
local f="$ROOT/.svc.env" exported=""
|
||||
if [ -f "$f" ]; then
|
||||
printf ' %s(自动加载层,权限 %s)\n' "$f" "$(info_file_mode "$f")"
|
||||
info_snapshot_lines "$f"
|
||||
else
|
||||
printf ' .svc.env(自动加载层):不存在\n'
|
||||
fi
|
||||
[ -n "${SVC_ENVFILE:-}" ] && printf ' 本次 --config/--env 文件:%s(值已并入生效配置)\n' "$SVC_ENVFILE"
|
||||
exported="$(env | grep '^SVC_' | sort || true)"
|
||||
if [ -n "$exported" ]; then
|
||||
printf ' shell 层已导出的 SVC_* 变量:\n'
|
||||
if [ "$CLI_REVEAL" = 1 ]; then
|
||||
printf '%s\n' "$exported" | sed 's/^/ /'
|
||||
else
|
||||
printf '%s\n' "$exported" | while IFS= read -r line; do printf ' %s\n' "$(mask_kv "$line")"; done
|
||||
fi
|
||||
else
|
||||
printf ' shell 层 SVC_* 变量:无(.svc.env 里的值是脚本内层变量,不出现在 env)\n'
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# info_names_filtered:LIST_TAG 过滤后的已登记服务名(stdout 每行一个;与
|
||||
# global_list 的 --tag 过滤同一语义)。
|
||||
info_names_filtered() {
|
||||
local name tags
|
||||
while IFS= read -r name; do
|
||||
if [ -n "${LIST_TAG:-}" ]; then
|
||||
tags="$(env_kv_of "$name" tags)"
|
||||
case ",$tags," in *",${LIST_TAG},"*) ;; *) continue ;; esac
|
||||
fi
|
||||
printf '%s\n' "$name"
|
||||
done < <(registered_names)
|
||||
return 0
|
||||
}
|
||||
|
||||
# cmd_info [NAME] [--tag T] [--reveal]:综合信息报告(只读)。
|
||||
# 无名 = 全景:服务表+运行汇总 → postgres 实例与内部库 → 各服务 svc.env 快照 +
|
||||
# 全局配置层 → 最近事件;有名 = 单服务深度:状态详情 +(postgres)实例 + 快照 + 事件。
|
||||
cmd_info() {
|
||||
CLI_REVEAL=0; LIST_TAG=""
|
||||
local name=""
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--reveal) CLI_REVEAL=1; shift ;;
|
||||
--tag) need_value "$@"; LIST_TAG="$2"; shift 2 ;;
|
||||
-h|--help) cmd_help lifecycle; return 0 ;;
|
||||
-*) c_err "info 未知参数:$1(可用:--tag T --reveal)"; return 2 ;;
|
||||
*) [ -z "$name" ] || { c_err "info 只接受一个服务名"; return 2; }
|
||||
name="$1"; shift ;;
|
||||
esac
|
||||
done
|
||||
if [ -n "$name" ]; then
|
||||
valid_env "$name" || { c_err "非法服务名:$name"; return 2; }
|
||||
[ -f "$RUNTIME/$name/svc.env" ] || { c_err "[$name] 无登记(scripts/svc.sh list 查看)"; return 2; }
|
||||
env_config "$name"
|
||||
info_section "服务 $name"
|
||||
env_status_detail
|
||||
if [ "$SVC_KIND" = postgres ]; then
|
||||
info_section "数据库实例 $name"
|
||||
info_pg_block "$name"
|
||||
fi
|
||||
info_section "配置快照 $name"
|
||||
info_config_block "$name"
|
||||
info_section "最近事件 $name"
|
||||
local hf="$RUNTIME/$name/history.jsonl"
|
||||
if [ -f "$hf" ]; then history_print_rows 5 "$hf"
|
||||
else printf ' (暂无事件)\n'; fi
|
||||
return 0
|
||||
fi
|
||||
# 全景报告。
|
||||
local names=() n kind st total=0 running=0 ka=0 kp=0 ks=0
|
||||
while IFS= read -r n; do names+=("$n"); done < <(info_names_filtered)
|
||||
info_section "服务"
|
||||
global_list
|
||||
for n in ${names[@]+"${names[@]}"}; do
|
||||
total=$((total + 1))
|
||||
st="$(svc_pid_state "$n")"
|
||||
[ "${st%% *}" = alive ] || continue
|
||||
running=$((running + 1))
|
||||
case "$(svc_kind "$n")" in
|
||||
agent) ka=$((ka + 1)) ;;
|
||||
postgres) kp=$((kp + 1)) ;;
|
||||
static) ks=$((ks + 1)) ;;
|
||||
esac
|
||||
done
|
||||
[ "$total" -gt 0 ] && printf ' 汇总:%d 已登记 / %d 运行中(agent %d、postgres %d、static %d)\n' \
|
||||
"$total" "$running" "$ka" "$kp" "$ks"
|
||||
info_section "数据库"
|
||||
local pgs=()
|
||||
for n in ${names[@]+"${names[@]}"}; do
|
||||
[ "$(svc_kind "$n")" = postgres ] && pgs+=("$n")
|
||||
done
|
||||
if [ "${#pgs[@]}" -eq 0 ]; then
|
||||
printf ' (无 postgres 实例;scripts/svc.sh db create <name> 创建)\n'
|
||||
else
|
||||
for n in ${pgs[@]+"${pgs[@]}"}; do info_pg_block "$n"; done
|
||||
fi
|
||||
info_section "配置"
|
||||
if [ "${#names[@]}" -eq 0 ]; then
|
||||
printf ' (无已登记服务)\n'
|
||||
else
|
||||
for n in ${names[@]+"${names[@]}"}; do info_config_block "$n"; done
|
||||
fi
|
||||
info_global_config
|
||||
info_section "最近事件"
|
||||
local files=() f
|
||||
for n in ${names[@]+"${names[@]}"}; do
|
||||
f="$RUNTIME/$n/history.jsonl"
|
||||
[ -f "$f" ] && files+=("$f")
|
||||
done
|
||||
if [ "${#files[@]}" -eq 0 ]; then
|
||||
printf ' (暂无事件)\n'
|
||||
else
|
||||
history_print_rows 5 "${files[@]}"
|
||||
printf ' (更多:scripts/svc.sh history%s)\n' "${LIST_TAG:+ --tag 对应服务名}"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# ---- 自动检索与更新 ----
|
||||
@@ -2297,6 +2557,7 @@ main() {
|
||||
db) shift; cmd_db "$@"; exit 0 ;;
|
||||
set) shift; cmd_set "$@"; exit 0 ;;
|
||||
rm) shift; cmd_rm "$@"; exit 0 ;;
|
||||
info) shift; cmd_info "$@" || exit $?; exit 0 ;;
|
||||
commits) shift; cmd_commits "$@"; exit 0 ;;
|
||||
history) shift; cmd_history "$@"; exit 0 ;;
|
||||
update) shift; cmd_update "$@" || exit $?; exit 0 ;;
|
||||
|
||||
Reference in New Issue
Block a user