fix: humanize observability operations copy
Some checks failed
CD Pipeline / deploy (push) Failing after 23s
Some checks failed
CD Pipeline / deploy (push) Failing after 23s
This commit is contained in:
@@ -402,7 +402,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
|
||||
# ==========================================
|
||||
# 系統版本與路徑
|
||||
# ==========================================
|
||||
SYSTEM_VERSION = "V10.675"
|
||||
SYSTEM_VERSION = "V10.676"
|
||||
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
|
||||
public_url = PUBLIC_URL # 用於模板顯示
|
||||
|
||||
|
||||
@@ -752,3 +752,4 @@ POSTGRES_HOST=momo-db
|
||||
| 2026-06-25 | 待確認候選 API 不可回傳 raw matcher code | V10.673 起 `match_reasons` 相容欄位也改回白話理由,避免前台或檢視 payload 時再次看到 `variant_selection_review`、`focused_exact_identity_*` 等工程代碼。 |
|
||||
| 2026-06-25 | 共用成長流程列手機版不可溢出畫面 | V10.674 起全站 `momo-growth-rail` 在手機寬度改為換行呈現,避免「評估 / 分析 / 建議 / 解法 / 治理」流程 chip 超出視覺邊界。 |
|
||||
| 2026-06-25 | 匯入、缺貨、設定與通知模板頁不可外露 SQL / 資料表 / 模板代碼 | V10.675 起匯入 job API 對前台回傳白話處置訊息,保留 raw error 於 DB/log;自動匯入失敗通知不再顯示 `psycopg2`、`daily_sales_snapshot`、`snapshot_date` 等內部字串;缺貨首頁、系統設定與通知模板列表改用營運語言,並補上逾時匯入任務重置與取消 API。 |
|
||||
| 2026-06-25 | 觀測台入口與通知預覽不可用工程主語干擾營運判讀 | V10.676 起觀測台導覽統一使用「AI 分工矩陣」,通知模板列表會把 K8s/Pod/資料庫/CI Pipeline 等內部詞轉成服務健康、資料連線與部署流程;主機健康事件與自癒劇本改顯示任務/問題/處置提醒,不直接露 `unknown_task`、`scheduler_task_failure`、`CODE_FIX` 等 raw code。 |
|
||||
|
||||
@@ -988,7 +988,7 @@ def agent_orchestration_dashboard():
|
||||
recommendations.append({
|
||||
'severity': 'high', 'agent': ag['label'],
|
||||
'finding': f"錯誤率 {ag['error_rate']:.1f}%({ag['errors']}/{ag['calls']})",
|
||||
'suggestion': '觸發程式碼審查流程找回歸問題(ai_calls 觀測台一鍵)',
|
||||
'suggestion': '觸發程式碼審查流程找回歸問題(可由 AI 流量控制台執行)',
|
||||
})
|
||||
# 規則 3:MCP 編排率 < 5% 但 calls 多 → 建議擴大 MCP 使用
|
||||
if mcp_calls_table_exists and ag['mcp_rate'] < 5 and ag['calls'] > 50:
|
||||
|
||||
@@ -157,11 +157,11 @@
|
||||
|
||||
<section class="runtime-main">
|
||||
<div class="runtime-stack">
|
||||
<article class="runtime-table-shell"><div class="runtime-table-title"><div><div class="runtime-label">事件紀錄</div><h3>最近 10 筆事件</h3></div></div><div class="table-responsive">{% if recent_incidents %}<table class="table table-sm mb-0"><thead class="table-light"><tr><th>時間</th><th>任務</th><th>錯誤</th><th>等級</th><th>狀態</th><th>訊息</th></tr></thead><tbody>{% for i in recent_incidents %}<tr><td><small>{{ i.created_at }}</small></td><td><code>{{ i.task_name }}</code></td><td><span class="badge bg-secondary">{{ i.error_type }}</span></td><td><span class="badge {% if i.severity in ('P0','P1') %}bg-danger{% elif i.severity == 'P2' %}bg-warning{% else %}bg-info{% endif %}">{{ i.severity }}</span></td><td>{{ i.status }}</td><td><small class="text-muted">{{ i.error_message }}</small></td></tr>{% endfor %}</tbody></table>{% else %}<div class="text-muted text-center p-3 small">尚無事件紀錄</div>{% endif %}</div></article>
|
||||
<article class="runtime-table-shell"><div class="runtime-table-title"><div><div class="runtime-label">事件紀錄</div><h3>最近 10 筆事件</h3></div></div><div class="table-responsive">{% if recent_incidents %}{% set task_labels = {'unknown_task': '待確認任務', 'ElephantAlphaAutonomousEngine': 'AI 自癒監控', 'run_icaim_analysis_task': '市場分析任務'} %}{% set error_labels = {'ollama_unhealthy': 'AI 模型主機不穩', 'scheduler_task_failure': '排程任務異常', 'crawler_timeout': '資料擷取逾時', 'python_exception': '程式例外'} %}<table class="table table-sm mb-0"><thead class="table-light"><tr><th>時間</th><th>任務</th><th>問題</th><th>等級</th><th>狀態</th><th>處置提醒</th></tr></thead><tbody>{% for i in recent_incidents %}{% set incident_msg = i.error_message or '' %}<tr><td><small>{{ i.created_at }}</small></td><td><span>{{ task_labels.get(i.task_name, '系統任務') }}</span></td><td><span class="badge bg-secondary">{{ error_labels.get(i.error_type, '系統異常') }}</span></td><td><span class="badge {% if i.severity in ('P0','P1') %}bg-danger{% elif i.severity == 'P2' %}bg-warning{% else %}bg-info{% endif %}">{{ i.severity }}</span></td><td>{{ i.status }}</td><td><small class="text-muted">{% if 'Ollama' in incident_msg %}AI 模型主機暫時不穩,已進入自癒監控。{% elif 'not defined' in incident_msg or 'Traceback' in incident_msg %}資料流程發生程式例外,需由修復流程處理。{% elif 'scheduler_task_failure' in incident_msg %}排程任務異常,需確認下次執行是否恢復。{% else %}{{ incident_msg|replace('_', ' ')|truncate(90) }}{% endif %}</small></td></tr>{% endfor %}</tbody></table>{% else %}<div class="text-muted text-center p-3 small">尚無事件紀錄</div>{% endif %}</div></article>
|
||||
<article class="runtime-table-shell"><div class="runtime-table-title"><div><div class="runtime-label">自癒紀錄</div><h3>最近 10 筆自癒</h3></div></div><div class="table-responsive">{% if recent_heals %}<table class="table table-sm mb-0"><thead class="table-light"><tr><th>時間</th><th>動作</th><th>結果</th><th class="text-end">耗時</th><th>細節</th></tr></thead><tbody>{% for h in recent_heals %}<tr><td><small>{{ h.created_at }}</small></td><td><span class="badge bg-info">{{ h.action_type or '—' }}</span></td><td>{% if h.result == 'success' %}<span class="badge bg-success">成功</span>{% elif h.result == 'failed' %}<span class="badge bg-danger">失敗</span>{% else %}<span class="badge bg-secondary">{{ h.result }}</span>{% endif %}</td><td class="text-end">{{ h.duration_ms }} ms</td><td><small class="text-muted">{{ h.action_detail }}</small></td></tr>{% endfor %}</tbody></table>{% else %}<div class="text-muted text-center p-3 small">尚無自癒紀錄</div>{% endif %}</div></article>
|
||||
</div>
|
||||
<aside class="runtime-stack">
|
||||
<article class="runtime-table-shell"><div class="runtime-table-title"><div><div class="runtime-label">自癒劇本</div><h3>AutoHeal 劇本</h3></div></div><div class="table-responsive">{% if playbook_ranking %}<table class="table table-sm mb-0"><thead class="table-light"><tr><th>名稱</th><th>成功率</th><th>狀態</th><th>切換</th></tr></thead><tbody>{% for p in playbook_ranking %}<tr><td><strong>{{ p.name }}</strong><br><small class="text-muted"><code>{{ p.error_type }}</code> · {{ p.action_type }}</small></td><td>{% if (p.success + p.fail) > 0 %}<strong>{{ "%.0f"|format(p.success_rate) }}%</strong>{% else %}<span class="text-muted">—</span>{% endif %}</td><td>{% if p.is_active %}<span class="badge bg-success">啟用</span>{% else %}<span class="badge bg-secondary">停用</span>{% endif %}</td><td><button class="btn btn-sm btn-outline-secondary" onclick="togglePlaybook({{ p.id }}, {{ p.name|tojson }})">切換</button></td></tr>{% endfor %}</tbody></table>{% else %}<div class="text-muted text-center p-3 small">尚無劇本資料</div>{% endif %}</div></article>
|
||||
<article class="runtime-table-shell"><div class="runtime-table-title"><div><div class="runtime-label">自癒劇本</div><h3>AutoHeal 劇本</h3></div></div><div class="table-responsive">{% if playbook_ranking %}{% set playbook_error_labels = {'python_exception': '程式例外', 'scheduler_task_failure': '排程異常', 'ollama_unhealthy': 'AI 模型主機不穩'} %}{% set playbook_action_labels = {'CODE_FIX': '程式修復', 'SERVICE_RESTART': '服務重啟', 'ALERT_ONLY': '告警追蹤'} %}<table class="table table-sm mb-0"><thead class="table-light"><tr><th>名稱</th><th>成功率</th><th>狀態</th><th>切換</th></tr></thead><tbody>{% for p in playbook_ranking %}<tr><td><strong>{{ p.name }}</strong><br><small class="text-muted">{{ playbook_error_labels.get(p.error_type, '系統異常') }} · {{ playbook_action_labels.get(p.action_type, '自癒處理') }}</small></td><td>{% if (p.success + p.fail) > 0 %}<strong>{{ "%.0f"|format(p.success_rate) }}%</strong>{% else %}<span class="text-muted">—</span>{% endif %}</td><td>{% if p.is_active %}<span class="badge bg-success">啟用</span>{% else %}<span class="badge bg-secondary">停用</span>{% endif %}</td><td><button class="btn btn-sm btn-outline-secondary" onclick="togglePlaybook({{ p.id }}, {{ p.name|tojson }})">切換</button></td></tr>{% endfor %}</tbody></table>{% else %}<div class="text-muted text-center p-3 small">尚無劇本資料</div>{% endif %}</div></article>
|
||||
<article class="runtime-table-shell"><div class="runtime-table-title"><div><div class="runtime-label">備份</div><h3>備份歷史 7 日</h3></div></div><div class="table-responsive">{% if backup_history %}<table class="table table-sm mb-0"><thead class="table-light"><tr><th>時間</th><th>狀態</th><th class="text-end">MB</th></tr></thead><tbody>{% for b in backup_history %}<tr><td><small>{{ b.created_at }}</small></td><td>{% if b.status == 'success' %}<span class="badge bg-success">成功</span>{% else %}<span class="badge bg-danger">{{ b.status }}</span>{% endif %}</td><td class="text-end">{{ b.size_mb }}</td></tr>{% endfor %}</tbody></table>{% else %}<div class="text-muted text-center p-3 small">過去 7 日無備份紀錄</div>{% endif %}</div></article>
|
||||
</aside>
|
||||
</section>
|
||||
|
||||
@@ -590,7 +590,7 @@
|
||||
<div class="obs-section-eyebrow">03 戰情指揮</div>
|
||||
<h3>戰情室</h3>
|
||||
<div class="obs-route-list">
|
||||
<a class="obs-route-card" href="/observability/agent_orchestration"><span class="obs-route-icon"><i class="fas fa-network-wired"></i></span><span><span class="obs-route-title">Agent 編排矩陣</span><span class="obs-route-desc">四 Agent × 模型 × MCP × RAG 分工。</span></span><span class="obs-route-code">02</span></a>
|
||||
<a class="obs-route-card" href="/observability/agent_orchestration"><span class="obs-route-icon"><i class="fas fa-network-wired"></i></span><span><span class="obs-route-title">AI 分工矩陣</span><span class="obs-route-desc">四類 AI 分工、模型、工具與知識命中。</span></span><span class="obs-route-code">02</span></a>
|
||||
<a class="obs-route-card" href="/observability/business_intel"><span class="obs-route-icon"><i class="fas fa-briefcase"></i></span><span><span class="obs-route-title">商業面 × AI</span><span class="obs-route-desc">AI 決策是否真的轉成生意動作。</span></span><span class="obs-route-code">03</span></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
<i class="fas fa-gauge-high"></i><span>觀測台總覽</span><span class="momo-nav-code">01</span>
|
||||
</a>
|
||||
<a class="momo-nav-sublink {% if _active_page == 'obs_agent_orchestration' %}is-active{% endif %}" href="/observability/agent_orchestration">
|
||||
<i class="fas fa-network-wired"></i><span>Agent 編排矩陣</span><span class="momo-nav-code">02</span>
|
||||
<i class="fas fa-network-wired"></i><span>AI 分工矩陣</span><span class="momo-nav-code">02</span>
|
||||
</a>
|
||||
<a class="momo-nav-sublink {% if _active_page == 'obs_business_intel' %}is-active{% endif %}" href="/observability/business_intel">
|
||||
<i class="fas fa-briefcase"></i><span>商業面 × AI</span><span class="momo-nav-code">03</span>
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="/observability/agent_orchestration">
|
||||
<i class="fas fa-network-wired me-2"></i>Agent 編排矩陣
|
||||
<i class="fas fa-network-wired me-2"></i>AI 分工矩陣
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
@@ -378,8 +378,16 @@ function publicTemplateText(text) {
|
||||
return output
|
||||
.replace(/CI\/CD Pipeline SUCCESS/g, '部署流程成功')
|
||||
.replace(/CI\/CD Pipeline FAILED/g, '部署流程失敗')
|
||||
.replace(/K8s Pod/g, '服務健康')
|
||||
.replace(/Pod 重啟/g, '服務重啟')
|
||||
.replace(/Pipeline/g, '部署流程')
|
||||
.replace(/Commit/g, '更新內容');
|
||||
.replace(/Commit/g, '更新內容')
|
||||
.replace(/備份資料庫/g, '建立營運資料備份')
|
||||
.replace(/資料庫狀態/g, '資料連線狀態')
|
||||
.replace(/資料庫大小/g, '資料容量')
|
||||
.replace(/資料庫:/g, '資料連線:')
|
||||
.replace(/資料庫:/g, '資料連線:')
|
||||
.replace(/資料庫/g, '資料連線');
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
@@ -438,6 +446,7 @@ function renderTemplates() {
|
||||
|
||||
tbody.innerHTML = filtered.map(t => {
|
||||
const catName = categories.find(c => c.code === t.category)?.name || t.category;
|
||||
const displayName = publicTemplateText(t.name || '未命名通知');
|
||||
const preview = publicTemplateText(`${t.emoji_prefix || ''} ${t.title || ''}\n${t.body || ''}`).substring(0, 96);
|
||||
const channelLabel = t.channel === 'telegram' ? 'Telegram' : t.channel === 'line' ? 'LINE' : '雙渠道';
|
||||
return `
|
||||
@@ -447,7 +456,7 @@ function renderTemplates() {
|
||||
${t.is_active ? '啟用' : '停用'}
|
||||
</span>
|
||||
</td>
|
||||
<td>${escapeHtml(t.name || '未命名通知')}</td>
|
||||
<td>${escapeHtml(displayName)}</td>
|
||||
<td><span class="notification-category-badge">${catName}</span></td>
|
||||
<td>${channelLabel}</td>
|
||||
<td class="template-preview">${escapeHtml(preview)}...</td>
|
||||
|
||||
Reference in New Issue
Block a user