1
2
3
4
5
6
7
8
9
10
11
12
13
14 package metrics
15
16 import (
17 "context"
18
19 "github.com/prometheus/client_golang/prometheus"
20 ctrl "sigs.k8s.io/controller-runtime"
21 "sigs.k8s.io/controller-runtime/pkg/cache"
22
23 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
24 )
25
26 var log = ctrl.Log.WithName("metrics-collector")
27
28
29 type ChaosCollector struct {
30 store cache.Cache
31 experimentStatus *prometheus.GaugeVec
32 SidecarTemplates prometheus.Gauge
33 ConfigTemplates *prometheus.GaugeVec
34 InjectionConfigs *prometheus.GaugeVec
35 TemplateNotExist *prometheus.CounterVec
36 TemplateLoadError prometheus.Counter
37 ConfigNameDuplicate *prometheus.CounterVec
38 InjectRequired *prometheus.CounterVec
39 Injections *prometheus.CounterVec
40 }
41
42
43 func NewChaosCollector(store cache.Cache, registerer prometheus.Registerer) *ChaosCollector {
44 c := &ChaosCollector{
45 store: store,
46 experimentStatus: prometheus.NewGaugeVec(prometheus.GaugeOpts{
47 Name: "chaos_mesh_experiments",
48 Help: "Total number of chaos experiments and their phases",
49 }, []string{"namespace", "kind", "phase"}),
50 SidecarTemplates: prometheus.NewGauge(prometheus.GaugeOpts{
51 Name: "chaos_mesh_templates",
52 Help: "Total number of injection templates",
53 }),
54 ConfigTemplates: prometheus.NewGaugeVec(prometheus.GaugeOpts{
55 Name: "chaos_mesh_config_templates",
56 Help: "Total number of config templates",
57 }, []string{"namespace", "template"}),
58 InjectionConfigs: prometheus.NewGaugeVec(prometheus.GaugeOpts{
59 Name: "chaos_mesh_injection_configs",
60 Help: "Total number of injection configs",
61 }, []string{"namespace", "template"}),
62 TemplateNotExist: prometheus.NewCounterVec(prometheus.CounterOpts{
63 Name: "chaos_mesh_template_not_exist_total",
64 Help: "Total number of template not exist error",
65 }, []string{"namespace", "template"}),
66 ConfigNameDuplicate: prometheus.NewCounterVec(prometheus.CounterOpts{
67 Name: "chaos_mesh_config_name_duplicate_total",
68 Help: "Total number of config name duplication error",
69 }, []string{"namespace", "config"}),
70 TemplateLoadError: prometheus.NewCounter(prometheus.CounterOpts{
71 Name: "chaos_mesh_template_load_failed_total",
72 Help: "Total number of failures when rendering config args to template",
73 }),
74 InjectRequired: prometheus.NewCounterVec(prometheus.CounterOpts{
75 Name: "chaos_mesh_inject_required_total",
76 Help: "Total number of injections required",
77 }, []string{"namespace", "config"}),
78 Injections: prometheus.NewCounterVec(prometheus.CounterOpts{
79 Name: "chaos_mesh_injections_total",
80 Help: "Total number of sidecar injections performed on the webhook",
81 }, []string{"namespace", "config"}),
82 }
83 registerer.MustRegister(c)
84 return c
85 }
86
87
88 func (c *ChaosCollector) Describe(ch chan<- *prometheus.Desc) {
89 c.experimentStatus.Describe(ch)
90 c.SidecarTemplates.Describe(ch)
91 c.ConfigTemplates.Describe(ch)
92 c.InjectionConfigs.Describe(ch)
93 c.TemplateNotExist.Describe(ch)
94 c.ConfigNameDuplicate.Describe(ch)
95 c.TemplateLoadError.Describe(ch)
96 c.InjectRequired.Describe(ch)
97 c.Injections.Describe(ch)
98 }
99
100
101 func (c *ChaosCollector) Collect(ch chan<- prometheus.Metric) {
102 c.collect()
103 c.SidecarTemplates.Collect(ch)
104 c.ConfigTemplates.Collect(ch)
105 c.InjectionConfigs.Collect(ch)
106 c.TemplateNotExist.Collect(ch)
107 c.ConfigNameDuplicate.Collect(ch)
108 c.TemplateLoadError.Collect(ch)
109 c.InjectRequired.Collect(ch)
110 c.Injections.Collect(ch)
111 c.experimentStatus.Collect(ch)
112 }
113
114 func (c *ChaosCollector) collect() {
115
116
117 c.experimentStatus.Reset()
118
119 for kind, obj := range v1alpha1.AllKinds() {
120 expCache := map[string]map[string]int{}
121 if err := c.store.List(context.TODO(), obj.ChaosList); err != nil {
122 log.Error(err, "failed to list chaos", "kind", kind)
123 return
124 }
125 for _, chaos := range obj.ListChaos() {
126 if _, ok := expCache[chaos.Namespace]; !ok {
127
128 expCache[chaos.Namespace] = make(map[string]int, 4)
129 }
130 expCache[chaos.Namespace][chaos.Status]++
131 }
132
133 for ns, v := range expCache {
134 for phase, count := range v {
135 c.experimentStatus.WithLabelValues(ns, kind, phase).Set(float64(count))
136 }
137 }
138 }
139 }
140