From 290a4d5051c4666b359a990c7f7e2f986836c88c Mon Sep 17 00:00:00 2001 From: AdheipSingh Date: Wed, 27 Nov 2024 23:05:59 +0530 Subject: [PATCH] handle pod failure data in db --- cmd/analyze.go | 8 ++--- cmd/generate.go | 46 +++++++++++++++++++++++++++++ pkg/analyze/anthropic/anthropic.go | 12 ++++---- pkg/analyze/duckdb/duckdb.go | 47 ++++++++++++++++++++++++++++++ pkg/analyze/ollama/ollama.go | 4 +-- pkg/analyze/openai/openai.go | 12 ++++---- 6 files changed, 113 insertions(+), 16 deletions(-) create mode 100644 cmd/generate.go diff --git a/cmd/analyze.go b/cmd/analyze.go index 812098d..1a5b1cf 100644 --- a/cmd/analyze.go +++ b/cmd/analyze.go @@ -147,8 +147,8 @@ var AnalyzeCmd = &cobra.Command{ // debug for empty results if result == nil { - fmt.Println(yellow + "No results found in DuckDB." + reset) - return nil + fmt.Println(yellow + "No results found for pod in DuckDB, analyzing the namespace." + reset) + result, err = duckdb.FetchNamespaceEventsfromDb(namespace) } s.Suffix = " Analyzing events with LLM..." @@ -167,7 +167,6 @@ var AnalyzeCmd = &cobra.Command{ } else if llmProvider == "ollama" { // Use Ollama's respective function (assuming a similar function exists) gptResponse, err = ollama.AnalyzeEventsWithOllama(pod, namespace, result) - fmt.Println(gptResponse) } else { // This should never happen since validateLLMConfig ensures the provider is valid return fmt.Errorf("invalid LLM provider: %s", llmProvider) @@ -362,7 +361,8 @@ func parseAndSelectAnalysis(response string) bool { var analysis AnalysisResponse err := json.Unmarshal([]byte(response), &analysis) if err != nil { - log.Println("Failed to parse LLM response: %v", err) + fmt.Println(green + "Summary:\n" + reset + response) + return true } // Display the summary by default diff --git a/cmd/generate.go b/cmd/generate.go new file mode 100644 index 0000000..2b07895 --- /dev/null +++ b/cmd/generate.go @@ -0,0 +1,46 @@ +// Copyright (c) 2024 Parseable, Inc +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package cmd + +// import ( +// "fmt" +// "log" +// "os" +// "sync" +// "time" + +// internalHTTP "pb/pkg/http" + +// "github.com/briandowns/spinner" + +// "pb/pkg/analyze/anthropic" +// "pb/pkg/analyze/duckdb" +// "pb/pkg/analyze/k8s" +// "pb/pkg/analyze/ollama" +// "pb/pkg/analyze/openai" + +// _ "github.com/marcboeker/go-duckdb" +// "github.com/spf13/cobra" +// ) + +// var GenerateCmd = &cobra.Command{ +// Use: "k8s", +// Short: "Generate k8s events on your k8s cluster by deploying apps in different states.", +// Example: "pb generate k8s events", +// Args: cobra.ExactArgs(1), +// RunE: func(cmd *cobra.Command, args []string) error { +// } +// } diff --git a/pkg/analyze/anthropic/anthropic.go b/pkg/analyze/anthropic/anthropic.go index a0ab516..8390189 100644 --- a/pkg/analyze/anthropic/anthropic.go +++ b/pkg/analyze/anthropic/anthropic.go @@ -54,15 +54,17 @@ func AnalyzeEventsWithAnthropic(podName, namespace string, data []duckdb.Summary I have a table containing those events and want to debug what is happening in this pod (%s) / namespace (%s). Give me a detailed summary of what happened by looking at these events. Provide a root cause analysis and suggest steps to mitigate the error if present. + Make sure summary is a string, root_cause_analysis is a string and mitigation_steps is []string. Please respect the data + In case where podName is empty or not provided analyse within the namespace, but strictly adher to the json struct mentioned. Do not send any response which is not compatible with json struct provided". When sending the response give it in a structured body json. With fields summary, root_cause_analysis and mitigation_steps. Don't add any json keywords in the response, make sure it just a clean json dump. Please adhere to the following structure type AnalysisResponse struct { - Summary string json:"summary" - RootCauseAnalysis string json:"root_cause_analysis" - MitigationSteps []string json:"mitigation_steps" + summary string json:"summary" + root_cause_analysis string json:"root_cause_analysis" + mitigation_steps []string json:"mitigation_steps" } - In mitigation steps give a command to get logs. - In case you are unable to figure out what happened, just say "I'm unable to figure out what is happening here.". + In mitigation steps give a command to get logs. The general command to get logs is 'kubectl logs -n . + Make sure you give a clean json response, without an '''json in the beginning. Please respect the json tags should be summary, root_cause_analysis and mitigation_steps. %s`, podName, namespace, formattedData) // Build the Anthropic request payload diff --git a/pkg/analyze/duckdb/duckdb.go b/pkg/analyze/duckdb/duckdb.go index 7045978..6aad666 100644 --- a/pkg/analyze/duckdb/duckdb.go +++ b/pkg/analyze/duckdb/duckdb.go @@ -205,3 +205,50 @@ func FetchPodEventsfromDb(podName string) ([]SummaryStat, error) { return stats, nil } + +// FetchNamespaceEventsfromDb fetches summary statistics for a given namespace from DuckDB. +func FetchNamespaceEventsfromDb(namespace string) ([]SummaryStat, error) { + // Open a connection to DuckDB + db, err := sql.Open("duckdb", "k8s_events.duckdb") + if err != nil { + return nil, fmt.Errorf("error connecting to DuckDB: %w", err) + } + defer db.Close() + + // Prepare the query with a placeholder for podName + query := ` + SELECT DISTINCT ON (message) * + FROM k8s_events + WHERE involvedObject_namespace = ? + ORDER BY "timestamp"; + ` + + // Execute the query with namespace as a parameter + rows, err := db.Query(query, namespace) + if err != nil { + return nil, fmt.Errorf("error executing summary query: %w", err) + } + defer rows.Close() + + var stats []SummaryStat + for rows.Next() { + var reason, message, objectName, objectNamespace, reportingComponent, timestamp string + if err := rows.Scan(&reason, &message, &objectName, &objectNamespace, &reportingComponent, ×tamp); err != nil { + return nil, fmt.Errorf("error scanning summary row: %w", err) + } + stats = append(stats, SummaryStat{ + Reason: reason, + Message: message, + ObjectName: objectName, + ObjectNamespace: objectNamespace, + ReportingComponent: reportingComponent, + Timestamp: timestamp, + }) + } + + if err := rows.Err(); err != nil { + return nil, fmt.Errorf("error reading rows: %w", err) + } + + return stats, nil +} diff --git a/pkg/analyze/ollama/ollama.go b/pkg/analyze/ollama/ollama.go index 9d7d20f..944b0bd 100644 --- a/pkg/analyze/ollama/ollama.go +++ b/pkg/analyze/ollama/ollama.go @@ -36,6 +36,8 @@ func AnalyzeEventsWithOllama(podName, namespace string, data []duckdb.SummarySta I have a table containing those events and want to debug what is happening in this pod (%s) / namespace (%s). Give me a detailed summary of what happened by looking at these events. Provide a root cause analysis and suggest steps to mitigate the error if present. + Make sure summary is a string, root_cause_analysis is a string and mitigation_steps is []string. Please respect the data + In case where podName is empty or not provided analyse within the namespace, but strictly adher to the json struct mentioned. Do not send any response which is not compatible with json struct provided". When sending the response give it in a structured body json. With fields summary, root_cause_analysis and mitigation_steps. Don't add any json keywords in the response, make sure it just a clean json dump. Please adhere to the following structure type AnalysisResponse struct { @@ -45,8 +47,6 @@ func AnalyzeEventsWithOllama(podName, namespace string, data []duckdb.SummarySta } In mitigation steps give a command to get logs. The general command to get logs is 'kubectl logs -n . Make sure you give a clean json response, without an '''json in the beginning. Please respect the json tags should be summary, root_cause_analysis and mitigation_steps. - Make sure summary is a string, root_cause_analysis is a string and mitigation_steps is []string. Please respect the datatypes. - In case you are unable to figure out what happened, just say "I'm unable to figure out what is happening here.". %s`, podName, namespace, formattedData) // Build the Ollama request payload diff --git a/pkg/analyze/openai/openai.go b/pkg/analyze/openai/openai.go index b211985..6440a5e 100644 --- a/pkg/analyze/openai/openai.go +++ b/pkg/analyze/openai/openai.go @@ -41,15 +41,17 @@ func AnalyzeEventsWithGPT(podName, namespace string, data []duckdb.SummaryStat) I have a table containing those events and want to debug what is happening in this pod (%s) / namespace (%s). Give me a detailed summary of what happened by looking at these events. Provide a root cause analysis and suggest steps to mitigate the error if present. + Make sure summary is a string, root_cause_analysis is a string and mitigation_steps is []string. Please respect the data + In case where podName is empty or not provided analyse within the namespace, but strictly adher to the json struct mentioned. Do not send any response which is not compatible with json struct provided". When sending the response give it in a structured body json. With fields summary, root_cause_analysis and mitigation_steps. Don't add any json keywords in the response, make sure it just a clean json dump. Please adhere to the following structure type AnalysisResponse struct { - Summary string json:"summary" - RootCauseAnalysis string json:"root_cause_analysis" - MitigationSteps []string json:"mitigation_steps" + summary string json:"summary" + root_cause_analysis string json:"root_cause_analysis" + mitigation_steps []string json:"mitigation_steps" } - In mitigation steps give a command to get logs. - In case you are unable to figure out what happened, just say "I'm unable to figure out what is happening here.". + In mitigation steps give a command to get logs. The general command to get logs is 'kubectl logs -n . + Make sure you give a clean json response, without an '''json in the beginning. Please respect the json tags should be summary, root_cause_analysis and mitigation_steps. %s`, podName, namespace, formattedData) // Build the OpenAI request payload