feat(metrics): add named felis_* Prometheus collectors

Introduce internal/metrics exposing the four metric families spec §23
mandates at minimum: felis_servers_total (gauge by desired state),
felis_start_duration_seconds (histogram with Minecraft cold-start
buckets), felis_image_build_failures_total and
felis_reaper_worlds_deleted_total (counters). Collectors are
package-level vars so any subsystem records without an import cycle;
Register wires them into a prometheus.Registerer and is idempotent.

Wire registration into the operator against controller-runtime's global
Registry, so /metrics on the manager's existing metrics endpoint carries
the felis_* families. Instrument the reaper to increment
felis_reaper_worlds_deleted_total in lockstep with Summary.WorldsReaped,
at the one point a world's PVC has actually been deleted.
This commit is contained in:
flyemoji committed 2026-06-30 12:38:55 +09:00
1 parent 50b8487ff5
commit 75642d90cf
5 files changed
+231

No files matched your search

+12
View File
@@ -6,12 +6,14 @@ import (
"io"
"felis.lolicon.best/internal/apis/felis/v1alpha1"
felismetrics "felis.lolicon.best/internal/metrics"
"felis.lolicon.best/internal/operator"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
)
@@ -57,6 +59,16 @@ func cmdOperator(args []string, _, stderr io.Writer) int {
}
fmt.Fprintf(stderr, "felis operator: watching namespace %q\n", *namespace)
// Publish the named felis_* metrics (spec §23) on the endpoint the manager
// already serves (metricsAddr). controller-runtime's metrics server exposes
// its global Registry, so registering into it is all that is needed for
// /metrics to carry felis_servers_total and friends. Register is idempotent,
// so an in-process restart never double-registers fatally.
if err := felismetrics.Register(ctrlmetrics.Registry); err != nil {
fmt.Fprintf(stderr, "felis operator: register metrics: %v\n", err)
return 1
}
r := &operator.Reconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),