From f63bc3209881a1dd176e40d2fff2c4a22fb53d83 Mon Sep 17 00:00:00 2001 From: josunect Date: Wed, 3 Dec 2025 12:35:35 +0000 Subject: [PATCH 1/6] Update logs tool Signed-off-by: josunect --- pkg/kiali/logs.go | 21 ++------------ pkg/toolsets/kiali/logs.go | 59 ++++---------------------------------- 2 files changed, 8 insertions(+), 72 deletions(-) diff --git a/pkg/kiali/logs.go b/pkg/kiali/logs.go index aae6a8eb5..64f10d4ff 100644 --- a/pkg/kiali/logs.go +++ b/pkg/kiali/logs.go @@ -15,12 +15,9 @@ import ( // - namespace: the namespace containing the workload // - workload: the name of the workload // - container: container name (optional, will be auto-detected if not provided) -// - service: service name (optional) // - duration: time duration (e.g., "5m", "1h") - optional -// - logType: type of logs (app, proxy, ztunnel, waypoint) - optional -// - sinceTime: Unix timestamp for start time - optional // - maxLines: maximum number of lines to return - optional -func (k *Kiali) WorkloadLogs(ctx context.Context, namespace string, workload string, container string, service string, duration string, logType string, sinceTime string, maxLines string) (string, error) { +func (k *Kiali) WorkloadLogs(ctx context.Context, namespace string, workload string, container string, duration string, maxLines string) (string, error) { if namespace == "" { return "", fmt.Errorf("namespace is required") } @@ -77,7 +74,7 @@ func (k *Kiali) WorkloadLogs(ctx context.Context, namespace string, workload str continue } - podLogs, err := k.PodLogs(ctx, namespace, pod.Name, podContainer, workload, service, duration, logType, sinceTime, maxLines) + podLogs, err := k.PodLogs(ctx, namespace, pod.Name, podContainer, workload, duration, maxLines) if err != nil { // Log the error but continue with other pods allLogs = append(allLogs, fmt.Sprintf("Error getting logs for pod %s: %v", pod.Name, err)) @@ -101,12 +98,9 @@ func (k *Kiali) WorkloadLogs(ctx context.Context, namespace string, workload str // - podName: the name of the pod // - container: container name (optional, will be auto-detected if not provided) // - workload: workload name (optional) -// - service: service name (optional) // - duration: time duration (e.g., "5m", "1h") - optional -// - logType: type of logs (app, proxy, ztunnel, waypoint) - optional -// - sinceTime: Unix timestamp for start time - optional // - maxLines: maximum number of lines to return - optional -func (k *Kiali) PodLogs(ctx context.Context, namespace string, podName string, container string, workload string, service string, duration string, logType string, sinceTime string, maxLines string) (string, error) { +func (k *Kiali) PodLogs(ctx context.Context, namespace string, podName string, container string, workload string, duration string, maxLines string) (string, error) { if namespace == "" { return "", fmt.Errorf("namespace is required") } @@ -167,18 +161,9 @@ func (k *Kiali) PodLogs(ctx context.Context, namespace string, podName string, c if workload != "" { q.Set("workload", workload) } - if service != "" { - q.Set("service", service) - } if duration != "" { q.Set("duration", duration) } - if logType != "" { - q.Set("logType", logType) - } - if sinceTime != "" { - q.Set("sinceTime", sinceTime) - } if maxLines != "" { q.Set("maxLines", maxLines) } diff --git a/pkg/toolsets/kiali/logs.go b/pkg/toolsets/kiali/logs.go index 5c74ce689..3c3be0694 100644 --- a/pkg/toolsets/kiali/logs.go +++ b/pkg/toolsets/kiali/logs.go @@ -1,7 +1,6 @@ package kiali import ( - "encoding/json" "fmt" "github.com/google/jsonschema-go/jsonschema" @@ -62,7 +61,6 @@ func workloadLogsHandler(params api.ToolHandlerParams) (*api.ToolCallResult, err // Extract required parameters namespace, _ := params.GetArguments()["namespace"].(string) workload, _ := params.GetArguments()["workload"].(string) - k := params.NewKiali() if namespace == "" { return api.NewToolCallResult("", fmt.Errorf("namespace parameter is required")), nil } @@ -76,8 +74,7 @@ func workloadLogsHandler(params api.ToolHandlerParams) (*api.ToolCallResult, err tail := params.GetArguments()["tail"] // Convert parameters to Kiali API format - var duration, logType, sinceTime, maxLines string - var service string // We don't have service parameter in our schema, but Kiali API supports it + var duration, maxLines string // Convert since to duration (Kiali expects duration format like "5m", "1h") if since != "" { @@ -96,56 +93,10 @@ func workloadLogsHandler(params api.ToolHandlerParams) (*api.ToolCallResult, err } } - // If no container specified, we need to get workload details first to find the main app container - if container == "" { - workloadDetails, err := k.WorkloadDetails(params.Context, namespace, workload) - if err != nil { - return api.NewToolCallResult("", fmt.Errorf("failed to get workload details: %v", err)), nil - } - - // Parse the workload details JSON to extract container names - var workloadData struct { - Pods []struct { - Name string `json:"name"` - Containers []struct { - Name string `json:"name"` - } `json:"containers"` - } `json:"pods"` - } - - if err := json.Unmarshal([]byte(workloadDetails), &workloadData); err != nil { - return api.NewToolCallResult("", fmt.Errorf("failed to parse workload details: %v", err)), nil - } - - if len(workloadData.Pods) == 0 { - return api.NewToolCallResult("", fmt.Errorf("no pods found for workload %s in namespace %s", workload, namespace)), nil - } - - // Find the main application container (not istio-proxy or istio-init) - for _, pod := range workloadData.Pods { - for _, c := range pod.Containers { - if c.Name != "istio-proxy" && c.Name != "istio-init" { - container = c.Name - break - } - } - if container != "" { - break - } - } - - // If no app container found, use the first container - if container == "" && len(workloadData.Pods) > 0 && len(workloadData.Pods[0].Containers) > 0 { - container = workloadData.Pods[0].Containers[0].Name - } - } - - if container == "" { - return api.NewToolCallResult("", fmt.Errorf("no container found for workload %s in namespace %s", workload, namespace)), nil - } - - // Use the WorkloadLogs method with the correct parameters - logs, err := k.WorkloadLogs(params.Context, namespace, workload, container, service, duration, logType, sinceTime, maxLines) + // WorkloadLogs handles container auto-detection internally, so we can pass empty string + // if container is not specified + k := params.NewKiali() + logs, err := k.WorkloadLogs(params.Context, namespace, workload, container, duration, maxLines) if err != nil { return api.NewToolCallResult("", fmt.Errorf("failed to get workload logs: %v", err)), nil } From 759869e6f37be3f537508c6ebd13ff0e676eeb00 Mon Sep 17 00:00:00 2001 From: josunect Date: Wed, 3 Dec 2025 12:51:16 +0000 Subject: [PATCH 2/6] Rename kiali_logs Signed-off-by: josunect --- README.md | 2 +- pkg/mcp/testdata/toolsets-kiali-tools.json | 2 +- pkg/toolsets/kiali/logs.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c6030bddc..7186d237b 100644 --- a/README.md +++ b/README.md @@ -382,7 +382,7 @@ In case multi-cluster support is enabled (default) and you have access to multip - `resource_type` (`string`) **(required)** - Type of resource to get details for (service, workload) - `step` (`string`) - Step between data points in seconds (e.g., '15'). Optional, defaults to 15 seconds -- **workload_logs** - Get logs for a specific workload's pods in a namespace. Only requires namespace and workload name - automatically discovers pods and containers. Optionally filter by container name, time range, and other parameters. Container is auto-detected if not specified. +- **kiali_workload_logs** - Get logs for a specific workload's pods in a namespace. Only requires namespace and workload name - automatically discovers pods and containers. Optionally filter by container name, time range, and other parameters. Container is auto-detected if not specified. - `container` (`string`) - Optional container name to filter logs. If not provided, automatically detects and uses the main application container (excludes istio-proxy and istio-init) - `namespace` (`string`) **(required)** - Namespace containing the workload - `since` (`string`) - Time duration to fetch logs from (e.g., '5m', '1h', '30s'). If not provided, returns recent logs diff --git a/pkg/mcp/testdata/toolsets-kiali-tools.json b/pkg/mcp/testdata/toolsets-kiali-tools.json index 29fed505d..485cddc67 100644 --- a/pkg/mcp/testdata/toolsets-kiali-tools.json +++ b/pkg/mcp/testdata/toolsets-kiali-tools.json @@ -287,6 +287,6 @@ "workload" ] }, - "name": "workload_logs" + "name": "kiali_workload_logs" } ] diff --git a/pkg/toolsets/kiali/logs.go b/pkg/toolsets/kiali/logs.go index 3c3be0694..c49152fb9 100644 --- a/pkg/toolsets/kiali/logs.go +++ b/pkg/toolsets/kiali/logs.go @@ -15,7 +15,7 @@ func initLogs() []api.ServerTool { // Workload logs tool ret = append(ret, api.ServerTool{ Tool: api.Tool{ - Name: "workload_logs", + Name: "kiali_workload_logs", Description: "Get logs for a specific workload's pods in a namespace. Only requires namespace and workload name - automatically discovers pods and containers. Optionally filter by container name, time range, and other parameters. Container is auto-detected if not specified.", InputSchema: &jsonschema.Schema{ Type: "object", From 9f8339701d1e31c55cb84fdb5e47f55f794ac10a Mon Sep 17 00:00:00 2001 From: josunect Date: Wed, 3 Dec 2025 14:16:49 +0000 Subject: [PATCH 3/6] Rerun Signed-off-by: josunect From d20649fb2c0c55a163a308c7dbafe40de96c30b9 Mon Sep 17 00:00:00 2001 From: josunect Date: Wed, 3 Dec 2025 14:37:18 +0000 Subject: [PATCH 4/6] Rerun Signed-off-by: josunect From d9517d46690d51bb6fc24bcd315db595801f7776 Mon Sep 17 00:00:00 2001 From: josunect Date: Wed, 3 Dec 2025 15:04:10 +0000 Subject: [PATCH 5/6] Rerun Signed-off-by: josunect From 48ef68ea79d141309f202f4c697628396a822336 Mon Sep 17 00:00:00 2001 From: josunect Date: Thu, 4 Dec 2025 09:05:53 +0000 Subject: [PATCH 6/6] Run CI Signed-off-by: josunect