Skip to content

Commit

Permalink
feat: add server metrics (#273)
Browse files Browse the repository at this point in the history
* feat: expose metrics path & init analyzer errors metrics

This commit add metrics path & the analyzer error metrics in the codebase. The changes have been made across all analyzers and include the addition of a new metric with label values for the analyzer's name, analyzed object's name, and namespace. The metric's value is set to the length of the analyzer objects failures.

Signed-off-by: Matthis Holleville <matthish29@gmail.com>

* feat: add metric to cronjob & deployment & netpol

Signed-off-by: Matthis Holleville <matthish29@gmail.com>

* feat: expose metric to NodeAnalyzer

Signed-off-by: Matthis Holleville <matthish29@gmail.com>

---------

Signed-off-by: Matthis Holleville <matthish29@gmail.com>
  • Loading branch information
matthisholleville committed Apr 15, 2023
1 parent 03a95e7 commit a3becc9
Show file tree
Hide file tree
Showing 15 changed files with 122 additions and 17 deletions.
9 changes: 9 additions & 0 deletions pkg/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ import (
"github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
"github.com/k8sgpt-ai/k8sgpt/pkg/integration"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

var (
AnalyzerErrorsMetric = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "analyzer_errors",
Help: "Number of errors detected by analyzer",
}, []string{"analyzer_name", "object_name", "namespace"})
)

var coreAnalyzerMap = map[string]common.IAnalyzer{
Expand Down
13 changes: 11 additions & 2 deletions pkg/analyzer/cronjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ import (
type CronJobAnalyzer struct{}

func (analyzer CronJobAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {

kind := "CronJob"

AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})

var results []common.Result

cronJobList, err := a.Client.GetClient().BatchV1().CronJobs("").List(a.Context, v1.ListOptions{})
Expand Down Expand Up @@ -81,14 +88,16 @@ func (analyzer CronJobAnalyzer) Analyze(a common.Analyzer) ([]common.Result, err
}

if len(failures) > 0 {
preAnalysis[cronJob.Name] = common.PreAnalysis{
preAnalysis[fmt.Sprintf("%s/%s", cronJob.Namespace, cronJob.Name)] = common.PreAnalysis{
FailureDetails: failures,
}
AnalyzerErrorsMetric.WithLabelValues(kind, cronJob.Name, cronJob.Namespace).Set(float64(len(failures)))

}

for key, value := range preAnalysis {
currentAnalysis := common.Result{
Kind: "CronJob",
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/analyzer/cronjob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,6 @@ func TestCronJobBroken(t *testing.T) {
}

assert.Equal(t, len(analysisResults), 1)
assert.Equal(t, analysisResults[0].Name, "example-cronjob")
assert.Equal(t, analysisResults[0].Name, "default/example-cronjob")
assert.Equal(t, analysisResults[0].Kind, "CronJob")
}
9 changes: 8 additions & 1 deletion pkg/analyzer/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ type DeploymentAnalyzer struct {
// Analyze scans all namespaces for Deployments with misconfigurations
func (d DeploymentAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {

kind := "Deployment"

AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})

deployments, err := a.Client.GetClient().AppsV1().Deployments("").List(context.Background(), v1.ListOptions{})
if err != nil {
return nil, err
Expand Down Expand Up @@ -44,13 +50,14 @@ func (d DeploymentAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error)
FailureDetails: failures,
Deployment: deployment,
}
AnalyzerErrorsMetric.WithLabelValues(kind, deployment.Name, deployment.Namespace).Set(float64(len(failures)))
}

}

for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: "Deployment",
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
Expand Down
9 changes: 8 additions & 1 deletion pkg/analyzer/hpa.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ type HpaAnalyzer struct{}

func (HpaAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {

kind := "HorizontalPodAutoscaler"

AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})

list, err := a.Client.GetClient().AutoscalingV1().HorizontalPodAutoscalers(a.Namespace).List(a.Context, metav1.ListOptions{})
if err != nil {
return nil, err
Expand Down Expand Up @@ -71,13 +77,14 @@ func (HpaAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
HorizontalPodAutoscalers: hpa,
FailureDetails: failures,
}
AnalyzerErrorsMetric.WithLabelValues(kind, hpa.Name, hpa.Namespace).Set(float64(len(failures)))
}

}

for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: "HorizontalPodAutoscaler",
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
Expand Down
10 changes: 9 additions & 1 deletion pkg/analyzer/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ type IngressAnalyzer struct{}

func (IngressAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {

kind := "Ingress"

AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})

list, err := a.Client.GetClient().NetworkingV1().Ingresses(a.Namespace).List(a.Context, metav1.ListOptions{})
if err != nil {
return nil, err
Expand Down Expand Up @@ -107,13 +113,15 @@ func (IngressAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
Ingress: ing,
FailureDetails: failures,
}
AnalyzerErrorsMetric.WithLabelValues(kind, ing.Name, ing.Namespace).Set(float64(len(failures)))

}

}

for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: "Ingress",
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
Expand Down
13 changes: 11 additions & 2 deletions pkg/analyzer/netpol.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ import (
type NetworkPolicyAnalyzer struct{}

func (NetworkPolicyAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {

kind := "NetworkPolicy"

AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})

// get all network policies in the namespace
policies, err := a.Client.GetClient().NetworkingV1().
NetworkPolicies(a.Namespace).List(a.Context, metav1.ListOptions{})
Expand Down Expand Up @@ -54,16 +61,18 @@ func (NetworkPolicyAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error)
}

if len(failures) > 0 {
preAnalysis[policy.Name] = common.PreAnalysis{
preAnalysis[fmt.Sprintf("%s/%s", policy.Namespace, policy.Name)] = common.PreAnalysis{
FailureDetails: failures,
NetworkPolicy: policy,
}
AnalyzerErrorsMetric.WithLabelValues(kind, policy.Name, policy.Namespace).Set(float64(len(failures)))

}
}

for key, value := range preAnalysis {
currentAnalysis := common.Result{
Kind: "NetworkPolicy",
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
Expand Down
11 changes: 10 additions & 1 deletion pkg/analyzer/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package analyzer

import (
"fmt"

v1 "k8s.io/api/core/v1"

"github.com/k8sgpt-ai/k8sgpt/pkg/common"
Expand All @@ -13,6 +14,12 @@ type NodeAnalyzer struct{}

func (NodeAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {

kind := "Node"

AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})

list, err := a.Client.GetClient().CoreV1().Nodes().List(a.Context, metav1.ListOptions{})
if err != nil {
return nil, err
Expand Down Expand Up @@ -42,12 +49,14 @@ func (NodeAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
Node: node,
FailureDetails: failures,
}
AnalyzerErrorsMetric.WithLabelValues(kind, node.Name, "").Set(float64(len(failures)))

}
}

for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: "Node",
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
Expand Down
9 changes: 8 additions & 1 deletion pkg/analyzer/pdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ type PdbAnalyzer struct{}

func (PdbAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {

kind := "PodDisruptionBudget"

AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})

list, err := a.Client.GetClient().PolicyV1().PodDisruptionBudgets(a.Namespace).List(a.Context, metav1.ListOptions{})
if err != nil {
return nil, err
Expand Down Expand Up @@ -63,12 +69,13 @@ func (PdbAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
PodDisruptionBudget: pdb,
FailureDetails: failures,
}
AnalyzerErrorsMetric.WithLabelValues(kind, pdb.Name, pdb.Namespace).Set(float64(len(failures)))
}
}

for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: "PodDisruptionBudget",
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
Expand Down
10 changes: 9 additions & 1 deletion pkg/analyzer/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ type PodAnalyzer struct {
}

func (PodAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {

kind := "Pod"

AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})

// search all namespaces for pods that are not running
list, err := a.Client.GetClient().CoreV1().Pods(a.Namespace).List(a.Context, metav1.ListOptions{})
if err != nil {
Expand Down Expand Up @@ -70,12 +77,13 @@ func (PodAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
Pod: pod,
FailureDetails: failures,
}
AnalyzerErrorsMetric.WithLabelValues(kind, pod.Name, pod.Namespace).Set(float64(len(failures)))
}
}

for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: "Pod",
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
Expand Down
9 changes: 8 additions & 1 deletion pkg/analyzer/pvc.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ type PvcAnalyzer struct{}

func (PvcAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {

kind := "PersistentVolumeClaim"

AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})

// search all namespaces for pods that are not running
list, err := a.Client.GetClient().CoreV1().PersistentVolumeClaims(a.Namespace).List(a.Context, metav1.ListOptions{})
if err != nil {
Expand Down Expand Up @@ -43,12 +49,13 @@ func (PvcAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
PersistentVolumeClaim: pvc,
FailureDetails: failures,
}
AnalyzerErrorsMetric.WithLabelValues(kind, pvc.Name, pvc.Namespace).Set(float64(len(failures)))
}
}

