// pod_logs.go - 获取 Pod 容器日志(只读) // Logan.Li package tools import ( "context" "fmt" "strings" k8sclient "ezops/pkg/kubernetesclient" ) // PodLogsTool 拉取 Pod 日志 // Logan.Li type PodLogsTool struct { client *k8sclient.Client namespace string podName string container string } // NewPodLogsTool 创建日志工具 // Logan.Li func NewPodLogsTool(client *k8sclient.Client, namespace, podName, container string) *PodLogsTool { return &PodLogsTool{client: client, namespace: namespace, podName: podName, container: container} } // Name 工具名 // Logan.Li func (t *PodLogsTool) Name() string { return "pod_logs" } // Description 给 LLM 的说明 // Logan.Li func (t *PodLogsTool) Description() string { return "获取目标 Pod 容器的最近日志(只读)。排障时优先使用此工具,比 pod_execute tail 更高效。" + "未选 Pod 时需通过 name 参数指定 Pod 名。" } // Parameters JSON Schema // Logan.Li func (t *PodLogsTool) Parameters() map[string]interface{} { return map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "pod": map[string]interface{}{ "type": "string", "description": "Pod 名称;会话已绑定 Pod 时可省略", }, "container": map[string]interface{}{ "type": "string", "description": "容器名;多容器时指定,默认会话绑定容器", }, "tail_lines": map[string]interface{}{ "type": "integer", "description": "返回最近行数,默认 200,最大 2000", }, }, } } // RiskLevel 只读安全 // Logan.Li func (t *PodLogsTool) RiskLevel() RiskLevel { return RiskSafe } // Execute 拉取日志 // Logan.Li func (t *PodLogsTool) Execute(ctx context.Context, args map[string]interface{}) (*Result, error) { pod := strings.TrimSpace(StringParam(args, "pod")) if pod == "" { pod = t.podName } if pod == "" { return &Result{Success: false, Error: "请指定 pod 参数或在前端选择目标 Pod"}, nil } container := strings.TrimSpace(StringParam(args, "container")) if container == "" { container = t.container } tail := IntParam(args, "tail_lines") if tail <= 0 { tail = 200 } if tail > 2000 { tail = 2000 } logs, err := t.client.GetPodLogs(t.namespace, pod, container, tail) if err != nil { return &Result{Success: false, Error: fmt.Sprintf("获取日志失败: %v", err)}, nil } if strings.TrimSpace(logs) == "" { return &Result{Success: true, Output: "(日志为空)"}, nil } return &Result{Success: true, Output: logs}, nil }