mirror of
https://github.com/k8sgpt-ai/k8sgpt.git
synced 2025-08-16 23:06:38 +00:00
* feat: initial Prometheus analyzers Added a prometheus integration with two analyzers: 1. PrometheusConfigValidate 2. PrometheusConfigRelabelReport The integration does not deploy any Prometheus stack in the cluster. Instead, it searches the provided --namespace for a Prometheus configuration, stored in a ConfigMap or Secret. If it finds one, it unmarshals it into memory and runs the analyzers on it. PrometheusConfigValidate checks if the actual Prometheus configuration is valid or has any errors. PrometheusConfigRelabelReport tries to distill the scrape config relabeling rules to give a concise label set per job that targets need to have to be scraped. This analyzer is unconventional, in that it does not necessarily mean there are issues with the config. It merely tries to give a human-readable explanation of the relabel rules it discovers, leaning on the LLM and prompt. Tested on both kube-prometheus and Google Managed Prometheus stacks. Signed-off-by: Daniel Clark <danielclark@google.com> * review: feedback cycle 1 Simplify ConfigValidate prompt and add comments. Signed-off-by: Daniel Clark <danielclark@google.com> * review: feedback cycle 2 Add Prometheus configuration discovery to integration activate command. Also improve logging to make this more clear to users. Signed-off-by: Daniel Clark <danielclark@google.com> --------- Signed-off-by: Daniel Clark <danielclark@google.com>
86 lines
2.1 KiB
Go
86 lines
2.1 KiB
Go
package prometheus
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
|
|
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
|
|
discoverykube "github.com/prometheus/prometheus/discovery/kubernetes"
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
type RelabelAnalyzer struct {
|
|
}
|
|
|
|
func (r *RelabelAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
|
|
ctx := a.Context
|
|
client := a.Client.GetClient()
|
|
namespace := a.Namespace
|
|
kind := ConfigRelabel
|
|
|
|
podConfigs, err := findPrometheusPodConfigs(ctx, client, namespace)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var preAnalysis = map[string]common.PreAnalysis{}
|
|
for _, pc := range podConfigs {
|
|
var failures []common.Failure
|
|
pod := pc.pod
|
|
|
|
// Check upstream validation.
|
|
// The Prometheus configuration structs do not generally have validation
|
|
// methods and embed their validation logic in the UnmarshalYAML methods.
|
|
config, _ := unmarshalPromConfigBytes(pc.b)
|
|
// Limit output for brevity.
|
|
limit := 6
|
|
i := 0
|
|
for _, sc := range config.ScrapeConfigs {
|
|
if i == limit {
|
|
break
|
|
}
|
|
if sc == nil {
|
|
continue
|
|
}
|
|
brc, _ := yaml.Marshal(sc.RelabelConfigs)
|
|
var bsd []byte
|
|
for _, cfg := range sc.ServiceDiscoveryConfigs {
|
|
ks, ok := cfg.(*discoverykube.SDConfig)
|
|
if !ok {
|
|
continue
|
|
}
|
|
bsd, _ = yaml.Marshal(ks)
|
|
}
|
|
// Don't bother with relabel analysis if the scrape config
|
|
// or service discovery config are empty.
|
|
if len(brc) == 0 || len(bsd) == 0 {
|
|
continue
|
|
}
|
|
failures = append(failures, common.Failure{
|
|
Text: fmt.Sprintf("job_name:\n%s\nrelabel_configs:\n%s\nkubernetes_sd_configs:\n%s\n", sc.JobName, string(brc), string(bsd)),
|
|
})
|
|
i++
|
|
}
|
|
|
|
if len(failures) > 0 {
|
|
preAnalysis[fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)] = common.PreAnalysis{
|
|
Pod: *pod,
|
|
FailureDetails: failures,
|
|
}
|
|
}
|
|
}
|
|
|
|
for key, value := range preAnalysis {
|
|
var currentAnalysis = common.Result{
|
|
Kind: kind,
|
|
Name: key,
|
|
Error: value.FailureDetails,
|
|
}
|
|
parent, _ := util.GetParent(a.Client, value.Pod.ObjectMeta)
|
|
currentAnalysis.ParentObject = parent
|
|
a.Results = append(a.Results, currentAnalysis)
|
|
}
|
|
|
|
return a.Results, nil
|
|
}
|