Skip to content

Commit 62c0551

Browse files
committed
Export metric indicating each experiment's status
Signed-off-by: Danny Kopping <danny@coder.com>
1 parent f0f9569 commit 62c0551

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

cli/server.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,10 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
892892
return xerrors.Errorf("register agents prometheus metric: %w", err)
893893
}
894894
defer closeAgentsFunc()
895+
896+
if err = prometheusmetrics.Experiments(logger, options.PrometheusRegistry, options.DeploymentValues.Experiments.Value(), codersdk.ExperimentsAll); err != nil {
897+
return xerrors.Errorf("register experiments metric: %w", err)
898+
}
895899
}
896900

897901
client := codersdk.New(localURL)

coderd/prometheusmetrics/prometheusmetrics.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,31 @@ func AgentStats(ctx context.Context, logger slog.Logger, registerer prometheus.R
516516
}, nil
517517
}
518518

519+
// Experiments registers a metric which indicates whether each experiment is enabled or not.
520+
func Experiments(_ slog.Logger, registerer prometheus.Registerer, exps []string, all codersdk.Experiments) error {
521+
experimentsGauge := prometheus.NewGaugeVec(prometheus.GaugeOpts{
522+
Namespace: "coderd",
523+
Name: "experiments",
524+
Help: "Indicates whether each experiment is enabled (1) or not (0)",
525+
}, []string{"experiment"})
526+
if err := registerer.Register(experimentsGauge); err != nil {
527+
return err
528+
}
529+
530+
for _, exp := range all {
531+
var val float64
532+
for _, enabled := range exps {
533+
if string(exp) == enabled {
534+
val = 1
535+
}
536+
}
537+
538+
experimentsGauge.WithLabelValues(string(exp)).Set(val)
539+
}
540+
541+
return nil
542+
}
543+
519544
// filterAcceptableAgentLabels handles a slightly messy situation whereby `prometheus-aggregate-agent-stats-by` can control on
520545
// which labels agent stats are aggregated, but for these specific metrics in this file there is no `template` label value,
521546
// and therefore we have to exclude it from the list of acceptable labels.

coderd/prometheusmetrics/prometheusmetrics_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,41 @@ func TestAgentStats(t *testing.T) {
500500
assert.EqualValues(t, golden, collected)
501501
}
502502

503+
func TestExperimentsMetric(t *testing.T) {
504+
t.Parallel()
505+
506+
log := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
507+
reg := prometheus.NewRegistry()
508+
509+
const (
510+
a codersdk.Experiment = "a"
511+
b codersdk.Experiment = "b"
512+
c codersdk.Experiment = "c"
513+
)
514+
allExps := codersdk.Experiments{a, b, c}
515+
require.NoError(t, prometheusmetrics.Experiments(log, reg, []string{string(b), string(c)}, allExps))
516+
517+
expectation := map[codersdk.Experiment]float64{
518+
a: 0,
519+
b: 1,
520+
c: 1,
521+
}
522+
523+
out, err := reg.Gather()
524+
require.NoError(t, err)
525+
require.Lenf(t, out, 1, "unexpected number of registered metrics")
526+
527+
for _, metric := range out[0].GetMetric() {
528+
labels := metric.GetLabel()
529+
require.Lenf(t, labels, 1, "unexpected number of labels")
530+
531+
experiment := labels[0].GetValue()
532+
expected, found := expectation[codersdk.Experiment(experiment)]
533+
require.Truef(t, found, "did not find experiment %q in expectations", experiment)
534+
require.EqualValues(t, expected, metric.GetGauge().GetValue())
535+
}
536+
}
537+
503538
func prepareWorkspaceAndAgent(t *testing.T, client *codersdk.Client, user codersdk.CreateFirstUserResponse, workspaceNum int) *agentsdk.Client {
504539
authToken := uuid.NewString()
505540

0 commit comments

Comments
 (0)