Files
coder/scaletest/workspaceupdates/metrics.go
T
Ethan 65ac6cb42a feat(scaletest): add runner for coder connect load gen (#19904)
Relates to https://github.com/coder/internal/issues/889.

This PR adds a scaletest runner that simulates a single Coder Connect client receiving workspace updates.

An instance of a workspace updates runner does the following:
- Creates a user, if a session token is not supplied.
- Attempts to repeatedly dial the Coder Connect endpoint, with a configurable (two minutes by default) timeout. 
- Once dialed successfully, waits for any other concurrently executing runners to also dial successfully, or timeout (using the barrier).
- Starts a configurable number of workspace builds.
- Waits for that many workspaces to be seen over the workspace updates stream (with a configurable timeout).

Exposes two prometheus metrics:
- `workspace_updates_latency_seconds` - `HistogramVec`. Labels = `{username, num_owned_workspaces, workspace_name}`
  - This is the time between starting a workspace build, and receiving both the corresponding workspace update.
- `workspace_updates_errors_total` - `NewCounterVec`. Labels = `{username, num_owned_workspaces, action}`
  - The number of times a specific action of the runner has failed, per user/client.
2025-09-30 17:28:58 +10:00

43 lines
1.5 KiB
Go

package workspaceupdates
import (
"strconv"
"time"
"github.com/prometheus/client_golang/prometheus"
)
type Metrics struct {
WorkspaceUpdatesLatencySeconds prometheus.HistogramVec
WorkspaceUpdatesErrorsTotal prometheus.CounterVec
}
func NewMetrics(reg prometheus.Registerer) *Metrics {
m := &Metrics{
WorkspaceUpdatesLatencySeconds: *prometheus.NewHistogramVec(prometheus.HistogramOpts{
Namespace: "coderd",
Subsystem: "scaletest",
Name: "workspace_updates_latency_seconds",
Help: "Time between starting a workspace build and receiving both the agent update and workspace update",
}, []string{"username", "num_owned_workspaces", "workspace_name"}),
WorkspaceUpdatesErrorsTotal: *prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: "coderd",
Subsystem: "scaletest",
Name: "workspace_updates_errors_total",
Help: "Total number of workspace updates errors",
}, []string{"username", "num_owned_workspaces", "action"}),
}
reg.MustRegister(m.WorkspaceUpdatesLatencySeconds)
reg.MustRegister(m.WorkspaceUpdatesErrorsTotal)
return m
}
func (m *Metrics) RecordCompletion(elapsed time.Duration, username string, ownedWorkspaces int64, workspace string) {
m.WorkspaceUpdatesLatencySeconds.WithLabelValues(username, strconv.Itoa(int(ownedWorkspaces)), workspace).Observe(elapsed.Seconds())
}
func (m *Metrics) AddError(username string, ownedWorkspaces int64, action string) {
m.WorkspaceUpdatesErrorsTotal.WithLabelValues(username, strconv.Itoa(int(ownedWorkspaces)), action).Inc()
}