/
job_stats.go
74 lines (60 loc) · 1.69 KB
/
job_stats.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package eventline
import (
"fmt"
"time"
"github.com/galdor/go-service/pkg/pg"
"github.com/jackc/pgx/v5"
)
type JobStats struct {
JobId Id `json:"job_id"`
NbExecutions int `json:"nb_executions"`
DurationP50 *time.Duration `json:"duration_p50,omitempty"`
SuccessRatio float64 `json:"success_ratio"` // last 7 days
}
type JobStatsList []*JobStats
func (js *JobStats) SuccessPercentage() float64 {
return js.SuccessRatio * 100.0
}
func (js *JobStats) SuccessPercentageString() string {
return fmt.Sprintf("%.0f%%", js.SuccessPercentage())
}
func LoadJobStats(conn pg.Conn, jobIds Ids, scope Scope) (map[Id]*JobStats, error) {
query := fmt.Sprintf(`
SELECT job_id,
COUNT(id) AS nb_executions,
(PERCENTILE_CONT(0.5) WITHIN GROUP
(ORDER BY end_time - start_time)
FILTER (WHERE status = 'successful')) AS duration_p50,
(COUNT(id) FILTER (WHERE status = 'successful')
/ COUNT(id)::FLOAT) AS success_ratio
FROM job_executions
WHERE %s
AND job_id = ANY ($1)
AND end_time > $2
GROUP BY job_id;
`, scope.SQLCondition())
now := time.Now().UTC()
minTime := now.AddDate(0, 0, -7)
var jss JobStatsList
err := pg.QueryObjects(conn, &jss, query, jobIds, minTime)
if err != nil {
return nil, err
}
table := make(map[Id]*JobStats)
for _, js := range jss {
table[js.JobId] = js
}
return table, nil
}
func (js *JobStats) FromRow(row pgx.Row) error {
return row.Scan(&js.JobId, &js.NbExecutions, &js.DurationP50,
&js.SuccessRatio)
}
func (jss *JobStatsList) AddFromRow(row pgx.Row) error {
var js JobStats
if err := js.FromRow(row); err != nil {
return err
}
*jss = append(*jss, &js)
return nil
}