Skip to content

Commit f87f766

Browse files
authored
[ws-manager-mk2] do not report workspace activity metrics if it not a leader (#19360)
1 parent cde558c commit f87f766

File tree

2 files changed

+81
-72
lines changed

2 files changed

+81
-72
lines changed

components/ws-manager-mk2/controllers/metrics.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ package controllers
66

77
import (
88
"context"
9+
"fmt"
910
"strings"
1011
"time"
1112

1213
wsk8s "github.com/gitpod-io/gitpod/common-go/kubernetes"
14+
"github.com/gitpod-io/gitpod/ws-manager-mk2/pkg/activity"
1315
"github.com/gitpod-io/gitpod/ws-manager-mk2/pkg/maintenance"
1416
workspacev1 "github.com/gitpod-io/gitpod/ws-manager/api/crd/v1"
1517
"github.com/go-logr/logr"
@@ -33,6 +35,7 @@ const (
3335
workspaceRestoresTotal string = "workspace_restores_total"
3436
workspaceRestoresFailureTotal string = "workspace_restores_failure_total"
3537
workspaceNodeUtilization string = "workspace_node_utilization"
38+
workspaceActivityTotal string = "workspace_activity_total"
3639
)
3740

3841
type StopReason string
@@ -65,6 +68,8 @@ type controllerMetrics struct {
6568

6669
workspaceNodeUtilization *nodeUtilizationVec
6770

71+
workspaceActivityTotal *workspaceActivityVec
72+
6873
// used to prevent recording metrics multiple times
6974
cache *lru.Cache
7075
}
@@ -144,6 +149,7 @@ func newControllerMetrics(r *WorkspaceReconciler) (*controllerMetrics, error) {
144149
workspacePhases: newPhaseTotalVec(r),
145150
timeoutSettings: newTimeoutSettingsVec(r),
146151
workspaceNodeUtilization: newNodeUtilizationVec(r),
152+
workspaceActivityTotal: newWorkspaceActivityVec(r),
147153
cache: cache,
148154
}, nil
149155
}
@@ -328,6 +334,7 @@ func (m *controllerMetrics) Describe(ch chan<- *prometheus.Desc) {
328334
m.workspacePhases.Describe(ch)
329335
m.timeoutSettings.Describe(ch)
330336
m.workspaceNodeUtilization.Describe(ch)
337+
m.workspaceActivityTotal.Describe(ch)
331338
}
332339

333340
// Collect implements Collector.
@@ -347,6 +354,7 @@ func (m *controllerMetrics) Collect(ch chan<- prometheus.Metric) {
347354
m.workspacePhases.Collect(ch)
348355
m.timeoutSettings.Collect(ch)
349356
m.workspaceNodeUtilization.Collect(ch)
357+
m.workspaceActivityTotal.Collect(ch)
350358
}
351359

352360
// phaseTotalVec returns a gauge vector counting the workspaces per phase
@@ -612,3 +620,76 @@ func (n *nodeUtilizationVec) Collect(ch chan<- prometheus.Metric) {
612620
}
613621
}
614622
}
623+
624+
type workspaceActivityVec struct {
625+
name string
626+
desc *prometheus.Desc
627+
reconciler *WorkspaceReconciler
628+
}
629+
630+
func newWorkspaceActivityVec(r *WorkspaceReconciler) *workspaceActivityVec {
631+
name := prometheus.BuildFQName(metricsNamespace, metricsWorkspaceSubsystem, workspaceActivityTotal)
632+
desc := prometheus.NewDesc(
633+
name,
634+
"total number of active workspaces",
635+
[]string{"active"},
636+
prometheus.Labels(map[string]string{}),
637+
)
638+
return &workspaceActivityVec{
639+
name: name,
640+
desc: desc,
641+
reconciler: r,
642+
}
643+
}
644+
645+
// Describe implements Collector. It will send exactly one Desc to the provided channel.
646+
func (wav *workspaceActivityVec) Describe(ch chan<- *prometheus.Desc) {
647+
ch <- wav.desc
648+
}
649+
650+
func (wav *workspaceActivityVec) Collect(ch chan<- prometheus.Metric) {
651+
ctx, cancel := context.WithTimeout(context.Background(), kubernetesOperationTimeout)
652+
defer cancel()
653+
654+
active, notActive, err := wav.getWorkspaceActivityCounts()
655+
if err != nil {
656+
log.FromContext(ctx).Error(err, fmt.Sprintf("cannot determine active/inactive counts - %s will be inaccurate", wav.name))
657+
return
658+
}
659+
660+
activeMetrics, err := prometheus.NewConstMetric(wav.desc, prometheus.GaugeValue, float64(active), "true")
661+
if err != nil {
662+
log.FromContext(ctx).Error(err, "cannot create wrokspace activity metric", "active", "true")
663+
return
664+
}
665+
notActiveMetrics, err := prometheus.NewConstMetric(wav.desc, prometheus.GaugeValue, float64(notActive), "false")
666+
if err != nil {
667+
log.FromContext(ctx).Error(err, "cannot create wrokspace activity metric", "active", "false")
668+
return
669+
}
670+
671+
ch <- activeMetrics
672+
ch <- notActiveMetrics
673+
}
674+
675+
func (wav *workspaceActivityVec) getWorkspaceActivityCounts() (active, notActive int, err error) {
676+
var workspaces workspacev1.WorkspaceList
677+
if err = wav.reconciler.List(context.Background(), &workspaces, client.InNamespace(wav.reconciler.Config.Namespace)); err != nil {
678+
return 0, 0, err
679+
}
680+
681+
for _, ws := range workspaces.Items {
682+
if ws.Spec.Type != workspacev1.WorkspaceTypeRegular {
683+
continue
684+
}
685+
686+
hasActivity := activity.Last(&ws) != nil
687+
if hasActivity {
688+
active++
689+
} else {
690+
notActive++
691+
}
692+
}
693+
694+
return
695+
}

