refactor(patrol): 監控頁改成固定三塊
巡檢產出與監控頁範本改成固定三塊:本頁基本資料、最新一輪、近 24 輪摘要。 舊寫法是一輪附加一節。十五分鐘跑一輪,一天就疊出九十六節,那樣的頁沒 有人讀得完,也就沒有人會發現助理壞在哪一輪。軌跡留著卻沒人看,等於沒 有留。 基本資料建頁時寫一次就不動。最新一輪每輪整塊換掉,只留最新那一輪的完 整內容。摘要表一輪一列,最新的在最上面,超過 24 列就丟掉最舊的那一列, 一列只有四欄:巡檢時間、本輪判定、四項成敗、待人處理筆數,一眼看得出 是從哪一輪開始壞的。collect 的輸出鍵位跟著換,section_file 不再產出, 改印 latest_file、summary_file 與 summary_row_file,另外多印本輪待人處 理的筆數。範本連帶把流程圖與寫入規則改成先讀回舊頁、再三塊重組整頁寫 回,並寫明舊格式的頁第一次重組要怎麼收。 順手把腳本內部找別的 domain 工具的順序改成 current 連結優先,理由跟排 程那支一樣:技能與權限規則都以 current 為準,腳本自己去挑另一個版本就 會跑到混版的工具,而那種不一致查起來沒有線索。功能範圍是一輪巡檢的收 攏與監控頁產出。
This commit is contained in:
+64
-21
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# collect 帶了 --out,finish 與 abort 就要帶同一個目錄,不然換不到本輪的用量快照。
|
||||
#
|
||||
# collect 讀四項來源、組出監控頁要附加的那一節、把鎖拿在手上。
|
||||
# collect 讀四項來源、組出監控頁那三塊、把鎖拿在手上。
|
||||
# finish 在監控頁寫成功之後才呼叫:寫心跳、換上用量快照、放掉鎖。
|
||||
# abort 在監控頁沒寫成時呼叫:只放掉鎖,不寫心跳。
|
||||
#
|
||||
@@ -16,10 +16,10 @@
|
||||
# 0 collect:四項全部讀到底(含「來源在、沒有資料」);finish:心跳寫好、快照換上、
|
||||
# 鎖放掉;abort:鎖放掉,本來就沒鎖也算
|
||||
# 1 collect:部分成功——至少一項失敗,也至少一項有結果。**結果照樣印得出來,呼叫端
|
||||
# 照樣要把這一節寫上監控頁**,只是本輪判定要標成警示
|
||||
# 照樣要把這一輪寫上監控頁**,只是本輪判定要標成警示
|
||||
# 2 finish:找不到 jsc-hooks 的 hooks/heartbeat.sh,心跳沒有東西可寫。collect 不會回這
|
||||
# 一碼——心跳讀不到只是 D-09 這一項失敗,另外三項照跑
|
||||
# 3 collect:四項全部失敗,一項資料都沒有。這一節還是要寫上監控頁,本輪判定標成異常
|
||||
# 3 collect:四項全部失敗,一項資料都沒有。這一輪還是要寫上監控頁,本輪判定標成異常
|
||||
# 4 上一輪還在跑,本輪讓開(collect),或鎖已經不在自己手上(finish、abort)。這不是
|
||||
# 失敗,是刻意讓開:不寫心跳、不寫監控頁,下一輪再來
|
||||
# 5 檔案系統失敗:鎖建不起來或放不掉、暫存檔寫不進去、快照換不上,或 heartbeat.sh write
|
||||
@@ -43,8 +43,7 @@
|
||||
#
|
||||
# 一輪巡檢包含一次 CLI 呼叫與兩次 wiki 寫入,跑過一個排程週期是有可能的。所以整輪拿一把
|
||||
# 鎖:$JSC_HOME/assistant/patrol.lock 是目錄,mkdir 是原子操作,搶不到就是別人在跑。
|
||||
# 搶不到的那一輪回 4 直接讓開,不排隊、不並行——並行的兩輪會在同一頁附加兩節,還會互相
|
||||
# 蓋掉用量快照。
|
||||
# 搶不到的那一輪回 4 直接讓開,不排隊、不並行——並行的兩輪會互相蓋掉監控頁與用量快照。
|
||||
# 鎖會逾時自動搶回來,門檻取心跳門檻(heartbeat.sh report 的 ttl 欄):上一輪跑得比門檻
|
||||
# 還久,它本來就已經維持不住心跳新鮮了,讓新的一輪接手才對。被搶回來的那一輪,finish 會
|
||||
# 拿 --round 比對出鎖不是自己的,回 4 且不寫心跳。
|
||||
@@ -65,6 +64,16 @@
|
||||
# 巡檢照抄第四欄原字,不自己補查遠端版本、不把「查詢失敗」寫成「相符」或「最新」。
|
||||
# 查不到就是沒有證據,寫成別的字等於幫一個既有缺陷蓋章。
|
||||
#
|
||||
# --- 監控頁固定三塊 ---
|
||||
#
|
||||
# 監控頁不再一輪附加一節。15 分鐘一輪,一天就是 96 節,那樣的頁沒有人讀得完,也就沒有人
|
||||
# 會發現壞掉。改成固定三塊:
|
||||
# 本頁基本資料 建頁時寫一次,之後一個字都不動
|
||||
# 最新一輪 每輪整塊換掉,只留最新那一輪的完整內容
|
||||
# 近 24 輪摘要 一輪一列,最新的在最上面,超過 24 列就丟掉最舊的
|
||||
# 軌跡留在摘要表:一輪一列,看得出是從哪一輪開始壞的。完整內容只留最新一輪,因為頁面要能
|
||||
# 讀完才有人讀。
|
||||
#
|
||||
# --- collect 的輸出 ---
|
||||
#
|
||||
# stdout 是 key=value,一行一個鍵,供呼叫端逐行取值。監控頁要用的 markdown 不印在
|
||||
@@ -79,8 +88,11 @@
|
||||
# verdict= 正常、警示、異常
|
||||
# failed_sources= 讀不到的來源路徑,以「、」分隔;全部讀得到就是「無」
|
||||
# tasks_total= tasks_failing= 待辦簿筆數與連續失敗筆數,只供目錄頁那一列用
|
||||
# section_file= 要附加到 MONITOR_{HASH} 的那一節
|
||||
# newpage_file= MONITOR_{HASH} 不存在時要建的整頁內容
|
||||
# pending= 本輪待人處理的筆數
|
||||
# latest_file= 「最新一輪」那一塊,整塊換掉舊頁同名那一塊
|
||||
# summary_file= 「近 24 輪摘要」那一塊,表格裡先放本輪這一列,舊頁的資料列接在下面
|
||||
# summary_row_file= 只有本輪那一列,方便直接插到既有表格最上面
|
||||
# newpage_file= MONITOR_{HASH} 不存在時要建的整頁內容,三塊都已經排好
|
||||
# contents_file= MONITOR_CONTENTS 那一列的欄位值
|
||||
#
|
||||
# 環境變數:
|
||||
@@ -95,6 +107,7 @@ set -u
|
||||
|
||||
JSC_HOME="${JSC_HOME:-$HOME/.jsc}"
|
||||
STATE_DIR="$JSC_HOME/assistant"
|
||||
CURRENT="$JSC_HOME/current"
|
||||
LOCK="$STATE_DIR/patrol.lock"
|
||||
PREV_SNAP="$STATE_DIR/usage-prev.tsv"
|
||||
RD="$STATE_DIR/patrol"
|
||||
@@ -126,12 +139,17 @@ die() { # $1=結束碼 $2=訊息
|
||||
}
|
||||
|
||||
# 找一支別的 domain 的腳本。搜尋順序比照 schedule.sh 的 heartbeat_sh():先環境變數覆寫,
|
||||
# 再開發用的並排存取庫版面,最後已安裝的 plugin 快取版面。
|
||||
# 再 $JSC_HOME/current 那一組連結,然後開發用的並排存取庫版面,最後已安裝的 plugin 快取
|
||||
# 版面。current 排在快取前面是刻意的:技能與權限規則都以 current 為準,腳本內部再自己去挑
|
||||
# 另一個版本,同一輪就會跑到混版的工具,而那種不一致查起來沒有任何線索。
|
||||
find_tool() { # $1=domain 短名 $2=domain 內相對路徑 $3=環境變數覆寫值(可為空)
|
||||
if [ -n "$3" ]; then
|
||||
[ -f "$3" ] && { printf '%s\n' "$3"; return 0; }
|
||||
return 1
|
||||
fi
|
||||
for _c in "$CURRENT/jsc-$1/$2" "$CURRENT/$1/$2"; do
|
||||
[ -f "$_c" ] && { printf '%s\n' "$_c"; return 0; }
|
||||
done
|
||||
_root="${CLAUDE_PLUGIN_ROOT:-$SCRIPT_DIR/..}"
|
||||
for _c in "$_root/../$1/$2" "$_root/../jsc-$1/$2"; do
|
||||
[ -f "$_c" ] && { printf '%s\n' "$_c"; return 0; }
|
||||
@@ -519,7 +537,7 @@ d09() {
|
||||
printf '| pid | %s。只給要找行程的人參考,不參與判定 |\n' "$(cell "${_pid:--}")"
|
||||
printf '| 心跳檔 | `%s` |\n' "$(cell "${_file:--}")"
|
||||
printf '\n心跳的判準只看 `ts` 距現在有沒有超過門檻,不看 pid 存活:五支 CLI 與容器裡的行程互相看不到彼此的 pid。閘門的判定留在 hook,助理只維持心跳,不參與判定。\n'
|
||||
printf '\n心跳新鮮代表上一輪巡檢跑完了,而且結果記上監控頁了。它不代表那一輪四項都成功——四項的成敗看本節上面的「本輪判定」。\n'
|
||||
printf '\n心跳新鮮代表上一輪巡檢跑完了,而且結果記上監控頁了。它不代表那一輪四項都成功——四項的成敗看這一塊上面的「本輪判定」。\n'
|
||||
} >>"$RD/d09.md"
|
||||
|
||||
case "$_st" in
|
||||
@@ -546,7 +564,7 @@ count_tasks() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# --- 組出監控頁那一節 ---
|
||||
# --- 組出監控頁那三塊 ---
|
||||
|
||||
tally() { # $1=項目狀態
|
||||
case "$1" in
|
||||
@@ -562,8 +580,12 @@ compose() {
|
||||
[ "$OK_COUNT" -eq 0 ] && _v='異常'
|
||||
VERDICT="$_v"
|
||||
|
||||
ITEM_TOTAL=$(( OK_COUNT + FAIL_COUNT ))
|
||||
PEND_COUNT=$(grep -c '^| ' "$RD/pend.md" 2>/dev/null); [ -n "$PEND_COUNT" ] || PEND_COUNT=0
|
||||
|
||||
{
|
||||
printf '## 巡檢 %s\n\n' "$AT"
|
||||
printf '## 最新一輪\n\n'
|
||||
printf '這一塊每輪整塊換掉,只留最新那一輪的完整內容。再往前的軌跡看下面的摘要表。\n\n'
|
||||
printf '| 項目 | 內容 |\n'
|
||||
printf '| --- | --- |\n'
|
||||
printf '| 巡檢時間 | %s |\n' "$AT"
|
||||
@@ -589,21 +611,38 @@ compose() {
|
||||
printf '| 項目 | 來源子節 | 建議入口 |\n'
|
||||
printf '| --- | --- | --- |\n'
|
||||
if [ -s "$RD/pend.md" ]; then cat "$RD/pend.md"; else printf '| (無) | - | - |\n'; fi
|
||||
} >"$RD/section.md"
|
||||
} >"$RD/latest.md"
|
||||
|
||||
# 摘要表的那一列。欄位刻意只有四個:時間、判定、四項成敗、待人處理筆數——一列要能一眼
|
||||
# 看完,才看得出是從哪一輪開始壞的。
|
||||
printf '| %s | %s | %s/%s | %s |\n' \
|
||||
"$AT" "$VERDICT" "$OK_COUNT" "$ITEM_TOTAL" "$PEND_COUNT" >"$RD/summary-row.md"
|
||||
|
||||
# 摘要那一塊:標題、表頭,加上本輪這一列。呼叫端把舊頁的資料列接在這一列下面,截到 24 列。
|
||||
{
|
||||
printf '## 近 24 輪摘要\n\n'
|
||||
printf '一輪一列,最新的在最上面,超過 24 列就丟掉最舊的那一列。\n\n'
|
||||
printf '| 巡檢時間 | 本輪判定 | 四項成敗 | 待人處理 |\n'
|
||||
printf '| --- | --- | --- | ---: |\n'
|
||||
cat "$RD/summary-row.md"
|
||||
} >"$RD/summary.md"
|
||||
|
||||
# 監控頁不存在時要建的整頁內容。基本資料建頁時寫一次,之後不再更動。
|
||||
{
|
||||
printf '# 助理巡檢 — %s/%s\n\n' "$HOST" "$USER_NAME"
|
||||
printf '> 由 `jsc-assist` 維護。這是監控頁 `%s`。\n' "$PAGE"
|
||||
printf '> 這頁是這台機器的巡檢軌跡:一次巡檢附加一節,節標題帶時間戳,舊的節一個字都不動。\n'
|
||||
printf '> 附加是刻意的。助理的寫入是背景行為,覆寫錯了沒人在現場,軌跡被抹掉也看不出斷在哪一輪。\n'
|
||||
printf '> 目錄頁 `MONITOR_CONTENTS` 只更新自己那一列,寫入語意與這頁不同,不要混用。\n\n'
|
||||
printf '> 這頁固定三塊:本頁基本資料、最新一輪、近 24 輪摘要。\n'
|
||||
printf '> 最新一輪每輪整塊換掉;摘要表一輪一列往上疊,只留 24 列;基本資料建頁時寫一次就不動。\n'
|
||||
printf '> 完整內容只留最新一輪,頁面才讀得完;軌跡留在摘要表,看得出是從哪一輪開始壞的。\n'
|
||||
printf '> 目錄頁 `MONITOR_CONTENTS` 只更新自己那一列,別台機器的列一個字都不動。\n\n'
|
||||
printf '```mermaid\nflowchart LR\n'
|
||||
printf ' A[巡檢一輪] --> B[收攏四項結果]\n'
|
||||
printf ' B --> C[附加一節,節標題帶時間戳]\n'
|
||||
printf ' C --> D[既有的節原樣保留]\n'
|
||||
printf ' D --> E[回頭更新 MONITOR_CONTENTS 自己那一列]\n'
|
||||
printf ' E --> F[最後才寫心跳]\n'
|
||||
printf ' B --> C[讀回舊頁]\n'
|
||||
printf ' C --> D[換掉最新一輪那一塊]\n'
|
||||
printf ' D --> E[本輪摘要列插到表格最上面,截到 24 列]\n'
|
||||
printf ' E --> F[整頁寫回]\n'
|
||||
printf ' F --> G[更新 MONITOR_CONTENTS 自己那一列]\n'
|
||||
printf ' G --> H[最後才寫心跳]\n'
|
||||
printf '```\n\n'
|
||||
printf '## 本頁基本資料\n\n'
|
||||
printf '建頁時寫一次,之後不再更動。\n\n'
|
||||
@@ -613,7 +652,8 @@ compose() {
|
||||
printf '| 帳號 | %s |\n' "$(cell "$USER_NAME")"
|
||||
printf '| 雜湊來源 | `%s/%s` |\n' "$(cell "$HOST")" "$(cell "$USER_NAME")"
|
||||
printf '| 狀態檔根目錄 | `$JSC_HOME/assistant/`(`$JSC_HOME` 未設定就退回 `~/.jsc`) |\n\n'
|
||||
cat "$RD/section.md"
|
||||
cat "$RD/latest.md"; printf '\n'
|
||||
cat "$RD/summary.md"
|
||||
} >"$RD/newpage.md"
|
||||
|
||||
{
|
||||
@@ -695,7 +735,10 @@ case "$CMD" in
|
||||
printf 'failed_sources=%s\n' "${FAILED_SOURCES:-無}"
|
||||
printf 'tasks_total=%s\n' "$TASKS_TOTAL"
|
||||
printf 'tasks_failing=%s\n' "$TASKS_FAILING"
|
||||
printf 'section_file=%s\n' "$RD/section.md"
|
||||
printf 'pending=%s\n' "$PEND_COUNT"
|
||||
printf 'latest_file=%s\n' "$RD/latest.md"
|
||||
printf 'summary_file=%s\n' "$RD/summary.md"
|
||||
printf 'summary_row_file=%s\n' "$RD/summary-row.md"
|
||||
printf 'newpage_file=%s\n' "$RD/newpage.md"
|
||||
printf 'contents_file=%s\n' "$RD/contents.tsv"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user