for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: "PersistentVolumeClaim",
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
Expand Down
9 changes: 8 additions & 1 deletion pkg/analyzer/rs.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ type ReplicaSetAnalyzer struct{}

func (ReplicaSetAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {

kind := "ReplicaSet"

AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})

// search all namespaces for pods that are not running
list, err := a.Client.GetClient().AppsV1().ReplicaSets(a.Namespace).List(a.Context, metav1.ListOptions{})
if err != nil {
Expand Down Expand Up @@ -42,12 +48,13 @@ func (ReplicaSetAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
ReplicaSet: rs,
FailureDetails: failures,
}
AnalyzerErrorsMetric.WithLabelValues(kind, rs.Name, rs.Namespace).Set(float64(len(failures)))
}
}

for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: "ReplicaSet",
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
Expand Down
9 changes: 8 additions & 1 deletion pkg/analyzer/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ type ServiceAnalyzer struct{}

func (ServiceAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {

kind := "Service"

AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})

// search all namespaces for pods that are not running
list, err := a.Client.GetClient().CoreV1().Endpoints(a.Namespace).List(a.Context, metav1.ListOptions{})
if err != nil {
Expand Down Expand Up @@ -71,12 +77,13 @@ func (ServiceAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
Endpoint: ep,
FailureDetails: failures,
}
AnalyzerErrorsMetric.WithLabelValues(kind, ep.Name, ep.Namespace).Set(float64(len(failures)))
}
}

for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: "Service",
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
Expand Down
10 changes: 9 additions & 1 deletion pkg/analyzer/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ import (
type StatefulSetAnalyzer struct{}

func (StatefulSetAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {

kind := "StatefulSet"

AnalyzerErrorsMetric.DeletePartialMatch(map[string]string{
"analyzer_name": kind,
})

list, err := a.Client.GetClient().AppsV1().StatefulSets(a.Namespace).List(a.Context, metav1.ListOptions{})
if err != nil {
return nil, err
Expand Down Expand Up @@ -61,12 +68,13 @@ func (StatefulSetAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
StatefulSet: sts,
FailureDetails: failures,
}
AnalyzerErrorsMetric.WithLabelValues(kind, sts.Name, sts.Namespace).Set(float64(len(failures)))
}
}

for key, value := range preAnalysis {
var currentAnalysis = common.Result{
Kind: "StatefulSet",
Kind: kind,
Name: key,
Error: value.FailureDetails,
}
Expand Down
Loading

0 comments on commit a3becc9

Please sign in to comment.