1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package metrics
17
18 import (
19 "context"
20
21 "github.com/go-logr/logr"
22 "github.com/prometheus/client_golang/prometheus"
23 "go.uber.org/fx"
24
25 "github.com/chaos-mesh/chaos-mesh/pkg/dashboard/core"
26 )
27
28 const chaosDashboardSubsystem = "chaos_dashboard"
29
30
31 type Collector struct {
32 log logr.Logger
33 experimentStore core.ExperimentStore
34 scheduleStore core.ScheduleStore
35 workflowStore core.WorkflowStore
36
37 archivedExperiments *prometheus.GaugeVec
38 archivedSchedules *prometheus.GaugeVec
39 archivedWorkflows *prometheus.GaugeVec
40 }
41
42
43 func NewCollector(log logr.Logger, experimentStore core.ExperimentStore, scheduleStore core.ScheduleStore, workflowStore core.WorkflowStore) *Collector {
44 return &Collector{
45 log: log,
46 experimentStore: experimentStore,
47 scheduleStore: scheduleStore,
48 workflowStore: workflowStore,
49 archivedExperiments: prometheus.NewGaugeVec(prometheus.GaugeOpts{
50 Subsystem: chaosDashboardSubsystem,
51 Name: "archived_experiments",
52 Help: "Total number of archived chaos experiments",
53 }, []string{"namespace", "type"}),
54 archivedSchedules: prometheus.NewGaugeVec(prometheus.GaugeOpts{
55 Subsystem: chaosDashboardSubsystem,
56 Name: "archived_schedules",
57 Help: "Total number of archived chaos schedules",
58 }, []string{"namespace"}),
59 archivedWorkflows: prometheus.NewGaugeVec(prometheus.GaugeOpts{
60 Subsystem: chaosDashboardSubsystem,
61 Name: "archived_workflows",
62 Help: "Total number of archived chaos workflows",
63 }, []string{"namespace"}),
64 }
65 }
66
67
68 func (collector *Collector) Describe(ch chan<- *prometheus.Desc) {
69 collector.archivedExperiments.Describe(ch)
70 collector.archivedSchedules.Describe(ch)
71 collector.archivedWorkflows.Describe(ch)
72 }
73
74
75 func (collector *Collector) Collect(ch chan<- prometheus.Metric) {
76 collector.collectArchivedExperiments()
77 collector.collectArchivedSchedules()
78 collector.collectArchivedWorkflows()
79 collector.archivedExperiments.Collect(ch)
80 collector.archivedSchedules.Collect(ch)
81 collector.archivedWorkflows.Collect(ch)
82 }
83
84 func (collector *Collector) collectArchivedExperiments() {
85 collector.archivedExperiments.Reset()
86
87 metas, err := collector.experimentStore.ListMeta(context.TODO(), "", "", "", true)
88 if err != nil {
89 collector.log.Error(err, "fail to list all archived chaos experiments")
90 return
91 }
92
93 countByNamespaceAndKind := map[string]map[string]int{}
94 for _, meta := range metas {
95 if _, ok := countByNamespaceAndKind[meta.Namespace]; !ok {
96 countByNamespaceAndKind[meta.Namespace] = map[string]int{}
97 }
98
99 countByNamespaceAndKind[meta.Namespace][meta.Kind]++
100 }
101
102 for namespace, countByKind := range countByNamespaceAndKind {
103 for kind, count := range countByKind {
104 collector.archivedExperiments.WithLabelValues(namespace, kind).Set(float64(count))
105 }
106 }
107 }
108
109 func (collector *Collector) collectArchivedSchedules() {
110 collector.archivedSchedules.Reset()
111
112 metas, err := collector.scheduleStore.ListMeta(context.TODO(), "", "", true)
113 if err != nil {
114 collector.log.Error(err, "fail to list all archived schedules")
115 return
116 }
117
118 countByNamespace := map[string]int{}
119 for _, meta := range metas {
120 countByNamespace[meta.Namespace]++
121 }
122
123 for namespace, count := range countByNamespace {
124 collector.archivedSchedules.WithLabelValues(namespace).Set(float64(count))
125 }
126 }
127
128 func (collector *Collector) collectArchivedWorkflows() {
129 collector.archivedWorkflows.Reset()
130
131 metas, err := collector.workflowStore.ListMeta(context.TODO(), "", "", true)
132 if err != nil {
133 collector.log.Error(err, "fail to list all archived workflows")
134 return
135 }
136
137 countByNamespace := map[string]int{}
138 for _, meta := range metas {
139 countByNamespace[meta.Namespace]++
140 }
141
142 for namespace, count := range countByNamespace {
143 collector.archivedWorkflows.WithLabelValues(namespace).Set(float64(count))
144 }
145 }
146
147 type Params struct {
148 fx.In
149 Log logr.Logger
150 Registry *prometheus.Registry
151 ExperimentStore core.ExperimentStore
152 ScheduleStore core.ScheduleStore
153 WorkflowStore core.WorkflowStore
154 }
155
156 func Register(params Params) {
157 collector := NewCollector(params.Log, params.ExperimentStore, params.ScheduleStore, params.WorkflowStore)
158 params.Registry.MustRegister(collector)
159 }
160