部署故障分析及解決助手

👤 bounding-elk 📦 v1.2.1 ⭐ 4.3 ⬇️ 637 下載
🔒 IT運維與安全 免費

📖 技能介紹


name: deploy-fault-analyzer description: 部署故障分析及解決助手 — 接收日誌/報錯文本,優先查詢 MySQL 故障知識庫;未命中時檢索 /data/scripts/ 指令碼庫;支援互動式單條更新故障庫並生成 Word 分析報告。 version: 1.2.1 author: Hermes created: 2026-05-09


部署故障分析及解決助手

當用戶提供日誌檔案(.json .log)或包含 error/錯誤/異常/故障/報錯/failed 等關鍵詞的文字內容時,自動分析故障並生成 Word 文件。分析前必須優先查詢 MySQL 故障知識庫 fault_knowledge_base.fault_records,用歷史案例提高定位準確率;所有新問題繼續記錄到 Excel 知識庫中累積沉澱,並可同步到資料庫。

⚠️ 交付規則: Word 報告生成後必須在同一條回覆中附帶故障分析摘要 + 傳送 Word 檔案給使用者,不能只生成到本地而不傳送。


觸發條件

滿足以下任一條件即觸發:

觸發方式 判定標準
日誌檔案 使用者上傳/拖入 .json.log 檔案,或指明檔案路徑
報錯文本 使用者訊息中包含 error/錯誤/異常/故障/報錯/failed/failure/exception/失敗 等關鍵詞
主動請求 使用者說"幫我分析這個故障"/"這是什麼錯"/"幫我看下日誌"等

排除:使用者只是在陳述中順帶提到"沒有錯誤"/"沒問題"/"成功了"時不觸發。


故障知識庫資料庫

資料庫資訊

故障知識庫來自部署排期表第 10 個 sheet「故障庫」,由 /data/work/scripts/sync_fault_knowledge_base.py 同步到 MySQL。

資料庫 fault_knowledge_base
主表 fault_records
連線命令 docker exec resource_pool_mysql mysql -upool_user -ppool_password_2024 fault_knowledge_base
Python 指令碼連庫埠 宿主機 33307insert_fault_record.py 預設已配置)
Excel 同步指令碼 /data/work/scripts/sync_fault_knowledge_base.py
單條入庫指令碼 /data/work/scripts/insert_fault_record.py
指令碼庫檢索 /data/work/scripts/search_deploy_scripts.py
預設 Excel /data/work/bom/基礎平臺部署排期表-2026年度.xlsx

部署指令碼庫(故障庫未命中時的回退檢索)

根目錄:/data/scripts/

庫目錄 說明 典型場景
cephdeployscripts/ Ceph 塊儲存部署/擴容指令碼(Fabric + ceph-deploy) 新建塊儲存叢集、OSD 擴容、cusmartcache、cephfs、pool 建立
deploy-perfect-20250821/ 基座新建部署指令碼 bootstrap、yum、repo、基座、DNS、ironic
kubeos-ansible/ 雙引擎部署指令碼 OpenStack 元件部署/擴容/新建、nova、neutron

cephdeployscripts 架構與故障索引(塊儲存必讀)

用途:Ceph 塊儲存新建部署擴容的標準指令碼庫。執行節點一般為部署機(含 ceph-deploy/fabric),通過 SSH 批次操作 monitor/OSD 節點。故障庫未命中且涉及塊儲存、cinder、osd、pool、擴容時,優先在本庫檢索

目錄結構

/data/scripts/cephdeployscripts/
├── blockstorage/              # 主入口:新建 + 擴容
│   ├── fabfile.py             # 核心編排(Fabric),新建/擴容主流程
│   ├── config.json            # 新建叢集配置(monitors/osdnodes/disks)
│   ├── expand.json            # 擴容配置(newosdnodes/ebs0001_ip)
│   └── create_cephfs_pool.py  # 建立 CephFS pool + MDS(獨立流程)
├── common/
│   └── common.py              # 公共邏輯:叢集型別判定、校驗、pool/OSD 檢查
├── config_samples/            # 各場景配置樣例(對照現場 config 用)
│   ├── config_mix.json
│   ├── config_allflash.json
│   ├── config_highperformance.json
│   ├── expand_mix.json
│   └── ...
├── resources/                 # 下發到各節點的輔助指令碼/配置
│   ├── check-cusmartcache.sh  # cusmartcache LV 標籤與 enable 校驗
│   ├── modprobe-cusmartcache.sh
│   ├── clearcephlvm.sh        # 清理 ceph LVM(lv/vg/pv/dm)
│   ├── balancer_osd_pg.sh     # PG 分佈與均衡診斷
│   ├── patch-ceph-osd-prestart.sh
│   ├── upgrade_package.sh     # openssl/openssh/libblkid 等版本升級
│   └── extended.ceph.conf
└── cephdeploy/                # 子模組(git),與上層 blockstorage 配合

技術棧與執行約定

