osbase/supervisor: implement Metrics API

This is a base building block for exporting per-DN/runnable status from
the supervisor into an external system. A sample implementation is
provided which can be used in simple debug facilities to inspect the
current supervision tree.

A follow-up change will use the same API to implement Prometheus
metrics.

Change-Id: I0d586b03a397a3ccf8dac2d8043b9dd2f319be4e
Reviewed-on: https://review.monogon.dev/c/monogon/+/3290
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/osbase/supervisor/supervisor.go b/osbase/supervisor/supervisor.go
index c7b0c0f..ff87a25 100644
--- a/osbase/supervisor/supervisor.go
+++ b/osbase/supervisor/supervisor.go
@@ -102,6 +102,8 @@
 
 	// propagate panics, ie. don't catch them.
 	propagatePanic bool
+
+	metrics *metricsFanout
 }
 
 // SupervisorOpt are runtime configurable options for the supervisor.
@@ -120,6 +122,15 @@
 	}
 }
 
+// WithMetrics makes the Supervisor export per-DN metrics into a given Metrics
+// implementation. This can be called repeatedly to export the same data into
+// multiple Metrics implementations.
+func WithMetrics(m Metrics) SupervisorOpt {
+	return func(s *supervisor) {
+		s.metrics.sub = append(s.metrics.sub, m)
+	}
+}
+
 // New creates a new supervisor with its root running the given root runnable.
 // The given context can be used to cancel the entire supervision tree.
 //
@@ -130,6 +141,7 @@
 	sup := &supervisor{
 		logtree: logtree.New(),
 		pReq:    make(chan *processorRequest),
+		metrics: &metricsFanout{},
 	}
 
 	for _, o := range opts {