Skip to content

Commit a0c823e

Browse files
committed
feat: migrate bbr metric server
Signed-off-by: nayihz <[email protected]>
1 parent c2fb015 commit a0c823e

File tree

3 files changed

+41
-99
lines changed

3 files changed

+41
-99
lines changed

cmd/bbr/main.go

Lines changed: 16 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,19 @@ package main
1818

1919
import (
2020
"flag"
21-
"net"
22-
"net/http"
2321
"os"
24-
"strconv"
2522

2623
"github.com/go-logr/logr"
27-
"github.com/prometheus/client_golang/prometheus/promhttp"
2824
uberzap "go.uber.org/zap"
2925
"go.uber.org/zap/zapcore"
3026
"google.golang.org/grpc"
3127
healthPb "google.golang.org/grpc/health/grpc_health_v1"
32-
"k8s.io/client-go/rest"
33-
"k8s.io/component-base/metrics/legacyregistry"
3428
ctrl "sigs.k8s.io/controller-runtime"
3529
"sigs.k8s.io/controller-runtime/pkg/log/zap"
3630
"sigs.k8s.io/controller-runtime/pkg/manager"
3731
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
32+
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
33+
3834
"sigs.k8s.io/gateway-api-inference-extension/internal/runnable"
3935
runserver "sigs.k8s.io/gateway-api-inference-extension/pkg/bbr/server"
4036
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metrics"
@@ -50,9 +46,8 @@ var (
5046
"grpcHealthPort",
5147
9005,
5248
"The port used for gRPC liveness and readiness probes")
53-
metricsPort = flag.Int(
54-
"metricsPort", 9090, "The metrics port")
55-
streaming = flag.Bool(
49+
metricsAddr = flag.String("metrics-bind-address", ":9090", "The address the metric endpoint binds to.")
50+
streaming = flag.Bool(
5651
"streaming", false, "Enables streaming support for Envoy full-duplex streaming mode")
5752
logVerbosity = flag.Int("v", logging.DEFAULT, "number for the log level verbosity")
5853

@@ -85,7 +80,18 @@ func run() error {
8580
return err
8681
}
8782

88-
mgr, err := ctrl.NewManager(cfg, ctrl.Options{})
83+
metrics.Register()
84+
85+
// Register metrics handler.
86+
// Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
87+
// More info:
88+
// - https://pkg.go.dev/sigs.k8s.io/[email protected]/pkg/metrics/server
89+
// - https://book.kubebuilder.io/reference/metrics.html
90+
metricsServerOptions := metricsserver.Options{
91+
BindAddress: *metricsAddr,
92+
FilterProvider: filters.WithAuthenticationAndAuthorization,
93+
}
94+
mgr, err := ctrl.NewManager(cfg, ctrl.Options{Metrics: metricsServerOptions})
8995
if err != nil {
9096
setupLog.Error(err, "Failed to create manager", "config", cfg)
9197
return err
@@ -107,11 +113,6 @@ func run() error {
107113
return err
108114
}
109115

110-
// Register metrics handler.
111-
if err := registerMetricsHandler(mgr, *metricsPort, cfg); err != nil {
112-
return err
113-
}
114-
115116
// Start the manager. This blocks until a signal is received.
116117
setupLog.Info("Manager starting")
117118
if err := mgr.Start(ctx); err != nil {
@@ -152,58 +153,3 @@ func initLogging(opts *zap.Options) {
152153
logger := zap.New(zap.UseFlagOptions(opts), zap.RawZapOpts(uberzap.AddCaller()))
153154
ctrl.SetLogger(logger)
154155
}
155-
156-
const metricsEndpoint = "/metrics"
157-
158-
// registerMetricsHandler adds the metrics HTTP handler as a Runnable to the given manager.
159-
func registerMetricsHandler(mgr manager.Manager, port int, cfg *rest.Config) error {
160-
metrics.Register()
161-
162-
// Init HTTP server.
163-
h, err := metricsHandlerWithAuthenticationAndAuthorization(cfg)
164-
if err != nil {
165-
return err
166-
}
167-
168-
mux := http.NewServeMux()
169-
mux.Handle(metricsEndpoint, h)
170-
171-
srv := &http.Server{
172-
Addr: net.JoinHostPort("", strconv.Itoa(port)),
173-
Handler: mux,
174-
}
175-
176-
if err := mgr.Add(&manager.Server{
177-
Name: "metrics",
178-
Server: srv,
179-
}); err != nil {
180-
setupLog.Error(err, "Failed to register metrics HTTP handler")
181-
return err
182-
}
183-
return nil
184-
}
185-
186-
func metricsHandlerWithAuthenticationAndAuthorization(cfg *rest.Config) (http.Handler, error) {
187-
h := promhttp.HandlerFor(
188-
legacyregistry.DefaultGatherer,
189-
promhttp.HandlerOpts{},
190-
)
191-
httpClient, err := rest.HTTPClientFor(cfg)
192-
if err != nil {
193-
setupLog.Error(err, "Failed to create http client for metrics auth")
194-
return nil, err
195-
}
196-
197-
filter, err := filters.WithAuthenticationAndAuthorization(cfg, httpClient)
198-
if err != nil {
199-
setupLog.Error(err, "Failed to create metrics filter for auth")
200-
return nil, err
201-
}
202-
metricsLogger := ctrl.Log.WithName("metrics").WithValues("path", metricsEndpoint)
203-
metricsAuthHandler, err := filter(metricsLogger, h)
204-
if err != nil {
205-
setupLog.Error(err, "Failed to create metrics auth handler")
206-
return nil, err
207-
}
208-
return metricsAuthHandler, nil
209-
}

pkg/bbr/handlers/request_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ import (
2626
extProcPb "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3"
2727
"github.com/google/go-cmp/cmp"
2828
"google.golang.org/protobuf/testing/protocmp"
29-
"k8s.io/component-base/metrics/legacyregistry"
3029
metricsutils "k8s.io/component-base/metrics/testutil"
30+
crmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
3131
"sigs.k8s.io/gateway-api-inference-extension/pkg/bbr/metrics"
3232
logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
3333
)
@@ -204,7 +204,7 @@ func TestHandleRequestBody(t *testing.T) {
204204
bbr_success_total{} 1
205205
`
206206

207-
if err := metricsutils.GatherAndCompare(legacyregistry.DefaultGatherer, strings.NewReader(wantMetrics), "inference_model_request_total"); err != nil {
207+
if err := metricsutils.GatherAndCompare(crmetrics.Registry, strings.NewReader(wantMetrics), "inference_model_request_total"); err != nil {
208208
t.Error(err)
209209
}
210210
}

pkg/bbr/metrics/metrics.go

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,49 +19,45 @@ package metrics
1919
import (
2020
"sync"
2121

22-
compbasemetrics "k8s.io/component-base/metrics"
23-
"k8s.io/component-base/metrics/legacyregistry"
22+
"github.com/prometheus/client_golang/prometheus"
23+
"sigs.k8s.io/controller-runtime/pkg/metrics"
2424
)
2525

2626
const component = "bbr"
2727

2828
var (
29-
successCounter = compbasemetrics.NewCounterVec(
30-
&compbasemetrics.CounterOpts{
31-
Subsystem: component,
32-
Name: "success_total",
33-
Help: "Count of successes pulling model name from body and injecting it in the request headers.",
34-
StabilityLevel: compbasemetrics.ALPHA,
29+
successCounter = prometheus.NewCounterVec(
30+
prometheus.CounterOpts{
31+
Subsystem: component,
32+
Name: "success_total",
33+
Help: "Count of successes pulling model name from body and injecting it in the request headers.",
3534
},
3635
[]string{},
3736
)
38-
modelNotInBodyCounter = compbasemetrics.NewCounterVec(
39-
&compbasemetrics.CounterOpts{
40-
Subsystem: component,
41-
Name: "model_not_in_body_total",
42-
Help: "Count of times the model was not present in the request body.",
43-
StabilityLevel: compbasemetrics.ALPHA,
37+
modelNotInBodyCounter = prometheus.NewCounterVec(
38+
prometheus.CounterOpts{
39+
Subsystem: component,
40+
Name: "model_not_in_body_total",
41+
Help: "Count of times the model was not present in the request body.",
4442
},
4543
[]string{},
4644
)
47-
modelNotParsedCounter = compbasemetrics.NewCounterVec(
48-
&compbasemetrics.CounterOpts{
49-
Subsystem: component,
50-
Name: "model_not_parsed_total",
51-
Help: "Count of times the model was in the request body but we could not parse it.",
52-
StabilityLevel: compbasemetrics.ALPHA,
45+
modelNotParsedCounter = prometheus.NewCounterVec(
46+
prometheus.CounterOpts{
47+
Subsystem: component,
48+
Name: "model_not_parsed_total",
49+
Help: "Count of times the model was in the request body but we could not parse it.",
5350
},
5451
[]string{},
5552
)
5653

5754
// TODO: Uncomment and use this metrics once the core server implementation has handling to skip body parsing if header exists.
5855
/*
59-
modelAlreadyPresentInHeaderCounter = compbasemetrics.NewCounterVec(
60-
&compbasemetrics.CounterOpts{
56+
modelAlreadyPresentInHeaderCounter = prometheus.NewCounterVec(
57+
prometheus.CounterOpts{
6158
Subsystem: component,
6259
Name: "model_already_present_in_header_total",
6360
Help: "Count of times the model was already present in request headers.",
64-
StabilityLevel: compbasemetrics.ALPHA,
6561
},
6662
[]string{},
6763
)
@@ -73,10 +69,10 @@ var registerMetrics sync.Once
7369
// Register all metrics.
7470
func Register() {
7571
registerMetrics.Do(func() {
76-
legacyregistry.MustRegister(successCounter)
77-
legacyregistry.MustRegister(modelNotInBodyCounter)
78-
legacyregistry.MustRegister(modelNotParsedCounter)
79-
// legacyregistry.MustRegister(modelAlreadyPresentInHeaderCounter)
72+
metrics.Registry.MustRegister(successCounter)
73+
metrics.Registry.MustRegister(modelNotInBodyCounter)
74+
metrics.Registry.MustRegister(modelNotParsedCounter)
75+
// metrics.Registry.MustRegister(modelAlreadyPresentInHeaderCounter)
8076
})
8177
}
8278

0 commit comments

Comments
 (0)