From 8c9cd962132d74175ac5f14f6a1a56511873cbcd Mon Sep 17 00:00:00 2001 From: Andrej Mickov Date: Mon, 2 Mar 2026 22:30:15 +0100 Subject: [PATCH] Auth for metrics, removed unwanted metrics and fixed tests. --- api/api.go | 8 +++---- auth/middleware.go | 2 +- logging/logging.go | 2 -- metrics/metrics.go | 46 +++++++++-------------------------------- metrics/metrics_test.go | 26 +++++++++++++++++++++++ 5 files changed, 41 insertions(+), 43 deletions(-) create mode 100644 metrics/metrics_test.go diff --git a/api/api.go b/api/api.go index 61e81a8..250bac2 100644 --- a/api/api.go +++ b/api/api.go @@ -110,13 +110,14 @@ func (h *Handler) handleHealth(w http.ResponseWriter, r *http.Request) { } func (h *Handler) handleMetrics(w http.ResponseWriter, r *http.Request) { - payload := metrics.Default.RenderPrometheus() w.Header().Set("Content-Type", "text/plain; version=0.0.4; charset=utf-8") - w.Header().Set("Content-Length", strconv.Itoa(len(payload))) - w.WriteHeader(http.StatusOK) if r.Method == http.MethodHead { + w.WriteHeader(http.StatusOK) return } + payload := metrics.Default.RenderPrometheus() + w.Header().Set("Content-Length", strconv.Itoa(len(payload))) + w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(payload)) } @@ -645,7 +646,6 @@ func newLimitedListener(inner net.Listener, maxConns int) net.Listener { return inner } metrics.Default.SetConnectionPoolMax(maxConns) - metrics.Default.SetWorkerPoolSize(maxConns) return &limitedListener{ Listener: inner, slots: make(chan struct{}, maxConns), diff --git a/auth/middleware.go b/auth/middleware.go index 63cebbd..24f656e 100644 --- a/auth/middleware.go +++ b/auth/middleware.go @@ -25,7 +25,7 @@ func Middleware( return } - if r.URL.Path == "/healthz" || r.URL.Path == "/metrics" { + if r.URL.Path == "/healthz" { metrics.Default.ObserveAuth("bypass", "none", "public_endpoint") next.ServeHTTP(w, r.WithContext(WithRequestContext(r.Context(), authCtx))) return diff --git a/logging/logging.go b/logging/logging.go index 2749695..3600da7 100644 --- a/logging/logging.go +++ b/logging/logging.go @@ -90,10 +90,8 @@ func HTTPMiddleware(logger *slog.Logger, cfg Config) func(http.Handler) http.Han ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor) op := metricOperationLabel(r) metrics.Default.IncHTTPInFlightOp(op) - metrics.Default.IncWorkerPoolActive() defer func() { metrics.Default.DecHTTPInFlightOp(op) - metrics.Default.DecWorkerPoolActive() }() requestID := middleware.GetReqID(r.Context()) if requestID != "" { diff --git a/metrics/metrics.go b/metrics/metrics.go index 307f8aa..8f11b39 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -75,8 +75,6 @@ type Registry struct { connectionPoolWaits atomic.Uint64 requestQueueLength atomic.Int64 - workerPoolActive atomic.Int64 - workerPoolSize atomic.Int64 mu sync.Mutex @@ -364,21 +362,6 @@ func (r *Registry) DecRequestQueueLength() { r.requestQueueLength.Add(-1) } -func (r *Registry) SetWorkerPoolSize(size int) { - if size < 0 { - size = 0 - } - r.workerPoolSize.Store(int64(size)) -} - -func (r *Registry) IncWorkerPoolActive() { - r.workerPoolActive.Add(1) -} - -func (r *Registry) DecWorkerPoolActive() { - r.workerPoolActive.Add(-1) -} - func (r *Registry) ObserveLockWait(lockName string, d time.Duration) { lockName = strings.TrimSpace(lockName) if lockName == "" { @@ -520,10 +503,7 @@ func (r *Registry) RenderPrometheus() string { connectionMax := float64(r.connectionPoolMax.Load()) connectionWaits := r.connectionPoolWaits.Load() queueLength := float64(r.requestQueueLength.Load()) - workerActive := float64(r.workerPoolActive.Load()) - workerSize := float64(r.workerPoolSize.Load()) - openFDs, hasOpenFDs := readOpenFDs() resident, hasResident := readResidentMemoryBytes() cpuSeconds, hasCPU := readProcessCPUSeconds() @@ -555,8 +535,6 @@ func (r *Registry) RenderPrometheus() string { writeCounter(&b, "fs_connection_pool_waits_total", "Number of waits due to pool saturation.", connectionWaits) writeGauge(&b, "fs_request_queue_length", "Requests waiting for an execution slot.", queueLength) - writeGauge(&b, "fs_worker_pool_active", "Active workers.", workerActive) - writeGauge(&b, "fs_worker_pool_size", "Configured worker pool size.", workerSize) writeHistogramVecKV(&b, "fs_lock_wait_seconds", "Time spent waiting for locks.", lockWait, []string{"lock_name"}) writeHistogramVecKV(&b, "fs_lock_hold_seconds", "Time locks were held.", lockHold, []string{"lock_name"}) @@ -594,10 +572,6 @@ func (r *Registry) RenderPrometheus() string { if hasResident { writeGauge(&b, "process_resident_memory_bytes", "Resident memory size in bytes.", resident) } - if hasOpenFDs { - writeGauge(&b, "process_open_fds", "Number of open file descriptors.", openFDs) - writeGauge(&b, "fs_open_fds", "Number of open file descriptors.", openFDs) - } return b.String() } @@ -732,8 +706,16 @@ func writeHistogramWithLabelsMap(b *strings.Builder, name string, labels map[str } fmt.Fprintf(b, "%s_bucket{%s} %d\n", name, labelsToString(bucketLabels), cumulative) } - fmt.Fprintf(b, "%s_sum{%s} %.9f\n", name, labelsToString(labels), s.sum) - fmt.Fprintf(b, "%s_count{%s} %d\n", name, labelsToString(labels), s.count) + labelsSuffix := formatLabelsSuffix(labels) + fmt.Fprintf(b, "%s_sum%s %.9f\n", name, labelsSuffix, s.sum) + fmt.Fprintf(b, "%s_count%s %d\n", name, labelsSuffix, s.count) +} + +func formatLabelsSuffix(labels map[string]string) string { + if len(labels) == 0 { + return "" + } + return "{" + labelsToString(labels) + "}" } func formatLabels(keys, values []string) string { @@ -786,14 +768,6 @@ func escapeLabelValue(value string) string { return value } -func readOpenFDs() (float64, bool) { - entries, err := os.ReadDir("/proc/self/fd") - if err != nil { - return 0, false - } - return float64(len(entries)), true -} - func readResidentMemoryBytes() (float64, bool) { data, err := os.ReadFile("/proc/self/statm") if err != nil { diff --git a/metrics/metrics_test.go b/metrics/metrics_test.go new file mode 100644 index 0000000..2fffc4f --- /dev/null +++ b/metrics/metrics_test.go @@ -0,0 +1,26 @@ +package metrics + +import ( + "strings" + "testing" +) + +func TestRenderPrometheusHistogramNoEmptyLabelSet(t *testing.T) { + reg := NewRegistry() + reg.ObserveBatchSize(3) + reg.ObserveGC(0, 0, 0, 0, true) + + out := reg.RenderPrometheus() + if strings.Contains(out, "fs_batch_size_histogram_sum{}") { + t.Fatalf("unexpected empty label set for batch sum metric") + } + if strings.Contains(out, "fs_batch_size_histogram_count{}") { + t.Fatalf("unexpected empty label set for batch count metric") + } + if strings.Contains(out, "fs_gc_duration_seconds_sum{}") { + t.Fatalf("unexpected empty label set for gc sum metric") + } + if strings.Contains(out, "fs_gc_duration_seconds_count{}") { + t.Fatalf("unexpected empty label set for gc count metric") + } +}