說明
編排框架 Python 2 + Fabricfabric.api),遠端執行 run/sudo
Ceph 工具 ceph-deployceph-deploy osd creategatherkeysmon create
部署目錄 各節點 /opt/cephdeploy,指令碼從 resources/ 複製
新建配置 blockstorage/config.json
擴容配置 blockstorage/expand.json(含 newosdnodesebs0001_ip
工作目錄 執行前 cd /cephdeployscripts/blockstorage/(程式碼內 WORKDIR

fabfile.py 函式命名約定(讀程式碼/日誌時對照):

  • Capital*:主流程入口(如 DeployMixOsdsAddNewHostsToCluster
  • local_*:部署節點本地執行
  • monitor_*:monitor 節點
  • osd_*:OSD 節點
  • all_*:全部節點(mon + osd)

叢集型別(decide_cluster_type

config.json / expand.jsondiskshdds/ssds 組合自動判定,同一叢集所有節點型別必須一致

型別常量 名稱 磁碟特徵 預設 RBD Pool
CLUSTER_TYPE_ALLFLASH (2) allflash 僅 SSD volumes-ssd
CLUSTER_TYPE_ALLNVME (5) allnvme 僅 NVMe SSD volumes-nvme
CLUSTER_TYPE_HIGHPERFORMANCE (3) highperformance SSD+HDD(無 cusmartcache) volumesvolumes-enhance
CLUSTER_TYPE_MIX (4) mix-cusmartcache SSD+HDD + cusmartcache volumesvolumes-enhance

mix 部署模式mixdeploymode,僅 MIX 叢集):

  • newcluster:新建 mix 叢集(預設)
  • addcusmartcacheforbcache:為已有 bcache 補 cusmartcache
  • addcusmartcacheforhdd:為 HDD 補 cusmartcache

HCUFS 特殊叢集:8×NVMe + 60×HDD(is_hcufs_cluster),佈局 [8,8,8,8,7,7,7,7] HDD/SSD 配對。

新建部署主流程(python fabfile.pyfab -f fabfile.py

Init() → 讀 config.json → 校驗磁碟/IP/掛載
  → all_generateauth / all_sshnopassword / all_systemconfig
  → all_do_misc_check(包版本、tuned、firewalld/SELinux)
  → all_install_ceph_package(mix 時含 cusmartcache)
  → CreateMonMgr() → Deploy*Osds() → RestartAllOsds() → Check*OsdCount()
  → 建立 pool(images + volumes*)+ client.cinder/client.glance + balancer

按叢集型別分支:DeployAllFlashOsds / DeployHighPerformaceOsds / DeployMixOsds

新建成功判定CheckNewClusterDeployResult):mon/mgr 程序數 = 配置數;totalosd == uposd == inosd == total_data_disk_num;mix 時 cusmartcache 數量 = OSD 數量

擴容主流程(AddNewHostsToCluster

LoadExpandConfig() → 讀 expand.json
  → check_expand_mon_osd / check_all_disks
  → decide_cluster_type(擴容節點型別)
  → get_expand_type(擴充套件現有 pool 或新建 pool)
  → IsEbs001MixNode()(mix 擴容時檢查 ebs0001 是否 mix 節點)
  → ceph-deploy gatherkeys → 新節點 init(裝包、拷 keyring、清盤)
  → Deploy*Osds() → Check*ExpandResult()

擴容成功判定totalosd - ORIGINALTOTAL == 新增 OSD 數;失敗常見日誌:some osds is FAILED, please double check your configuration

expand_type

  • expand_current_pool:OSD 加入現有 pool(如 volumesvolumes-ssdcephfs-data
  • create_new_pool:需手工建立新 pool(日誌提示 please create new pool

CephFS 獨立流程(create_cephfs_pool.py

與塊儲存 RBD 新建並行可選步驟,依賴已有 Ceph 叢集 + config.json 中 monitors 與 ceph.conf 一致:

CreateCephfsForCluster()
  → 安裝 ceph-mds → 建立 MDS → 按主機名字首建立 pool → 掛載目錄初始化

主機名字首 → pool 規格對映(node_pool_map):ebs/ebn/hcicephfs-metadata/cephfs-datanasssd*-ssdnashdden*-enhance 等。

故障場景 → 指令碼索引(Agent 檢索用)

故障現象 / 關鍵詞 優先檢索路徑 指令碼內關注點
osd node ip mismatch / 配置 IP 不一致 blockstorage/fabfile.py LoadConfig/LoadExpandConfig osdnodesdisks[].ips 必須完全一致
not support nvme partition / ssd partition fabfile.py LoadConfig SSD 不允許分割槽裝置
no enough space for ssd / to many hdds fabfile.py osd_deploy_* HDD/SSD 容量比、MAXHDDPERSSD=6
some osds is FAILED / OSD 數量不對 common/common.py CheckNewClusterDeployResult ceph -spgrep ceph-osd、cusmartcache 數量
cusmartcache num mismatch common/common.py + resources/check-cusmartcache.sh /proc/cusmartcache/cusc_clilv_tags
cusmartcache kernel module not loaded resources/modprobe-cusmartcache.sh cusmartcache.kodepmodinsmod
there are N objects in cluster 無法新建 common/common.py CheckClusterObjectNum 叢集已有資料,需清 pool 再部署
invalid expand pool common/common.py check_expand_pool 擴容 pool 名與節點型別不匹配
ebs0001 is not mix node common/common.py IsEbs001MixNode expand.jsonebs0001_ip/ebs0001_password
host deploy type error common/common.py decide_cluster_type 各節點磁碟型別不一致
package.*version / openssl openssh common/common.py all_do_misc_check resources/upgrade_package.sh
LVM 啟用失敗 / 重啟後 OSD down common/common.py osds_config_rc_local ceph-volume lvm activate --all
PG 不均衡 / incomplete pgs resources/balancer_osd_pg.sh ceph pg dump、primary PG 分佈
清盤重灌 / LVM 殘留 resources/clearcephlvm.sh lvremove/vgremove/pvremove
cephfs pool / mds 建立失敗 blockstorage/create_cephfs_pool.py monitors 與 ceph.conf 一致性、主機名字首
ceph-deploy osd create 失敗 fabfile.py osd_deploy_* wipefssgdiskblock-db/block-wal/data 路徑
mix 擴容降級 highperformance fabfile.py LoadExpandConfig ebs0001 無 cusmartcache 時自動降級

推薦檢索命令(塊儲存)

# 1. 按現象檢索(module 填 塊儲存)
python3 /data/work/scripts/search_deploy_scripts.py \
  --query "osd FAILED cusmartcache ceph-deploy" \
  --module "塊儲存" \
  --path-contains "cephdeployscripts/blockstorage" \
  --path-contains "cephdeployscripts/common" \
  --top 8 --json

# 2. 配置/校驗類
python3 /data/work/scripts/search_deploy_scripts.py \
  --query "osd node ip mismatch expand.json config.json" \
  --module "塊儲存" \
  --path-contains "cephdeployscripts" \
  --top 5 --json

# 3. cusmartcache 專項
python3 /data/work/scripts/search_deploy_scripts.py \
  --query "cusmartcache cusc_cli lv_tags proc/cusmartcache" \
  --module "塊儲存" \
  --path-contains "cephdeployscripts/resources" \
  --top 5 --json

命中後須閱讀對應指令碼中的校驗分支與 exit 條件(見 Step 2.6C),再給出可執行的排查/修復步驟。


當用戶說“同步故障庫”“把 Excel 故障庫入庫”等含義時,執行以下流程:

# 1. 先檢查 Excel 可解析和有效行數
python3 /data/work/scripts/sync_fault_knowledge_base.py --dry-run

# 2. 正式同步,重複執行不會重複插入同一條故障
python3 /data/work/scripts/sync_fault_knowledge_base.py

# 3. 驗證行數和去重
docker exec resource_pool_mysql mysql -upool_user -ppool_password_2024 fault_knowledge_base \
  -e "SELECT COUNT(*) AS total, COUNT(DISTINCT content_hash) AS unique_hashes FROM fault_records;"

如資料庫未初始化,先執行:

docker exec -i resource_pool_mysql mysql -uroot -proot_password_2024 \
  < /data/work/sql/create_fault_knowledge_base.sql

欄位含義

欄位 含義 查詢用途
module_name 模組 第一層收窄範圍,優先從報錯中的產品/元件/任務名推斷
issue_type 問題型別 第二層收窄範圍,優先從故障現象推斷
issue_description 問題描述 核心相似度匹配欄位
solution_summary 解決方法概要 給出歷史解決路徑
product_version 交付產品集版本 版本相關問題過濾
delivery_branch 交付分支 架構/OS/分支差異過濾
resource_pool 資源池 判斷是否為特定現場案例

欄位填寫質量規範(單條入庫必遵)

id:1110 為標杆:

  • issue_description:保留完整報錯原文(命令輸出、stderr、Traceback、exit code),≥50 字,禁止僅寫「部署失敗」等空泛描述
  • solution_summary:明確可操作修復動作(如「部署表字段 X:TRUE 改 FALSE」),≥10 字,禁止「待排查」「聯絡研發」
  • delivery_mode(交付形態):必填,填寫現場交付型別,例如:私有云 / 行業雲 / 內部上雲
  • resource_pool(資源池):必填,填寫具體資源池名稱,例如:北京九區 / 巴西CT雲 / 呼和國產化
  • product_version(交付產品集版本):必填,填寫版本號,例如:7.6.0 / 7.7.0 / 7.5.0
  • delivery_branch(交付分支):必填,填寫架構與 OS 組合,例如:@X86@CUlinux / @ARM@CUlinux / @X86@CentOS;多分支用逗號分隔,如 @X86@CUlinux,@ARM@CUlinux
  • deployer(部署人):必填,填寫實際部署負責人姓名,例如:田慶霖 / 姜金科

核心流程

Step 0 — 儲存原始輸入

任何輸入在處理前必須先存檔,防止後續分析覆蓋原始資料:

from pathlib import Path
from datetime import datetime
import shutil

RAW_DIR = Path.home() / '.hermes/skills/openclaw-imports/deploy-fault-analyzer/data/raw'
RAW_DIR.mkdir(parents=True, exist_ok=True)

# 檔案輸入 → 複製到 raw/
ts = datetime.now().strftime('%Y-%m-%d_%H%M%S')
raw_path = RAW_DIR / f'{ts}_{Path(src_file).name}'
shutil.copy2(src_file, raw_path)

# 文本輸入 → 寫入 raw/
raw_path = RAW_DIR / f'{ts}_user_input.txt'
raw_path.write_text(user_text, encoding='utf-8')

Step 1 — 讀取並解析輸入

按檔案格式選擇解析策略:

1A. 結構化 JSON 日誌(特徵:頂層有 logs 陣列,每項有 type/message 欄位)

import json
with open(filepath) as f:
    data = json.load(f)

logs = data['logs']  # 日誌陣列
# 提取欄位:
#   log['type']     → 'error'|'warning'|'info'|'success'
#   log['message']  → 日誌內容(含時間戳 `[HH:MM:SS]`)
#   log['timestamp']→ ISO 時間(JSON欄位,可能缺失)
#   log['task_id']  → 任務ID(如 PREP_UPLOAD_33B3DC)

errors   = [l for l in logs if l['type'] == 'error']
warnings = [l for l in logs if l['type'] == 'warning']
infos    = [l for l in logs if l['type'] == 'info']

1B. 純文本 .log 檔案

# 逐行讀取,按關鍵詞提取 ERROR/WARN/CRITICAL/FAIL 行
# 使用正則: ^\d{4}-\d{2}-\d{2}.*(ERROR|WARN|CRITICAL|FAIL)

1C. 使用者貼上文本 → 直接作為分析輸入

Step 2 — 錯誤自動歸類與去重

2A. 中文錯誤模式自動歸類

使用關鍵詞正則匹配,按優先順序從高到低匹配:

優先順序 匹配模式(關鍵詞) 類別
1 日期格式不正確 日期格式錯誤 格式yyyy-mm-dd 資料異常 — 日期格式
2 資源池名稱不正確 名稱不一致 sheet.*≠ 配置錯誤 — 資源池名
3 未填寫 必填項.*未 必填.*缺失 配置錯誤 — 必填欄位
4 缺失 不存在 not found No such file 資源不足 — 檔案/目錄
5 格式不正確.*IP IP地址格式 格式不合法 配置錯誤 — IP格式
6 already installed is already 衝突 conflict 服務異常 — 安裝衝突
7 已終止 使用者.*終止 使用者.*取消 使用者操作 — 部署終止
8 Verifying verification 校驗失敗 驗證失敗 服務異常 — 驗證超時
9 連線.*拒絕 Connection refused timeout unreachable 網路/連線故障
10 host.*not found DNS.*fail 解析失敗 網路/連線故障
11 bms.*pri hostname.*invalid 配置錯誤 — 主機名
12 Permission denied 許可權不足 訪問被拒 許可權問題
13 OOM out of memory 磁碟空間不足 No space 資源不足 — 系統資源
14 ModuleNotFoundError ImportError 依賴.*缺失 依賴缺失

實現:

def categorize_error_message(msg: str) -> str:
    """根據中文關鍵詞自動歸類錯誤"""
    patterns = [
        (r'日期格式不正確|日期格式錯誤|格式yyyy-mm-dd', '資料異常'),
        (r'資源池名稱不正確|名稱不一致', '配置錯誤'),
        (r'未填寫|必填項.*未填|必填.*缺失', '配置錯誤'),
        (r'缺失|不存在|not found|No such file|no such file', '資源不足'),
        (r'格式不正確.*IP|IP地址格式|格式不合法', '配置錯誤'),
        (r'already installed|is already|衝突|conflict', '服務異常'),
        (r'已終止|使用者.*終止|使用者.*取消', '使用者操作'),
        (r'Connection refused|timeout|unreachable|連線.*拒絕', '網路/連線故障'),
        (r'Permission denied|許可權不足|訪問被拒', '許可權問題'),
        (r'OOM|out of memory|磁碟空間不足|No space', '資源不足'),
        (r'ModuleNotFoundError|ImportError|依賴.*缺失', '依賴缺失'),
    ]
    for pattern, category in patterns:
        if re.search(pattern, msg):
            return category
    return '待分類'

2B. 錯誤去重歸併(關鍵步驟)

真實日誌中同根因錯誤通常大量重複。必須先去重再分析

  1. 過濾掉 使用者操作類已終止/使用者終止)→ 不計入故障,僅在報告中標註
  2. 錯誤訊息去重:取 messageERROR 關鍵字後的核心文本去重
  3. task_id + 類別 歸併:同一任務同一類別的多條錯誤合併為一個根因
  4. 輸出:每個根因一個 fault_data 字典
def deduplicate_errors(errors: list) -> list:
    """歸併重複錯誤 → 根因列表"""
    # 1. 分離使用者操作
    real_faults = [e for e in errors if '使用者已終止' not in e['message'] and '使用者終止' not in e['message']]

    # 2. 按訊息核心去重
    seen = {}
    for e in real_faults:
        msg = e['message']
        # 提取核心:ERROR 後的文本或訊息中獨特部分
        core = re.sub(r'\[.*?\]', '', msg).strip()[:100]
        cat = categorize_error_message(core)
        key = f"{cat}:{core[:50]}"
        if key not in seen:
            seen[key] = {'count': 1, 'sample': e, 'category': cat, 'task_ids': {e.get('task_id','?')}}
        else:
            seen[key]['count'] += 1
            seen[key]['task_ids'].add(e.get('task_id', '?'))

    return list(seen.values())

Step 2.5 — 優先查詢 MySQL 故障知識庫(必須執行)

在進入根因分析前,必須先用去重後的核心錯誤到 fault_knowledge_base.fault_records 查詢歷史案例。查詢目標是找到相同或相近的 module_nameissue_typeissue_description,並把命中的 solution_summary 作為解決方案候選,而不是直接憑經驗生成結論。

2.5A. 先推斷 module_name

優先從日誌裡的產品名、任務名、服務名、報錯路徑、部署階段推斷模組;無法確定時再不帶模組查詢。

高頻 module_name 候選(按歷史庫頻次和故障定位價值排序):

候選模組 常見關鍵詞
基座 bootstrap、基礎包、yum、repo、平臺基礎服務、部署指令碼公共步驟
主機交付問題 主機、host、IPMI、root密碼、作業系統、lldp、網路不通
環境檢查 precheck、前置檢查、埠檢查、連通性檢查、環境檢查
塊儲存 cinder、ceph、塊儲存、volume、儲存池、磁碟
VPP vpp、dpdk、轉發、網絡卡繫結、HugePage
監控 telegraf、prometheus、grafana、監控節點、採集
SDN sdn、neutron、網路控制、雲內sdn、雲間sdn
門戶 portal、控制台、門戶匯入表、規格族
物件儲存 obs、s3、物件儲存、bucket
CSK / 容器 / 雲原生 csk、k8s、kube、容器、master、worker
Trove mysql、redis、trove、資料庫服務
虛擬化 / 裸金屬 nova、ecs、bms、ironic、裸金屬
DNS dns、域名、解析失敗
ECR ecr、映象倉庫、registry
網路交付問題 交換機、路由、vlan、外部網路、防火牆

2.5B. 再推斷 issue_type

issue_type 用於第二層收窄。優先候選:

候選型別 常見關鍵詞
指令碼問題 script、指令碼、執行失敗、返回碼、命令失敗、already installed
環境問題 網路不通、埠不通、系統版本、依賴環境、服務狀態
新建部署問題 新建、首次部署、安裝、部署失敗
新建驗收問題 驗收、驗證、verification、檢查失敗
部署包問題 包缺失、rpm、tar、映象、目錄不存在、版本包
部署表問題 Excel、部署表、必填、格式、資源池名稱、規格族
網路交付問題 DNS、路由、交換機、連通性、防火牆、VLAN
主機交付問題 主機名、IPMI、作業系統、root密碼、lldp、網絡卡
部署文件問題 文件、步驟、章節、說明不一致
操作問題 人工操作、輸入錯誤、誤操作、順序錯誤
擴容問題 / 擴容驗收問題 擴容、增加節點、擴容後驗收
最佳化建議 / 其他問題 無明確故障但存在改進項

2.5C. 查詢策略

按“強約束 → 放寬”的順序查詢,避免一開始全庫模糊搜尋導致誤命中:

  1. module_name + issue_type + issue_description 關鍵詞查詢
  2. module_name + issue_description 查詢
  3. issue_type + issue_description 查詢
  4. issue_description 全文/LIKE 查詢
  5. 如果完全無命中,繼續按原流程分析,並在報告中註明“歷史故障庫未找到高置信匹配”

推薦命令模板:

docker exec resource_pool_mysql mysql -upool_user -ppool_password_2024 fault_knowledge_base -e "
SELECT
  id, module_name, issue_type, found_at, product_version, delivery_branch,
  LEFT(issue_description, 220) AS issue_preview,
  LEFT(solution_summary, 220) AS solution_preview
FROM fault_records
WHERE module_name = '基座'
  AND issue_type = '指令碼問題'
  AND (
    issue_description LIKE '%bootstrap%'
    OR solution_summary LIKE '%bootstrap%'
    OR MATCH(issue_description, solution_summary, remark) AGAINST('bootstrap 指令碼 失敗' IN NATURAL LANGUAGE MODE)
  )
ORDER BY
  (module_name = '基座') DESC,
  (issue_type = '指令碼問題') DESC,
  updated_at DESC
LIMIT 5;"

如果無法穩定判斷模組,使用關鍵詞全庫檢索:

docker exec resource_pool_mysql mysql -upool_user -ppool_password_2024 fault_knowledge_base -e "
SELECT id, module_name, issue_type,
       LEFT(issue_description, 200) AS issue_preview,
       LEFT(solution_summary, 200) AS solution_preview
FROM fault_records
WHERE issue_description LIKE '%關鍵報錯%'
   OR solution_summary LIKE '%關鍵報錯%'
   OR remark LIKE '%關鍵報錯%'
LIMIT 10;"

2.5D. 命中結果使用規則

  • 高置信命中:module_nameissue_type、核心報錯關鍵詞均匹配,解決方案可作為首選,但仍要結合當前日誌證據驗證。
  • 中置信命中:模組或問題型別匹配,但錯誤文本只部分相似,只能作為排查方向。
  • 低置信命中:僅關鍵詞相似,不能直接引用為結論,只在“歷史類似案例”中備註。
  • 如果多個歷史案例衝突,優先選擇同模組、同問題型別、同版本/分支的記錄。
  • Word 報告中增加“歷史故障庫匹配”小節,列出命中記錄的模組、問題型別、問題摘要、解決摘要和置信度。

2.5E. 未命中時的處理

若 Step 2.5 無高置信命中(模組、問題型別、核心報錯關鍵詞均未對齊),必須先進入 Step 2.6 指令碼庫檢索,不得直接憑經驗給出最終結論。

Step 2.6 — 指令碼庫相似檢索(故障庫未命中時執行)

告知使用者:「歷史故障庫未找到高置信匹配,開始分析指令碼庫 /data/scripts/」,然後執行:

2.6A. 指令碼索引範圍(更精準的檢索入口)

指令碼庫根目錄:/data/scripts/,當前已知指令碼庫與推薦索引範圍如下(優先在推薦範圍內命中):

指令碼庫 推薦索引範圍(優先順序從高到低) 適用模組/場景(示例關鍵詞)
deploy-perfect-20250821/ second_deploy/dns/second_deploy/ironic/second_deploy/trove/second_deploy/dcs/second_deploy/ecml/second_deploy/dims/second_deploy/cloud_sdn/sdn/yum_repo/perfect_deploy.shcreate_conf.pyglobals.yml 基座新建/二次部署、DNS/ironic/trove、yum/repo、部署表生成(dnsironictrovebootstrapyumrepoportal多套內部浮動網
kubeos-ansible/ ansible/site.ymlansible/pre_deploy.ymlansible/*extend*.ymlansible/roles/**/tasks/ansible/roles/**/templates/tools/ 雙引擎 OpenStack/元件部署擴容(ansiblenovaneutronrabbitmqprometheusworker_extendprecheck
cephdeployscripts/ blockstorage/fabfile.pyblockstorage/create_cephfs_pool.pycommon/common.pyresources/*.shconfig_samples/ 塊儲存新建/擴容(ceph-deployosdcusmartcachepoolcephfsexpand.jsonconfig.json

檢索檔案型別.sh .py .yml .yaml .ini .conf .cfg .j2 .md
排除範圍.gitnode_modules.idea__pycache__ 等非業務內容。

2.6B. 從故障問題提取“可檢索關鍵詞”(必須做)

為保證指令碼檢索精準度,--query 不能只用“部署失敗/執行失敗”這類泛詞,必須從輸入中抽取:

  • 核心報錯原文片段:如 No valid service subnetKeyErrorConnection refusedTarballDownloadExceptioniptables -t raw
  • 元件/命令/指令碼痕跡:如 neutronceph-deploycusc_cliceph-volumefabfileexpand.jsonwipefssgdisk
  • 關鍵資源名/路徑(可截斷):如 ceph-provisioners-0.1.0.tgz/data/monitor-deploy//opt/ECR/

推薦:把 issue_description 中的 2~6 個關鍵詞拼成 query(中英文混合可用)。

python3 /data/work/scripts/search_deploy_scripts.py \
  --query "核心報錯關鍵詞" \
  --module "推斷的模組名" \
  --top 5 --json

2.6C. 用指令碼內容參與根因分析(必須做)

指令碼檢索的目的不是“給出一堆路徑”,而是讓故障問題根據指令碼內容得到驗證或定位。對每個 Top 候選指令碼,至少完成以下動作之一:

  • 定位校驗點:腳本里是否存在與報錯對應的檢查/條件分支/變數(例如:部署表字段校驗、網段/子網匹配、iptables 規則寫入)
  • 定位失敗點:腳本里是否有與日誌一致的命令呼叫(如 neutron floatingip-createarmada applypython2 /usr/bin/db_populate.py)以及 rc/異常處理方式
  • 給出驗證命令/驗證方法:從指令碼推導使用者可執行的驗證步驟(例如:檢查配置檔案、檢查 service subnet、檢查 iptables raw 表規則)

向用戶展示 Top 候選(庫名、指令碼路徑、匹配行摘要),並詢問:

以上指令碼是否命中並解決了此次問題?(是 / 否)

  • 使用者回答「是」 → 詢問是否需要將此次 Q&A 更新到故障庫;若需要,進入 Step 8
  • 使用者回答「否」 → 繼續 Step 3 起的常規根因分析與報告生成

remark 欄位可記錄命中的指令碼路徑,例如:指令碼庫命中: cephdeployscripts/blockstorage/fabfile.pycephdeployscripts/resources/check-cusmartcache.sh

Step 3 — 故障資訊提取(多故障)

從去重後的錯誤列表,為每個根因提取結構化資訊:

提取方法:

提取項 JSON 日誌提取方法 文本日誌提取方法
故障時間 e['timestamp'](ISO格式)或從 message 中提取 [HH:MM:SS] 正則 \d{4}-\d{2}-\d{2}.*\d{2}:\d{2}:\d{2}
錯誤型別 task_id + 異常描述拼接,如 CHECK_DEPLOY_F5B45D: checkTableImpl.DateFormatError 異常類名或錯誤碼
錯誤訊息 e['message'] 前200字元 緊跟在 ERROR 後的描述文本
出現次數 dedup_count 行數統計
堆疊跟蹤 message 中的 checkTableImpl.py:318 等提取呼叫鏈 Traceback 段落前20行
影響元件 task_id 字首 + message 中的模組路徑(如 /home/conf/ 服務名、主機名
影響範圍 從部署流程推斷(阻塞/警告/跳過) 從錯誤推斷
關聯配置 message 中的檔案路徑、引數名 配置檔案引用

任務ID解析(JSON日誌特有):

# task_id 字首含義:
#   PREP_UPLOAD_* → 上傳檢查步驟
#   PREP_TASK_*   → 前置任務
#   CHECK_DEPLOY_* → 部署表檢查
#   PREP_DEPLOY_*  → 部署準備

def parse_task_id(task_id: str) -> dict:
    """解析 task_id → 任務型別和階段"""
    if task_id is None:
        return {'phase': '全域性', 'type': '系統'}
    parts = task_id.split('_')
    if len(parts) >= 2:
        return {'phase': parts[0], 'type': parts[1], 'id': parts[-1] if len(parts) > 2 else ''}
    return {'phase': task_id, 'type': 'UNKNOWN'}

Step 4 — 根因分析

基於提取的資訊,執行以下分析步驟:

  1. 錯誤分類:歸入以下類別之一
  2. 🟥 網路/連線故障(ConnectionError, timeout, unreachable)
  3. 🟧 配置錯誤(config file, parameter, permission)
  4. 🟨 資源不足(OOM, disk full, CPU throttle, fd limit)
  5. 🟩 服務異常(service down, crash, restart loop)
  6. 🟦 許可權問題(permission denied, unauthorized)
  7. 🟪 依賴缺失(module not found, library mismatch)
  8. ⬜ 資料異常(data corrupt, schema mismatch)

  9. 歷史案例對齊:把 Step 2.5 命中的故障庫記錄與當前日誌證據逐項對比,確認模組、問題型別、關鍵詞、版本/分支是否一致

  10. 因果關係鏈:從堆疊自底向上追溯,找到最初觸發點

  11. 關鍵證據:摘錄日誌中能佐證根因的2-3條關鍵行

Step 5 — 生成解決方案

優先採用高置信歷史案例中的 solution_summary,再結合當前日誌、環境和標準排查路徑細化;沒有命中時才完全按通用框架生成方案。

錯誤類別 標準排查路徑 典型解決步驟
網路/連線 telnet/ping/curl 測試連通性 → 防火牆規則 → DNS解析 檢查目的埠可達性、放行防火牆規則、修正IP配置
配置錯誤 對比配置模板 → 校驗引數值 修正配置檔案、重啟服務、驗證引數生效
資源不足 free/df -h/ulimit -n 檢查 → top 定位佔用程序 清理磁碟、擴容、調大 ulimit、重啟服務釋放洩漏
服務異常 systemctl status → journalctl 查崩潰原因 重啟服務、檢查依賴服務狀態、排查 OOM killer
許可權問題 ls -l / id / 檢查 sudo 修正檔案許可權(chmod/chown)、新增 sudo 授權
依賴缺失 rpm -qa / pip list → 對比版本要求 安裝缺失包、版本降級/升級
資料異常 檢查資料完整性 → 對比 schema 資料修復、遷移、回滾

輸出解決方案時遵循的結構:

【解決方案】
1. 排查步驟
   - 第一步:xxx
   - 第二步:xxx
2. 修復操作
   - 操作命令(可複製執行)
3. 驗證方法
   - 驗證命令 + 預期結果
4. 回滾方案(如適用)

Step 6 — 生成交付物

6.1 判斷生成模式

if len(root_causes) == 1:
    mode = 'single'   # 單故障 → 標準五段式報告
else:
    mode = 'multi'    # 多故障 → 總覽 + 逐項分析 + 綜合建議

6.2 Word 文件(單故障模式)

生成 部署故障分析及解決方案_YYYY-MM-DD_HHmmss.docx,標準五段式結構(同原版)。

6.3 Word 文件(多故障模式)

mode == 'multi' 時,增加總覽頁和綜合建議:

封面
├── 總體概況表
│   ├── 文件編號 / 分析時間 / 部署目標 / 部署計劃
│   ├── 總日誌數 / 總錯誤數 / 歸併根因數
│   └── 最高故障級別
├── 錯誤全景圖(表格)
│   ├── # / 故障 / 類別 / 級別 / 出現次數
├── 逐項詳細分析
│   ├── 故障 1:...(完整五段式)
│   ├── 故障 2:...
│   └── ...
└── 綜合建議與整改清單
    └── 按優先順序排列的改進項

重點:每個故障頁有明確的 故障 N / 總N 標註,分隔線分隔。

6.4 使用 generate_report.py 指令碼

from scripts.generate_report import generate_fault_report, generate_multi_fault_report, append_to_excel

# 單故障
if len(faults) == 1:
    docx_path = generate_fault_report(output_path, faults[0])

# 多故障
else:
    docx_path = generate_multi_fault_report(output_path, faults)

# 批次追加 Excel(所有故障都寫一行)
for fault in faults:
    append_to_excel(xlsx_path, {...})

文件儲存路徑: ~/.hermes/skills/openclaw-imports/deploy-fault-analyzer/output/

Step 7 — 傳送交付物(必須執行)

⚠️ 分析完成後必須在同一條回覆中做兩件事:

  1. 貼出故障分析摘要(故障全景表 + 核心結論),讓使用者無需開啟檔案即可瞭解全貌
  2. 傳送 Word 檔案 — 使用 message 工具傳送檔案給使用者
# 傳送 .docx 檔案給使用者(以當前會話的 chat 通道傳送)
# 使用 message 工具: action=send, filePath=docx_path, caption='部署故障分析報告'

傳送規則: - 回覆訊息中貼摘要表(純文本,不依賴 markdown 表格渲染) - 同時呼叫 message 工具傳送 Word 檔案 - 傳送後回覆 NO_REPLY 避免重複訊息

摘要模板(回覆訊息中貼出):

🔍 部署故障分析結果

概覽:N條日誌,M條錯誤 → 歸併 K 個根因

| # | 故障 | 類別 | 級別 | 次數 | 定位 |
F1 | xxx | 資料異常 | P1 | 44 | xxx
F2 | ...

🎯 核心結論:xxx

📄 Word 報告已同步傳送,請查收。

Step 8 — 單條更新故障庫(互動式)

適用場景: 1. Step 2.6 中使用者確認指令碼已解決問題,且同意更新故障庫 2. 使用者主動說「錄入這條故障」「更新故障庫」「把這次問題加到故障庫」

注意:本流程僅寫入 MySQL fault_records,不修改 Excel。

8.1 Agent 起草記錄

根據會話上下文整理 JSON 草稿,欄位規則:

欄位 必填 規則
module_name 複用 Step 2.5A 推斷
issue_type 建議 複用 Step 2.5B 推斷
issue_description 完整報錯原文,參照 id:1110
solution_summary 明確修復動作,參照 id:1110
found_at 建議 預設今天 YYYY-MM-DD
delivery_mode 交付形態,如 私有云 / 行業雲 / 內部上雲
resource_pool 資源池名稱,如 北京九區
product_version 交付產品集版本,如 7.6.0
delivery_branch 交付分支,如 @X86@CUlinux / @ARM@CUlinux / @X86@CentOS
deployer 部署人姓名
word_file 預設 不涉及
remark 可寫關聯指令碼路徑

草稿 JSON 示例:

{
  "module_name": "DNS",
  "issue_type": "新建部署問題",
  "found_at": "2026-06-08",
  "issue_description": "+ neutron floatingip-create ...\nfloatingip 建立失敗,請檢查\n+ exit 1",
  "solution_summary": "部署表「內網dns雲主機是否通過外部網路訪問外網」TRUE 改 FALSE",
  "delivery_mode": "私有云",
  "resource_pool": "巴西CT雲",
  "product_version": "7.6.0",
  "delivery_branch": "@X86@CUlinux",
  "deployer": "田慶霖",
  "word_file": "不涉及",
  "remark": "指令碼庫命中: deploy-perfect-20250821/second_deploy/dns/dns_deploy/dns.sh"
}

將草稿儲存到 skill 目錄,例如:output/fault_draft_YYYY-MM-DD_HHmmss.json

8.2 展示草稿並等待使用者確認

向用戶展示完整草稿(模板如下),詢問:

📋 故障庫入庫草稿(請確認或補充)

模組:DNS
問題型別:新建部署問題
問題描述:
  <完整報錯原文...>
解決方法概要:
  部署表「內網dns雲主機是否通過外部網路訪問外網」TRUE 改 FALSE
交付形態:私有云
資源池:巴西CT雲 | 版本:7.6.0 | 分支:@X86@CUlinux | 部署人:田慶霖

請回復:確認同步 / 需要修改:<說明> / 取消

請確認或補充:回覆「確認同步」/「需要修改:…」/「取消」

7w4.net小蔥技能。

8.3 校驗與入庫

使用者確認後執行:

# 1. 校驗(不寫入)
python3 /data/work/scripts/insert_fault_record.py \
  --json output/fault_draft_YYYY-MM-DD_HHmmss.json --dry-run

# 2. 正式寫入(追加到最後,id = MAX(id)+1)
python3 /data/work/scripts/insert_fault_record.py \
  --json output/fault_draft_YYYY-MM-DD_HHmmss.json \
  --port 33307

# 3. 驗證
docker exec resource_pool_mysql mysql -upool_user -ppool_password_2024 fault_knowledge_base \
  -e "SELECT id, module_name, issue_type, LEFT(issue_description,80), LEFT(solution_summary,80) FROM fault_records ORDER BY id DESC LIMIT 1;"

校驗失敗時根據指令碼輸出修正草稿,重新展示給使用者確認,不得使用 --force 跳過校驗。


Python 指令碼模板

docx 生成指令碼

from docx import Document
from docx.shared import Inches, Pt, Cm, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from datetime import datetime
import os

def generate_fault_report(output_path, fault_data):
    """
    fault_data = {
        'fault_time': '2026-05-09 10:23:45',
        'error_type': 'ConnectionError',
        'error_message': '...',
        'stack_trace': '...',
        'affected_component': 'nova-api',
        'affected_scope': 'AZ-1 計算節點',
        'related_config': '/etc/nova/nova.conf',
        'error_category': '網路/連線故障',
        'fault_level': 'P1',
        'root_cause': '...',
        'evidence_lines': ['...', '...'],
        'solution_steps': [...],
        'verification': '...',
        'prevention': '...',
    }
    """
    doc = Document()

    # 標題
    title = doc.add_heading('部署故障分析及解決方案', level=0)
    title.alignment = WD_ALIGN_PARAGRAPH.CENTER

    # 文件資訊表
    doc.add_paragraph('')
    info_table = doc.add_table(rows=3, cols=2, style='Light Grid Accent 1')
    info_data = [
        ('文件編號', f"DOC-{datetime.now().strftime('%Y%m%d')}-{fault_data.get('fault_level','P2')}"),
        ('分析時間', datetime.now().strftime('%Y-%m-%d %H:%M:%S')),
        ('故障級別', fault_data.get('fault_level', 'P2')),
    ]
    for i, (k, v) in enumerate(info_data):
        info_table.rows[i].cells[0].text = k
        info_table.rows[i].cells[1].text = v

    doc.add_paragraph('')

    # 一、故障概述
    doc.add_heading('一、故障概述', level=1)
    doc.add_paragraph(f"故障時間:{fault_data.get('fault_time', '未知')}")
    doc.add_paragraph(f"影響元件:{fault_data.get('affected_component', '未知')}")
    doc.add_paragraph(f"影響範圍:{fault_data.get('affected_scope', '未知')}")
    doc.add_paragraph(f"錯誤型別:{fault_data.get('error_type', '未知')}")

    # 二、故障詳情
    doc.add_heading('二、故障詳情', level=1)
    doc.add_heading('錯誤訊息', level=2)
    doc.add_paragraph(fault_data.get('error_message', ''))

    if fault_data.get('stack_trace'):
        doc.add_heading('堆疊跟蹤', level=2)
        p = doc.add_paragraph()
        p.style = doc.styles['No Spacing']
        for line in fault_data['stack_trace'].split('\n')[:20]:
            doc.add_paragraph(line, style='No Spacing')

    if fault_data.get('related_config'):
        doc.add_paragraph(f"關聯配置:{fault_data['related_config']}")

    # 三、根因分析
    doc.add_heading('三、根因分析', level=1)
    doc.add_paragraph(f"錯誤分類:{fault_data.get('error_category', '未分類')}")
    doc.add_paragraph(f"根本原因:{fault_data.get('root_cause', '待進一步分析')}")

    if fault_data.get('evidence_lines'):
        doc.add_heading('關鍵證據', level=2)
        for i, line in enumerate(fault_data['evidence_lines'], 1):
            doc.add_paragraph(f"{i}. {line}")

    # 四、解決方案
    doc.add_heading('四、解決方案', level=1)
    for step in fault_data.get('solution_steps', []):
        doc.add_paragraph(step, style='List Bullet')

    if fault_data.get('verification'):
        doc.add_heading('驗證方法', level=2)
        doc.add_paragraph(fault_data['verification'])

    # 五、預防措施
    doc.add_heading('五、預防措施', level=1)
    doc.add_paragraph(fault_data.get('prevention', '—'))

    doc.save(output_path)
    return output_path

邊界情況與注意事項

當輸入過於模糊時

如果日誌/文本中找不到明確的錯誤資訊,不要強行編造分析結果。此時: - 輸出一份簡要的"日誌初步篩查報告" Word 文件 - 在文件中標註"待補充資訊" - Excel 中錯誤類別記為"待分類"

當單個輸入包含多個錯誤時(重要)

流程: 1. Step 2A 自動歸類 → 按關鍵詞將錯誤分入不同類別 2. Step 2B 錯誤去重 → 歸併重複錯誤,統計每個根因出現次數 3. 過濾"使用者操作"類(已終止/使用者終止)→ 不計入故障清單 4. 對每個根因執行 Step 2.5,按 module_nameissue_typeissue_description 查詢 MySQL 故障知識庫 5. 按故障級別(P1→P2→P3)和歷史命中置信度排序輸出 6. Word 文件使用多故障模式 → 生成總覽表 + 逐項分析 + 歷史故障庫匹配 7. Excel 中每個根因佔一行,必要時同步到 MySQL 故障庫

真實案例參考

以下是從實際部署日誌中提取的典型錯誤模式,用於指導分類:

模式 1 — 部署表日期格式錯誤(44條 → 1個根因)

[CHECK_DEPLOY_F5B45D] 匯入表:日期格式不正確45677.7661111, 格式yyyy-mm-dd hh:mm:ss
→ 類別:資料異常 | 根因:Excel日期序列號未轉換 | 級別:P1

模式 2 — 資源池名稱不一致(35條 → 1個根因)

[CHECK_DEPLOY_F5B45D] 資源池名稱不正確 sheet11:呼和交付驗證雲池; sheet1:呼和國產化...
→ 類別:配置錯誤 | 根因:多sheet資源池名未統一 | 級別:P1

模式 3 — 部署包目錄缺失(6條 → 1個根因)

[PREP_UPLOAD_33B3DC] /opt/ImageManager: 缺失
→ 類別:資源不足 | 根因:部署包未上傳或不在此次部署範圍 | 級別:P1

模式 4 — RPM 安裝誤報(1條 → 不阻塞)

[PREP_TASK_53658B] rpm -ivh → already installed → exit code ≠ 0
→ 類別:服務異常 | 根因:安裝指令碼未處理"已安裝"狀態 | 級別:P3

使用者操作類不計入故障

以下訊息型別不歸類為故障,僅在報告中備註: - 使用者已終止部署流程 → 使用者主動操作 - 部署已自動暫停,等待使用者確認 → 流程機制,非故障本身 - 使用者確認繼續 → 流程恢復

路徑規範

所有輸出統一在 skill 目錄下:

~/.hermes/skills/openclaw-imports/deploy-fault-analyzer/
├── SKILL.md
├── output/          # Word 文件輸出
├── data/
│   ├── problems.xlsx   # Excel 知識庫
│   └── raw/             # 原始輸入存檔

MySQL 故障知識庫不在 skill 目錄下,固定查詢 fault_knowledge_base.fault_records。 相關指令碼均在 /data/work/scripts/sync_fault_knowledge_base.py(Excel 批次同步)、insert_fault_record.py(單條入庫)、search_deploy_scripts.py(指令碼庫檢索)。


快速參考

使用者說什麼 你做什麼
上傳 xxxx.log 讀取 → 提取ERROR行 → 推斷 module_name/issue_type → 查詢 MySQL 故障庫 → 分析 → 生成 docx + 寫入 xlsx → 傳送 docx 給使用者 + 貼摘要
貼上報錯文本 同日志流程,必須先查 fault_knowledge_base.fault_records 再給結論
"幫我看下這個報錯" 識別附帶文本 → 查 MySQL 歷史案例 → 分析 → 生成 docx + 寫入 xlsx → 傳送 docx 給使用者 + 貼摘要
"查一下之前類似問題" 優先查詢 fault_knowledge_base.fault_records,按模組、問題型別、問題描述返回歷史案例
"這個錯之前遇到過嗎" 在 MySQL 故障庫中搜索匹配的 issue_descriptionsolution_summary
故障庫未命中 告知使用者 → search_deploy_scripts.py 檢索 /data/scripts/ → 詢問是否解決 → 可選進入 Step 8
"同步故障庫" / "把 Excel 故障庫入庫" sync_fault_knowledge_base.py --dry-run → 確認後正式同步
"更新故障庫" / "錄入這條故障" / "把這次問題加到故障庫" Step 8:起草 JSON → 使用者確認 → insert_fault_record.py --dry-run → 正式寫入

🤖 AI 評測

這是一款專業級的部署故障分析助手,能自動解析日誌、匹配歷史故障庫、生成 Word 報告。文件詳細、流程完整、覆蓋面廣是其優勢,對中文使用者友好。但檔案過大、配置依賴多、某些步驟描述不夠具體,實際使用時可能需要較長的學習成本。總體質量中等偏上,適合有特定運維環境支撐的專業使用者使用。

📊 多維度評分

適應性4.4
規範性4.2
有效性4.4
可靠性4
可信度5

📁 包含檔案 (4 個)

📄 SKILL.md 45.8 KB
📄 _meta.json 140 B
📄 scripts/generate_report.py 18.3 KB
📄 skill-card.md 2.4 KB