Skip to content

Commit d943c7b

Browse files
committed
Add histogram metric for workspace startup time
Signed-off-by: Angel Misevski <[email protected]>
1 parent 12ded7b commit d943c7b

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

controllers/workspace/metrics/metrics.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,20 @@ var (
5353
metricSourceLabel,
5454
},
5555
)
56+
workspaceStartupTimesHist = prometheus.NewHistogramVec(
57+
prometheus.HistogramOpts{
58+
Namespace: "devworkspace",
59+
Name: "startup_time",
60+
Help: "Total time taken to start a DevWorkspace, in seconds",
61+
Buckets: []float64{10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180},
62+
},
63+
[]string{
64+
metricSourceLabel,
65+
},
66+
)
5667
)
5768

5869
func init() {
5970
// Register custom metrics with the global prometheus registry
60-
metrics.Registry.MustRegister(workspaceTotal, workspaceStarts, workspaceFailures)
71+
metrics.Registry.MustRegister(workspaceTotal, workspaceStarts, workspaceFailures, workspaceStartupTimesHist)
6172
}

controllers/workspace/metrics/update.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,26 @@ import (
1616
dw "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
1717
"github.com/go-logr/logr"
1818
"github.com/prometheus/client_golang/prometheus"
19+
20+
"github.com/devfile/devworkspace-operator/pkg/conditions"
1921
)
2022

23+
// WorkspaceStarted updates metrics for workspaces entering the 'Starting' phase, given a workspace. If an error is
24+
// encountered, the provided logger is used to log the error.
2125
func WorkspaceStarted(wksp *dw.DevWorkspace, log logr.Logger) {
2226
incrementMetricForWorkspace(workspaceTotal, wksp, log)
2327
}
2428

29+
// WorkspaceRunning updates metrics for workspaces entering the 'Running' phase, given a workspace. If an error is
30+
// encountered, the provided logger is used to log the error. This function assumes the provided workspace has
31+
// fully-synced conditions (i.e. the WorkspaceReady condition is present).
2532
func WorkspaceRunning(wksp *dw.DevWorkspace, log logr.Logger) {
2633
incrementMetricForWorkspace(workspaceStarts, wksp, log)
34+
incrementStartTimeBucketForWorkspace(wksp, log)
2735
}
2836

37+
// WorkspaceFailed updates metrics for workspace entering the 'Failed' phase. If an error is encountered, the provided
38+
// logger is used to log the error.
2939
func WorkspaceFailed(wksp *dw.DevWorkspace, log logr.Logger) {
3040
incrementMetricForWorkspace(workspaceFailures, wksp, log)
3141
}
@@ -34,7 +44,27 @@ func incrementMetricForWorkspace(metric *prometheus.CounterVec, wksp *dw.DevWork
3444
sourceLabel := wksp.Labels[workspaceSourceLabel]
3545
ctr, err := metric.GetMetricWith(map[string]string{metricSourceLabel: sourceLabel})
3646
if err != nil {
37-
log.Info("Failed to increment metric: %s", err)
47+
log.Error(err, "Failed to increment metric")
3848
}
3949
ctr.Inc()
4050
}
51+
52+
func incrementStartTimeBucketForWorkspace(wksp *dw.DevWorkspace, log logr.Logger) {
53+
sourceLabel := wksp.Labels[workspaceSourceLabel]
54+
hist, err := workspaceStartupTimesHist.GetMetricWith(map[string]string{metricSourceLabel: sourceLabel})
55+
if err != nil {
56+
log.Error(err, "Failed to update metric")
57+
}
58+
readyCondition := conditions.GetConditionByType(wksp.Status.Conditions, dw.DevWorkspaceReady)
59+
if readyCondition == nil {
60+
return
61+
}
62+
startedCondition := conditions.GetConditionByType(wksp.Status.Conditions, conditions.Started)
63+
if startedCondition == nil {
64+
return
65+
}
66+
readyTime := readyCondition.LastTransitionTime
67+
startTime := startedCondition.LastTransitionTime
68+
startDuration := readyTime.Sub(startTime.Time)
69+
hist.Observe(startDuration.Seconds())
70+
}

controllers/workspace/status.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,10 @@ var healthHttpClient = &http.Client{
6363
// Parameters for result and error are returned unmodified, unless error is nil and another error is encountered while
6464
// updating the status.
6565
func (r *DevWorkspaceReconciler) updateWorkspaceStatus(workspace *dw.DevWorkspace, logger logr.Logger, status *currentStatus, reconcileResult reconcile.Result, reconcileError error) (reconcile.Result, error) {
66+
syncConditions(&workspace.Status, status)
6667
updateMetricsForPhase(workspace, status.phase, logger)
6768
workspace.Status.Phase = status.phase
6869

69-
syncConditions(&workspace.Status, status)
70-
7170
infoMessage := getInfoMessage(workspace, status)
7271
if workspace.Status.Message != infoMessage {
7372
workspace.Status.Message = infoMessage

0 commit comments

Comments
 (0)