github.com/kubeshop/testkube@v1.17.23/internal/app/api/metrics/metrics.go (about) 1 package metrics 2 3 import ( 4 "fmt" 5 "slices" 6 "strings" 7 8 "github.com/prometheus/client_golang/prometheus" 9 "github.com/prometheus/client_golang/prometheus/promauto" 10 11 "github.com/kubeshop/testkube/pkg/api/v1/testkube" 12 ) 13 14 var testExecutionsCount = promauto.NewCounterVec(prometheus.CounterOpts{ 15 Name: "testkube_test_executions_count", 16 Help: "The total number of test executions", 17 }, []string{"type", "name", "result", "labels", "test_uri"}) 18 19 var testExecutionsDurationMs = promauto.NewSummaryVec(prometheus.SummaryOpts{ 20 Name: "testkube_test_executions_duration_ms", 21 Help: "The duration of test executions", 22 Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.95: 0.005, 0.99: 0.001}, 23 }, []string{"type", "name", "result", "labels", "test_uri"}) 24 25 var testSuiteExecutionsCount = promauto.NewCounterVec(prometheus.CounterOpts{ 26 Name: "testkube_testsuite_executions_count", 27 Help: "The total number of test suite executions", 28 }, []string{"name", "result", "labels", "testsuite_uri"}) 29 30 var testSuiteExecutionsDurationMs = promauto.NewSummaryVec(prometheus.SummaryOpts{ 31 Name: "testkube_testsuite_executions_duration_ms", 32 Help: "The duration of test suite executions", 33 Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.95: 0.005, 0.99: 0.001}, 34 }, []string{"name", "result", "labels", "testsuite_uri"}) 35 36 var testCreationCount = promauto.NewCounterVec(prometheus.CounterOpts{ 37 Name: "testkube_test_creations_count", 38 Help: "The total number of tests created by type events", 39 }, []string{"type", "result"}) 40 41 var testSuiteCreationCount = promauto.NewCounterVec(prometheus.CounterOpts{ 42 Name: "testkube_testsuite_creations_count", 43 Help: "The total number of test suites created events", 44 }, []string{"result"}) 45 46 var testUpdatesCount = promauto.NewCounterVec(prometheus.CounterOpts{ 47 Name: "testkube_test_updates_count", 48 Help: "The total number of tests updated by type events", 49 }, []string{"type", "result"}) 50 51 var testSuiteUpdatesCount = promauto.NewCounterVec(prometheus.CounterOpts{ 52 Name: "testkube_testsuite_updates_count", 53 Help: "The total number of test suites updated events", 54 }, []string{"result"}) 55 56 var testTriggerCreationCount = promauto.NewCounterVec(prometheus.CounterOpts{ 57 Name: "testkube_testtrigger_creations_count", 58 Help: "The total number of test trigger created events", 59 }, []string{"result"}) 60 61 var testTriggerUpdatesCount = promauto.NewCounterVec(prometheus.CounterOpts{ 62 Name: "testkube_testtriggers_updates_count", 63 Help: "The total number of test trigger updated events", 64 }, []string{"result"}) 65 66 var testTriggerDeletesCount = promauto.NewCounterVec(prometheus.CounterOpts{ 67 Name: "testkube_testtriggers_deletes_count", 68 Help: "The total number of test trigger deleted events", 69 }, []string{"result"}) 70 71 var testTriggerBulkUpdatesCount = promauto.NewCounterVec(prometheus.CounterOpts{ 72 Name: "testkube_testtriggers_bulk_updates_count", 73 Help: "The total number of test trigger bulk update events", 74 }, []string{"result"}) 75 76 var testTriggerBulkDeletesCount = promauto.NewCounterVec(prometheus.CounterOpts{ 77 Name: "testkube_testtriggers_bulk_deletes_count", 78 Help: "The total number of test trigger bulk delete events", 79 }, []string{"result"}) 80 81 var testAbortCount = promauto.NewCounterVec(prometheus.CounterOpts{ 82 Name: "testkube_test_aborts_count", 83 Help: "The total number of tests aborted by type events", 84 }, []string{"type", "result"}) 85 86 var testWorkflowCreationCount = promauto.NewCounterVec(prometheus.CounterOpts{ 87 Name: "testkube_testworkflow_creations_count", 88 Help: "The total number of test workflow created by type events", 89 }, []string{"result"}) 90 91 var testWorkflowUpdatesCount = promauto.NewCounterVec(prometheus.CounterOpts{ 92 Name: "testkube_testworkflow_updates_count", 93 Help: "The total number of test workflow updated by type events", 94 }, []string{"result"}) 95 96 var testWorkflowDeletesCount = promauto.NewCounterVec(prometheus.CounterOpts{ 97 Name: "testkube_testworkflow_deletes_count", 98 Help: "The total number of test workflow deleted events", 99 }, []string{"result"}) 100 101 var testWorkflowTemplateCreationCount = promauto.NewCounterVec(prometheus.CounterOpts{ 102 Name: "testkube_testworkflowtemplate_creations_count", 103 Help: "The total number of test workflow template created by type events", 104 }, []string{"result"}) 105 106 var testWorkflowTemplateUpdatesCount = promauto.NewCounterVec(prometheus.CounterOpts{ 107 Name: "testkube_testworkflowtemplate_updates_count", 108 Help: "The total number of test workflow template updated by type events", 109 }, []string{"result"}) 110 111 var testWorkflowTemplateDeletesCount = promauto.NewCounterVec(prometheus.CounterOpts{ 112 Name: "testkube_testworkflowtemplate_deletes_count", 113 Help: "The total number of test workflow template deleted events", 114 }, []string{"result"}) 115 116 func NewMetrics() Metrics { 117 return Metrics{ 118 TestExecutionsCount: testExecutionsCount, 119 TestExecutionsDurationMs: testExecutionsDurationMs, 120 TestSuiteExecutionsCount: testSuiteExecutionsCount, 121 TestSuiteExecutionsDurationMs: testSuiteExecutionsDurationMs, 122 TestCreations: testCreationCount, 123 TestSuiteCreations: testSuiteCreationCount, 124 TestUpdates: testUpdatesCount, 125 TestSuiteUpdates: testSuiteUpdatesCount, 126 TestTriggerCreations: testTriggerCreationCount, 127 TestTriggerUpdates: testTriggerUpdatesCount, 128 TestTriggerDeletes: testTriggerDeletesCount, 129 TestTriggerBulkUpdates: testTriggerBulkUpdatesCount, 130 TestTriggerBulkDeletes: testTriggerBulkDeletesCount, 131 TestAbort: testAbortCount, 132 TestWorkflowCreations: testWorkflowCreationCount, 133 TestWorkflowUpdates: testWorkflowUpdatesCount, 134 TestWorkflowDeletes: testWorkflowDeletesCount, 135 TestWorkflowTemplateCreations: testWorkflowTemplateCreationCount, 136 TestWorkflowTemplateUpdates: testWorkflowTemplateUpdatesCount, 137 TestWorkflowTemplateDeletes: testWorkflowTemplateDeletesCount, 138 } 139 } 140 141 type Metrics struct { 142 TestExecutionsCount *prometheus.CounterVec 143 TestExecutionsDurationMs *prometheus.SummaryVec 144 TestSuiteExecutionsCount *prometheus.CounterVec 145 TestSuiteExecutionsDurationMs *prometheus.SummaryVec 146 TestCreations *prometheus.CounterVec 147 TestSuiteCreations *prometheus.CounterVec 148 TestUpdates *prometheus.CounterVec 149 TestSuiteUpdates *prometheus.CounterVec 150 TestTriggerCreations *prometheus.CounterVec 151 TestTriggerUpdates *prometheus.CounterVec 152 TestTriggerDeletes *prometheus.CounterVec 153 TestTriggerBulkUpdates *prometheus.CounterVec 154 TestTriggerBulkDeletes *prometheus.CounterVec 155 TestAbort *prometheus.CounterVec 156 TestWorkflowCreations *prometheus.CounterVec 157 TestWorkflowUpdates *prometheus.CounterVec 158 TestWorkflowDeletes *prometheus.CounterVec 159 TestWorkflowTemplateCreations *prometheus.CounterVec 160 TestWorkflowTemplateUpdates *prometheus.CounterVec 161 TestWorkflowTemplateDeletes *prometheus.CounterVec 162 } 163 164 func (m Metrics) IncAndObserveExecuteTest(execution testkube.Execution, dashboardURI string) { 165 status := "" 166 if execution.ExecutionResult != nil && execution.ExecutionResult.Status != nil { 167 status = string(*execution.ExecutionResult.Status) 168 } 169 170 var labels []string 171 for key, value := range execution.Labels { 172 labels = append(labels, fmt.Sprintf("%s=%s", key, value)) 173 } 174 175 slices.Sort(labels) 176 m.TestExecutionsCount.With(map[string]string{ 177 "type": execution.TestType, 178 "name": execution.TestName, 179 "result": status, 180 "labels": strings.Join(labels, ","), 181 "test_uri": fmt.Sprintf("%s/tests/%s", dashboardURI, execution.TestName), 182 }).Inc() 183 184 m.TestExecutionsDurationMs.With(map[string]string{ 185 "type": execution.TestType, 186 "name": execution.TestName, 187 "result": status, 188 "labels": strings.Join(labels, ","), 189 "test_uri": fmt.Sprintf("%s/tests/%s", dashboardURI, execution.TestName), 190 }).Observe(float64(execution.DurationMs)) 191 } 192 193 func (m Metrics) IncAndObserveExecuteTestSuite(execution testkube.TestSuiteExecution, dashboardURI string) { 194 name := "" 195 status := "" 196 if execution.TestSuite != nil { 197 name = execution.TestSuite.Name 198 } 199 200 if execution.Status != nil { 201 status = string(*execution.Status) 202 } 203 204 var labels []string 205 for key, value := range execution.Labels { 206 labels = append(labels, fmt.Sprintf("%s=%s", key, value)) 207 } 208 209 slices.Sort(labels) 210 testSuiteName := "" 211 if execution.TestSuite != nil { 212 testSuiteName = execution.TestSuite.Name 213 } 214 215 m.TestSuiteExecutionsCount.With(map[string]string{ 216 "name": name, 217 "result": status, 218 "labels": strings.Join(labels, ","), 219 "testsuite_uri": fmt.Sprintf("%s/test-suites/%s", dashboardURI, testSuiteName), 220 }).Inc() 221 222 m.TestSuiteExecutionsDurationMs.With(map[string]string{ 223 "name": name, 224 "result": status, 225 "labels": strings.Join(labels, ","), 226 "testsuite_uri": fmt.Sprintf("%s/test-suites/%s", dashboardURI, testSuiteName), 227 }).Observe(float64(execution.DurationMs)) 228 } 229 230 func (m Metrics) IncUpdateTest(testType string, err error) { 231 result := "updated" 232 if err != nil { 233 result = "error" 234 } 235 236 m.TestUpdates.With(map[string]string{ 237 "type": testType, 238 "result": result, 239 }).Inc() 240 } 241 242 func (m Metrics) IncUpdateTestSuite(err error) { 243 result := "updated" 244 if err != nil { 245 result = "error" 246 } 247 248 m.TestSuiteUpdates.With(map[string]string{ 249 "result": result, 250 }).Inc() 251 } 252 253 func (m Metrics) IncCreateTest(testType string, err error) { 254 result := "created" 255 if err != nil { 256 result = "error" 257 } 258 259 m.TestCreations.With(map[string]string{ 260 "type": testType, 261 "result": result, 262 }).Inc() 263 } 264 265 func (m Metrics) IncCreateTestSuite(err error) { 266 result := "created" 267 if err != nil { 268 result = "error" 269 } 270 271 m.TestSuiteCreations.With(map[string]string{ 272 "result": result, 273 }).Inc() 274 } 275 276 func (m Metrics) IncCreateTestTrigger(err error) { 277 result := "created" 278 if err != nil { 279 result = "error" 280 } 281 282 m.TestTriggerCreations.With(map[string]string{ 283 "result": result, 284 }).Inc() 285 } 286 287 func (m Metrics) IncUpdateTestTrigger(err error) { 288 result := "updated" 289 if err != nil { 290 result = "error" 291 } 292 293 m.TestTriggerUpdates.With(map[string]string{ 294 "result": result, 295 }).Inc() 296 } 297 298 func (m Metrics) IncDeleteTestTrigger(err error) { 299 result := "deleted" 300 if err != nil { 301 result = "error" 302 } 303 304 m.TestTriggerDeletes.With(map[string]string{ 305 "result": result, 306 }).Inc() 307 } 308 309 func (m Metrics) IncBulkUpdateTestTrigger(err error) { 310 result := "bulk_update" 311 if err != nil { 312 result = "error" 313 } 314 315 m.TestTriggerBulkUpdates.With(map[string]string{ 316 "result": result, 317 }).Inc() 318 } 319 320 func (m Metrics) IncBulkDeleteTestTrigger(err error) { 321 result := "bulk_delete" 322 if err != nil { 323 result = "error" 324 } 325 326 m.TestTriggerBulkDeletes.With(map[string]string{ 327 "result": result, 328 }).Inc() 329 } 330 331 func (m Metrics) IncAbortTest(testType string, failed bool) { 332 result := "aborted" 333 if failed { 334 result = "error" 335 } 336 337 m.TestAbort.With(map[string]string{ 338 "type": testType, 339 "result": result, 340 }).Inc() 341 } 342 343 func (m Metrics) IncCreateTestWorkflow(err error) { 344 result := "created" 345 if err != nil { 346 result = "error" 347 } 348 349 m.TestWorkflowCreations.With(map[string]string{ 350 "result": result, 351 }).Inc() 352 } 353 354 func (m Metrics) IncUpdateTestWorkflow(err error) { 355 result := "updated" 356 if err != nil { 357 result = "error" 358 } 359 360 m.TestWorkflowUpdates.With(map[string]string{ 361 "result": result, 362 }).Inc() 363 } 364 365 func (m Metrics) IncDeleteTestWorkflow(err error) { 366 result := "deleted" 367 if err != nil { 368 result = "error" 369 } 370 371 m.TestWorkflowDeletes.With(map[string]string{ 372 "result": result, 373 }).Inc() 374 } 375 376 func (m Metrics) IncCreateTestWorkflowTemplate(err error) { 377 result := "created" 378 if err != nil { 379 result = "error" 380 } 381 382 m.TestWorkflowTemplateCreations.With(map[string]string{ 383 "result": result, 384 }).Inc() 385 } 386 387 func (m Metrics) IncUpdateTestWorkflowTemplate(err error) { 388 result := "updated" 389 if err != nil { 390 result = "error" 391 } 392 393 m.TestWorkflowTemplateUpdates.With(map[string]string{ 394 "result": result, 395 }).Inc() 396 } 397 398 func (m Metrics) IncDeleteTestWorkflowTemplate(err error) { 399 result := "deleted" 400 if err != nil { 401 result = "error" 402 } 403 404 m.TestWorkflowTemplateDeletes.With(map[string]string{ 405 "result": result, 406 }).Inc() 407 }