package metrics import ( "github.com/prometheus/client_golang/prometheus" controllerExtraction "proxy-pool/internal/controller/extraction" ) // ExtractionCollector exposes bounded Distribution business metrics. Client, // proxy, upstream, filter, request, and error values are never labels. type ExtractionCollector struct { requests *prometheus.CounterVec requested prometheus.Counter returned prometheus.Counter } var _ controllerExtraction.MetricsObserver = (*ExtractionCollector)(nil) func NewExtractionCollector(registerer prometheus.Registerer) (*ExtractionCollector, error) { if registerer == nil { return nil, ErrInvalidDependencies } requests, err := registerCounterVec(registerer, prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: "proxy_pool", Subsystem: "controller", Name: "extraction_requests_total", Help: "Number of completed Distribution extraction requests by fixed result.", }, []string{"result"})) if err != nil { return nil, err } requested, err := registerCounter(registerer, prometheus.NewCounter(prometheus.CounterOpts{ Namespace: "proxy_pool", Subsystem: "controller", Name: "extraction_requested_proxies_total", Help: "Number of proxies requested from completed Distribution extraction requests.", })) if err != nil { return nil, err } returned, err := registerCounter(registerer, prometheus.NewCounter(prometheus.CounterOpts{ Namespace: "proxy_pool", Subsystem: "controller", Name: "extraction_returned_proxies_total", Help: "Number of proxies returned in Distribution extraction responses, including idempotent replays.", })) if err != nil { return nil, err } return &ExtractionCollector{requests: requests, requested: requested, returned: returned}, nil } func (collector *ExtractionCollector) ObserveExtraction(event controllerExtraction.MetricsEvent) { if collector == nil || collector.requests == nil || !validExtractionMetricResult(event.Result) { return } collector.requests.WithLabelValues(string(event.Result)).Inc() if event.Requested > 0 && collector.requested != nil { collector.requested.Add(float64(event.Requested)) } if event.Returned > 0 && collector.returned != nil { collector.returned.Add(float64(event.Returned)) } } func validExtractionMetricResult(result controllerExtraction.MetricResult) bool { switch result { case controllerExtraction.MetricComplete, controllerExtraction.MetricPartial, controllerExtraction.MetricEmpty, controllerExtraction.MetricInsufficient, controllerExtraction.MetricIdempotencyConflict, controllerExtraction.MetricRateLimited, controllerExtraction.MetricUnavailable, controllerExtraction.MetricInvalid, controllerExtraction.MetricError: return true default: return false } }