components/ws-manager-mk2/service/manager.go

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,7 +1417,6 @@ func (subs *subscriptions) OnChange(ctx context.Context, status *wsmanapi.Worksp
14171417

14181418
type workspaceMetrics struct {
14191419
totalStartsCounterVec *prometheus.CounterVec
1420-
workspaceActivityVec *workspaceActivityVec
14211420
}
14221421

14231422
func newWorkspaceMetrics(namespace string, k8s client.Client) *workspaceMetrics {
@@ -1428,7 +1427,6 @@ func newWorkspaceMetrics(namespace string, k8s client.Client) *workspaceMetrics
14281427
Name: "workspace_starts_total",
14291428
Help: "total number of workspaces started",
14301429
}, []string{"type", "class"}),
1431-
workspaceActivityVec: newWorkspaceActivityVec(namespace, k8s),
14321430
}
14331431
}
14341432

@@ -1446,79 +1444,9 @@ func (m *workspaceMetrics) recordWorkspaceStart(ws *workspacev1.Workspace) {
14461444
// Describe implements Collector. It will send exactly one Desc to the provided channel.
14471445
func (m *workspaceMetrics) Describe(ch chan<- *prometheus.Desc) {
14481446
m.totalStartsCounterVec.Describe(ch)
1449-
m.workspaceActivityVec.Describe(ch)
14501447
}
14511448

14521449
// Collect implements Collector.
14531450
func (m *workspaceMetrics) Collect(ch chan<- prometheus.Metric) {
14541451
m.totalStartsCounterVec.Collect(ch)
1455-
m.workspaceActivityVec.Collect(ch)
1456-
}
1457-
1458-
type workspaceActivityVec struct {
1459-
*prometheus.GaugeVec
1460-
name string
1461-
workspaceNamespace string
1462-
k8s client.Client
1463-
}
1464-
1465-
func newWorkspaceActivityVec(workspaceNamespace string, k8s client.Client) *workspaceActivityVec {
1466-
opts := prometheus.GaugeOpts{
1467-
Namespace: "gitpod",
1468-
Subsystem: "ws_manager_mk2",
1469-
Name: "workspace_activity_total",
1470-
Help: "total number of active workspaces",
1471-
}
1472-
return &workspaceActivityVec{
1473-
GaugeVec: prometheus.NewGaugeVec(opts, []string{"active"}),
1474-
name: prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
1475-
workspaceNamespace: workspaceNamespace,
1476-
k8s: k8s,
1477-
}
1478-
}
1479-
1480-
func (wav *workspaceActivityVec) Collect(ch chan<- prometheus.Metric) {
1481-
active, notActive, err := wav.getWorkspaceActivityCounts()
1482-
if err != nil {
1483-
log.WithError(err).Errorf("cannot determine active/inactive counts - %s will be inaccurate", wav.name)
1484-
return
1485-
}
1486-
1487-
activeGauge, err := wav.GetMetricWithLabelValues("true")
1488-
if err != nil {
1489-
log.WithError(err).Error("cannot get active gauge count - this is an internal configuration error and should not happen")
1490-
return
1491-
}
1492-
1493-
notActiveGauge, err := wav.GetMetricWithLabelValues("false")
1494-
if err != nil {
1495-
log.WithError(err).Error("cannot get not-active gauge count - this is an internal configuration error and should not happen")
1496-
return
1497-
}
1498-
1499-
activeGauge.Set(float64(active))
1500-
notActiveGauge.Set(float64(notActive))
1501-
wav.GaugeVec.Collect(ch)
1502-
}
1503-
1504-
func (wav *workspaceActivityVec) getWorkspaceActivityCounts() (active, notActive int, err error) {
1505-
var workspaces workspacev1.WorkspaceList
1506-
if err = wav.k8s.List(context.Background(), &workspaces, client.InNamespace(wav.workspaceNamespace)); err != nil {
1507-
return 0, 0, err
1508-
}
1509-
1510-
for _, ws := range workspaces.Items {
1511-
if ws.Spec.Type != workspacev1.WorkspaceTypeRegular {
1512-
continue
1513-
}
1514-
1515-
hasActivity := activity.Last(&ws) != nil
1516-
if hasActivity {
1517-
active++
1518-
} else {
1519-
notActive++
1520-
}
1521-
}
1522-
1523-
return
15241452
}

0 commit comments

Comments
 (0)