Skip to content

Commit

Permalink
enhance(metrics): include route specific queue length
Browse files Browse the repository at this point in the history
  • Loading branch information
ecrupper committed Jan 8, 2025
1 parent f34ffb9 commit d7d3255
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 6 deletions.
19 changes: 14 additions & 5 deletions api/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package api

import (
"fmt"
"net/http"
"time"

Expand All @@ -15,6 +16,7 @@ import (
"github.com/go-vela/server/constants"
"github.com/go-vela/server/database"
"github.com/go-vela/server/queue"
"github.com/go-vela/server/router/middleware/settings"
)

// MetricsQueryParameters holds query parameter information pertaining to requested metrics.
Expand Down Expand Up @@ -303,13 +305,20 @@ func recordGauges(c *gin.Context) {

// queued_build_count
if q.QueuedBuildCount {
// send API call to capture the total number of queued builds
t, err := queue.FromContext(c).Length(c)
if err != nil {
logrus.Errorf("unable to get count of all queued builds: %v", err)
queueTotal := int64(0)

for _, route := range settings.FromContext(c).GetRoutes() {
t, err := queue.FromContext(c).RouteLength(c, route)
if err != nil {
logrus.Errorf("unable to get count of all queued builds for route %s: %v", route, err)
}

totals.WithLabelValues("build", "status", fmt.Sprintf("queued_%s", route)).Set(float64(t))

queueTotal += t
}

totals.WithLabelValues("build", "status", "queued").Set(float64(t))
totals.WithLabelValues("build", "status", "queued").Set(float64(queueTotal))
}

// failure_build_count
Expand Down
19 changes: 19 additions & 0 deletions queue/redis/route_length.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: Apache-2.0

package redis

import (
"context"
)

// RouteLength returns count of all items present in the given route.
func (c *client) RouteLength(ctx context.Context, channel string) (int64, error) {
c.Logger.Tracef("reading length of all configured routes in queue")

items, err := c.Redis.LLen(ctx, channel).Result()
if err != nil {
return 0, err
}

return items, nil
}
68 changes: 68 additions & 0 deletions queue/redis/route_length_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: Apache-2.0

package redis

import (
"context"
"encoding/json"
"testing"

"github.com/go-vela/server/queue/models"
)

func TestRedis_RouteLength(t *testing.T) {
// setup types
// use global variables in redis_test.go
_item := &models.Item{
Build: _build,
}

// setup queue item
bytes, err := json.Marshal(_item)
if err != nil {
t.Errorf("unable to marshal queue item: %v", err)
}

// setup redis mock
_redis, err := NewTest(_signingPrivateKey, _signingPublicKey, "vela", "vela:second", "vela:third")
if err != nil {
t.Errorf("unable to create queue service: %v", err)
}

// setup tests
tests := []struct {
routes []string
want int64
}{
{
routes: []string{"vela"},
want: 1,
},
{
routes: []string{"vela", "vela:second", "vela:third"},
want: 2,
},
{
routes: []string{"vela", "vela:second", "phony"},
want: 3,
},
}

// run tests
for _, test := range tests {
for _, channel := range test.routes {
err := _redis.Push(context.Background(), channel, bytes)
if err != nil {
t.Errorf("unable to push item to queue: %v", err)
}
}
got, err := _redis.RouteLength(context.Background(), "vela")
if err != nil {
t.Errorf("RouteLength returned err: %v", err)
}

if got != test.want {
t.Errorf("Length is %v, want %v", got, test.want)
}
}
}
6 changes: 5 additions & 1 deletion queue/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ type Service interface {
Driver() string

// Length defines a function that outputs
// the length of a queue channel
// the length of all queue channels
Length(context.Context) (int64, error)

// RouteLength defines a function that outputs
// the length of a defined queue route
RouteLength(context.Context, string) (int64, error)

// Pop defines a function that grabs an
// item off the queue.
Pop(context.Context, []string) (*models.Item, error)
Expand Down

0 comments on commit d7d3255

Please sign in to comment.