Skip to content

Commit 62e0a7d

Browse files
authored
feat(api): allow to filter tasks with tags (#256)
Signed-off-by: Thomas Bétrancourt <[email protected]>
1 parent c8a8325 commit 62e0a7d

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

api/metrics.go

+21-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package api
22

33
import (
44
"context"
5+
"strings"
56
"time"
67

78
"github.com/gin-gonic/gin"
9+
"github.com/juju/errors"
810
"github.com/loopfz/gadgeto/zesty"
911
"github.com/prometheus/client_golang/prometheus"
1012
"github.com/prometheus/client_golang/prometheus/promauto"
@@ -30,7 +32,7 @@ func collectMetrics(ctx context.Context) {
3032
for {
3133
select {
3234
case <-tick.C:
33-
stats, err := task.LoadStateCount(dbp)
35+
stats, err := task.LoadStateCount(dbp, nil)
3436
if err != nil {
3537
logrus.Warn(err)
3638
}
@@ -45,6 +47,10 @@ func collectMetrics(ctx context.Context) {
4547
}()
4648
}
4749

50+
type StatsIn struct {
51+
Tags []string `query:"tag" explode:"true"`
52+
}
53+
4854
// StatsOut aggregates different business stats:
4955
// - a map of task states and their count
5056
type StatsOut struct {
@@ -53,14 +59,26 @@ type StatsOut struct {
5359

5460
// Stats handles the http request to fetch µtask statistics
5561
// common to all instances
56-
func Stats(c *gin.Context) (*StatsOut, error) {
62+
func Stats(c *gin.Context, in *StatsIn) (*StatsOut, error) {
5763
dbp, err := zesty.NewDBProvider(utask.DBName)
5864
if err != nil {
5965
return nil, err
6066
}
6167

68+
tags := make(map[string]string, len(in.Tags))
69+
for _, t := range in.Tags {
70+
parts := strings.Split(t, "=")
71+
if len(parts) != 2 {
72+
return nil, errors.BadRequestf("invalid tag %s", t)
73+
}
74+
if parts[0] == "" || parts[1] == "" {
75+
return nil, errors.BadRequestf("invalid tag %s", t)
76+
}
77+
tags[parts[0]] = parts[1]
78+
}
79+
6280
out := StatsOut{}
63-
out.TaskStates, err = task.LoadStateCount(dbp)
81+
out.TaskStates, err = task.LoadStateCount(dbp, tags)
6482
if err != nil {
6583
return nil, err
6684
}

models/task/stats.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package task
22

33
import (
4+
"encoding/json"
45
"time"
56

67
"github.com/juju/errors"
@@ -46,13 +47,22 @@ func RegisterTaskTime(templateName string, taskCreation, resCreation time.Time)
4647
}
4748

4849
// LoadStateCount returns a map containing the count of tasks grouped by state
49-
func LoadStateCount(dbp zesty.DBProvider) (sc map[string]float64, err error) {
50+
func LoadStateCount(dbp zesty.DBProvider, tags map[string]string) (sc map[string]float64, err error) {
5051
defer errors.DeferredAnnotatef(&err, "Failed to load task stats")
5152

52-
query, params, err := sqlgenerator.PGsql.Select(`state, count(state) as state_count`).
53+
sel := sqlgenerator.PGsql.Select(`state, count(state) as state_count`).
5354
From(`"task"`).
54-
GroupBy(`state`).
55-
ToSql()
55+
GroupBy(`state`)
56+
57+
if len(tags) > 0 {
58+
b, err := json.Marshal(tags)
59+
if err != nil {
60+
return nil, err
61+
}
62+
sel = sel.Where(`"task".tags @> ?::jsonb`, string(b))
63+
}
64+
65+
query, params, err := sel.ToSql()
5666
if err != nil {
5767
return nil, err
5868
}

0 commit comments

Comments
 (0)