feat(api): Phase 13.2 #79 SignOz MCP Tool 整合

整合真實 SignOzClient 到 MCP Bridge:
- gold_metrics: RPS + Error Rate + P99 Latency
- trace_url: 動態 Trace URL 生成
- system_metrics: CPU/Disk 系統指標

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-03-25 12:44:46 +08:00
parent e36dab1aee
commit 23b753dbec

View File

@@ -200,16 +200,21 @@ class MCPBridge:
self._tool_cache: dict[str, list[MCPTool]] = {}
self._http_client = httpx.AsyncClient(timeout=30.0)
# 註冊 Mock Servers (Phase 3: 先驗證介面)
self._register_mock_servers()
# 註冊 MCP Servers (Phase 13.2: 整合真實服務)
self._register_servers()
def _register_mock_servers(self) -> None:
"""註冊 Mock MCP Servers (開發測試用)"""
def _register_servers(self) -> None:
"""註冊 MCP Servers"""
self._servers["kubernetes"] = MCPServer(
name="kubernetes",
transport=MCPTransport.HTTP,
endpoint="http://localhost:8081/mcp",
)
self._servers["signoz"] = MCPServer(
name="signoz",
transport=MCPTransport.HTTP,
endpoint="http://192.168.0.188:3301", # SignOz Query Service
)
self._servers["filesystem"] = MCPServer(
name="filesystem",
transport=MCPTransport.STDIO,
@@ -319,6 +324,47 @@ class MCPBridge:
server_name=server.name,
),
],
"signoz": [
MCPTool(
name="gold_metrics",
description="Get Gold Metrics (RPS, Error Rate, P99 Latency) for a service",
input_schema={
"type": "object",
"properties": {
"service_name": {"type": "string", "description": "Service name (e.g., api-gateway)"},
"namespace": {"type": "string", "description": "K8s namespace (default: awoooi-prod)"},
"time_window_minutes": {"type": "integer", "description": "Time window in minutes (default: 10)"},
},
"required": ["service_name"],
},
server_name=server.name,
),
MCPTool(
name="trace_url",
description="Generate SignOz trace URL for debugging a service",
input_schema={
"type": "object",
"properties": {
"service_name": {"type": "string", "description": "Service name"},
"window_minutes": {"type": "integer", "description": "Time window ± minutes (default: 5)"},
},
"required": ["service_name"],
},
server_name=server.name,
),
MCPTool(
name="system_metrics",
description="Get system metrics (CPU, Disk I/O) from SignOz",
input_schema={
"type": "object",
"properties": {
"host": {"type": "string", "description": "Host IP (default: 192.168.0.188)"},
"time_window_minutes": {"type": "integer", "description": "Time window in minutes (default: 5)"},
},
},
server_name=server.name,
),
],
"database": [
MCPTool(
name="query",
@@ -568,6 +614,82 @@ class MCPBridge:
else:
return {"error": f"Unknown kubernetes tool: {tool_name}"}
# =============================================
# SignOz: 監控指標查詢 (Phase 13.2 #79)
# =============================================
elif server.name == "signoz":
from src.services.signoz_client import get_signoz_client
signoz = get_signoz_client()
if tool_name == "gold_metrics":
# 取得 Gold Metrics (RPS, Error Rate, P99)
service_name = parameters.get("service_name", "")
if not service_name:
return {"error": "Missing 'service_name' parameter"}
namespace = parameters.get("namespace", "awoooi-prod")
time_window = parameters.get("time_window_minutes", 10)
metrics = await signoz.get_gold_metrics(
service_name=service_name,
namespace=namespace,
time_window_minutes=time_window,
)
return {
"service_name": metrics.service_name,
"namespace": metrics.namespace,
"rps": round(metrics.rps, 2),
"rps_trend": metrics.rps_trend,
"error_rate": round(metrics.error_rate, 2),
"error_count": metrics.error_count,
"total_requests": metrics.total_requests,
"p50_latency_ms": round(metrics.p50_latency_ms, 1),
"p95_latency_ms": round(metrics.p95_latency_ms, 1),
"p99_latency_ms": round(metrics.p99_latency_ms, 1),
"latency_trend": metrics.latency_trend,
"summary": metrics.to_summary(),
}
elif tool_name == "trace_url":
# 生成 SignOz Trace URL
service_name = parameters.get("service_name", "")
if not service_name:
return {"error": "Missing 'service_name' parameter"}
window_minutes = parameters.get("window_minutes", 5)
url = signoz.generate_trace_url(
service_name=service_name,
window_minutes=window_minutes,
)
return {
"service_name": service_name,
"trace_url": url,
"window_minutes": window_minutes,
}
elif tool_name == "system_metrics":
# 取得系統指標 (CPU/Disk)
host = parameters.get("host", "192.168.0.188")
time_window = parameters.get("time_window_minutes", 5)
metrics = await signoz.get_system_metrics(
_host=host,
time_window_minutes=time_window,
)
return {
"host": host,
"cpu": metrics.get("cpu", {}),
"disk": metrics.get("disk", {}),
"time_range": metrics.get("time_range", {}),
}
else:
return {"error": f"Unknown signoz tool: {tool_name}"}
# =============================================
# Database: 查詢 incident/approval 歷史 (Phase 13.2 #81)
# =============================================