@@ -9,36 +9,60 @@ import (
9
9
)
10
10
11
11
var (
12
- probeDataGeneralLabels = []string {"job" , "script" , "task" , "probe" }
13
- probeDateItemGeneralLabels = []string {"job" , "script" , "task" , "probe" , "item" }
14
- taskGeneralLabels = []string {"job" , "script" , "task" }
12
+ LabelsScriptGeneral = []string {"job" , "script" }
13
+ LabelsTaskGeneral = []string {"job" , "script" , "task" }
14
+ LabelsProbeDataGeneral = []string {"job" , "script" , "task" , "probe" }
15
+ LabelsProbeDateItemGeneral = []string {"job" , "script" , "task" , "probe" , "item" }
15
16
)
16
17
17
18
const (
18
- probeDataHelpDescr = "probe execution data result"
19
- probeDataName = "boogieman_probe_data"
20
- probeDataItemName = "boogieman_probe_data_item"
21
- descriptorKeyProbeData = "probe_data"
22
- descriptorKeyProbeDataItem = "probe_data_item"
19
+ probeDataHelpDescr = "probe execution data result"
20
+ pNameData = "boogieman_probe_data"
21
+ pNameDataItem = "boogieman_probe_data_item"
22
+ pNameScriptResult = "boogieman_script_result"
23
+ pNameTaskResult = "boogieman_task_result"
24
+ pNameTaskRuntime = "boogieman_task_runtime"
25
+ pNameTaskRuns = "boogieman_task_runs"
23
26
)
24
27
25
- // prometheus metrics descriptors
26
- var pDescriptors = map [string ]* prometheus.Desc {
27
- "script_result" : prometheus .NewDesc ("boogieman_script_result" , "script execution result" , []string {"job" , "script" }, nil ),
28
- "task_result" : prometheus .NewDesc ("boogieman_task_result" , "task execution result" , taskGeneralLabels , nil ),
29
- "task_runtime" : prometheus .NewDesc ("boogieman_task_runtime" , "task runtime" , taskGeneralLabels , nil ),
30
- "task_runs" : prometheus .NewDesc ("boogieman_task_runs" , "task run counter" , taskGeneralLabels , nil ),
31
- descriptorKeyProbeData : prometheus .NewDesc (probeDataName , probeDataHelpDescr , probeDataGeneralLabels , nil ),
32
- descriptorKeyProbeDataItem : prometheus .NewDesc (probeDataItemName , probeDataHelpDescr , probeDateItemGeneralLabels , nil ),
28
+ // probe metrics struct
29
+ type metricData struct {
30
+ valueType prometheus.ValueType
31
+ value float64
32
+ labels []string
33
+ constLabels prometheus.Labels
33
34
}
34
35
35
- // probe metrics struct
36
- type probeDataMetric struct {
37
- valueType prometheus.ValueType
38
- value float64
39
- labels []string
36
+ type metricDescriptorInfo struct {
37
+ name string
38
+ help string
39
+ labels []string
40
+ }
41
+
42
+ var metricBaseDescriptors = map [string ]metricDescriptorInfo {
43
+ pNameScriptResult : {
44
+ pNameScriptResult , "script execution result" , LabelsScriptGeneral ,
45
+ },
46
+ pNameTaskResult : {
47
+ pNameTaskResult , "task execution result" , LabelsTaskGeneral ,
48
+ },
49
+ pNameTaskRuntime : {
50
+ pNameTaskRuntime , "task runtime" , LabelsTaskGeneral ,
51
+ },
52
+ pNameTaskRuns : {
53
+ pNameTaskRuns , "task run counter" , LabelsTaskGeneral ,
54
+ },
55
+ pNameData : {
56
+ pNameData , probeDataHelpDescr , LabelsProbeDataGeneral ,
57
+ },
58
+ pNameDataItem : {
59
+ pNameDataItem , probeDataHelpDescr , LabelsProbeDateItemGeneral ,
60
+ },
40
61
}
41
62
63
+ // prometheus metrics descriptors
64
+ var pDescriptors = map [string ]* prometheus.Desc {}
65
+
42
66
// Describe - implementation of prometheus.Collector interface
43
67
func (s * Scheduler ) Describe (chan <- * prometheus.Desc ) {
44
68
@@ -51,82 +75,65 @@ func (s *Scheduler) Collect(ch chan<- prometheus.Metric) {
51
75
defer s .Unlock ()
52
76
for _ , j := range s .jobs {
53
77
scriptResult := j .Script .ResultFinished ()
54
- ch <- prometheus .MustNewConstMetric (
55
- pDescriptors ["script_result" ],
56
- prometheus .GaugeValue , gbValue (scriptResult .Success ),
57
- j .Name , j .ScriptFile ,
78
+ s .sendMetric (ch , []string {pNameScriptResult },
79
+ metricData {prometheus .GaugeValue , gbValue (scriptResult .Success ), []string {j .Name , j .ScriptFile }, nil },
58
80
)
59
81
for _ , t := range scriptResult .Tasks {
60
82
// task general metrics
61
83
taskMetricLabelValues := []string {j .Name , j .ScriptFile , t .Name }
62
- ch <- prometheus .MustNewConstMetric (
63
- pDescriptors ["task_result" ],
64
- prometheus .GaugeValue , gbValue (t .Success ),
65
- taskMetricLabelValues ... ,
66
- )
67
- ch <- prometheus .MustNewConstMetric (
68
- pDescriptors ["task_runtime" ],
69
- prometheus .GaugeValue , float64 (t .RuntimeMs ),
70
- taskMetricLabelValues ... ,
71
- )
72
- ch <- prometheus .MustNewConstMetric (
73
- pDescriptors ["task_runs" ],
74
- prometheus .CounterValue , float64 (t .RunCounter ),
75
- taskMetricLabelValues ... ,
76
- )
77
- // task data metrics
78
- if t .Probe .Data != nil {
79
- // check if there are additional metric labels for this task
80
- var taskLabels model.MetricLabels
81
- for _ , task := range j .Script .Tasks {
82
- if task .Name == t .Name {
83
- taskLabels = task .MetricLabels
84
- break
85
- }
86
- }
87
- if ! taskLabels .IsEmpty () {
88
84
85
+ // check if there are additional metric labels for this task
86
+ var taskMetric model.TaskMetric
87
+ for _ , task := range j .Script .Tasks {
88
+ if task .Name == t .Name {
89
+ taskMetric = task .Metric
90
+ break
89
91
}
92
+ }
93
+ s .sendMetric (
94
+ ch , []string {pNameTaskResult },
95
+ metricData {prometheus .GaugeValue , gbValue (t .Success ), taskMetricLabelValues , taskMetric .Labels .Data ()})
96
+ s .sendMetric (
97
+ ch , []string {pNameTaskRuntime },
98
+ metricData {prometheus .GaugeValue , float64 (t .RuntimeMs ), taskMetricLabelValues , taskMetric .Labels .Data ()})
99
+ s .sendMetric (
100
+ ch , []string {pNameTaskRuns },
101
+ metricData {prometheus .CounterValue , float64 (t .RunCounter ), taskMetricLabelValues , taskMetric .Labels .Data ()})
102
+
103
+ // task data metrics
104
+ if t .Probe .Data != nil {
105
+ // add probe name to metric labels
90
106
dataMetricLabelValues := taskMetricLabelValues [:]
91
107
dataMetricLabelValues = append (dataMetricLabelValues , t .Probe .Name )
92
108
ms := probeMetrics (t .Probe .Data )
93
109
for _ , m := range ms {
94
110
var (
95
111
labelValues []string
96
- pDescriptorKey string
112
+ pDescriptorKey [] string
97
113
)
98
114
if len (m .labels ) == 0 {
99
115
labelValues = dataMetricLabelValues
100
- pDescriptorKey = descriptorKeyProbeData
116
+ pDescriptorKey = [] string { pNameData }
101
117
} else {
102
118
labelValues = dataMetricLabelValues [:]
103
- labelValues = append (labelValues , m .labels ... )
104
- pDescriptorKey = descriptorKeyProbeDataItem
105
- }
106
- // has dynamic labels
107
- if ! taskLabels .IsEmpty () {
108
- descriptorKey := strings .Join (taskMetricLabelValues , "|" )
109
- if _ , exists := pDescriptors [descriptorKey ]; ! exists {
110
- var (
111
- labels []string
112
- name string
113
- )
114
-
115
- switch pDescriptorKey {
116
- case descriptorKeyProbeData :
117
- labels = probeDataGeneralLabels
118
- name = probeDataName
119
- case descriptorKeyProbeDataItem :
120
- labels = probeDateItemGeneralLabels
121
- name = probeDataItemName
119
+ if len (taskMetric .ValueMap ) > 0 {
120
+ val , ok := taskMetric .ValueMap [m .labels [0 ]]
121
+ if ok {
122
+ m .labels [0 ] = val
122
123
}
123
-
124
- pDescriptors [descriptorKey ] =
125
- prometheus .NewDesc (name , probeDataHelpDescr , labels , taskLabels .Data ())
126
124
}
127
- pDescriptorKey = descriptorKey
125
+ labelValues = append (labelValues , m .labels ... )
126
+ pDescriptorKey = []string {pNameDataItem }
127
+ }
128
+ // if task has custom labels
129
+ if ! taskMetric .Labels .IsEmpty () {
130
+ pDescriptorKey = append (pDescriptorKey , taskMetricLabelValues ... )
128
131
}
129
- ch <- prometheus .MustNewConstMetric (pDescriptors [pDescriptorKey ], m .valueType , m .value , labelValues ... )
132
+ s .sendMetric (
133
+ ch , pDescriptorKey ,
134
+ metricData {
135
+ valueType : m .valueType , value : m .value , labels : labelValues , constLabels : taskMetric .Labels .Data (),
136
+ })
130
137
}
131
138
}
132
139
}
@@ -141,6 +148,50 @@ func gbValue(v bool) float64 {
141
148
return 0
142
149
}
143
150
151
+ func (s * Scheduler ) sendMetric (ch chan <- prometheus.Metric , descrCompositeKey []string , metricData metricData ) {
152
+
153
+ var (
154
+ descrKey string
155
+ pDescr * prometheus.Desc
156
+ ok bool
157
+ )
158
+
159
+ // metric descriptor key is a concatenation of base metric descriptor key and task labels
160
+ if len (descrCompositeKey ) == 1 && len (metricData .constLabels ) > 0 {
161
+ descrCompositeKey = append (descrCompositeKey , metricData .labels ... )
162
+ }
163
+
164
+ if len (descrCompositeKey ) == 1 {
165
+ descrKey = descrCompositeKey [0 ]
166
+ } else {
167
+ descrKey = strings .Join (descrCompositeKey , "|" )
168
+ }
169
+
170
+ // check if metric descriptor already exists
171
+ pDescr , ok = pDescriptors [descrKey ]
172
+ if ! ok { // metric descriptor not found, create it
173
+ descrInfo , ok := metricBaseDescriptors [descrKey ]
174
+ if ok {
175
+ pDescr = prometheus .NewDesc (descrKey , descrInfo .help , descrInfo .labels , metricData .constLabels )
176
+ pDescriptors [descrKey ] = pDescr
177
+ } else {
178
+ descrInfo , ok = metricBaseDescriptors [descrCompositeKey [0 ]]
179
+ if ! ok {
180
+ s .logger .Printf ("unknown base metric descriptor: %s" , descrCompositeKey [0 ])
181
+ return
182
+ }
183
+ pDescr =
184
+ prometheus .NewDesc (descrCompositeKey [0 ], descrInfo .help , descrInfo .labels , metricData .constLabels )
185
+ pDescriptors [descrKey ] = pDescr
186
+ }
187
+ }
188
+ ch <- prometheus .MustNewConstMetric (
189
+ pDescr ,
190
+ metricData .valueType , metricData .value ,
191
+ metricData .labels ... ,
192
+ )
193
+ }
194
+
144
195
func addToArray (arr []string , s string ) []string {
145
196
r := make ([]string , len (arr )+ 1 )
146
197
copy (r , arr )
@@ -160,7 +211,7 @@ func reflectIsFloat(kind reflect.Kind) bool {
160
211
// data can be a simple value or hash of names and values
161
212
//
162
213
//nolint:funlen
163
- func probeMetrics (data any ) (metrics []probeDataMetric ) {
214
+ func probeMetrics (data any ) (metrics []metricData ) {
164
215
var (
165
216
valueType = prometheus .GaugeValue
166
217
labels []string
@@ -203,7 +254,7 @@ func probeMetrics(data any) (metrics []probeDataMetric) {
203
254
continue
204
255
}
205
256
206
- metrics = append (metrics , probeDataMetric {
257
+ metrics = append (metrics , metricData {
207
258
valueType : valueType ,
208
259
value : value ,
209
260
labels : labels ,
@@ -225,7 +276,7 @@ func probeMetrics(data any) (metrics []probeDataMetric) {
225
276
labels = []string {v .String ()}
226
277
}
227
278
228
- return []probeDataMetric {
279
+ return []metricData {
229
280
{
230
281
valueType : valueType ,
231
282
value : value ,
0 commit comments