@@ -18,18 +18,26 @@ package main
18
18
19
19
import (
20
20
"flag"
21
+ "net"
22
+ "net/http"
21
23
"os"
24
+ "strconv"
22
25
23
26
"github.com/go-logr/logr"
27
+ "github.com/prometheus/client_golang/prometheus/promhttp"
24
28
uberzap "go.uber.org/zap"
25
29
"go.uber.org/zap/zapcore"
26
30
"google.golang.org/grpc"
27
31
healthPb "google.golang.org/grpc/health/grpc_health_v1"
32
+ "k8s.io/client-go/rest"
33
+ "k8s.io/component-base/metrics/legacyregistry"
28
34
ctrl "sigs.k8s.io/controller-runtime"
29
35
"sigs.k8s.io/controller-runtime/pkg/log/zap"
30
36
"sigs.k8s.io/controller-runtime/pkg/manager"
37
+ "sigs.k8s.io/controller-runtime/pkg/metrics/filters"
31
38
"sigs.k8s.io/gateway-api-inference-extension/internal/runnable"
32
39
runserver "sigs.k8s.io/gateway-api-inference-extension/pkg/body-based-routing/server"
40
+ "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metrics"
33
41
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
34
42
)
35
43
42
50
"grpcHealthPort" ,
43
51
9003 ,
44
52
"The port used for gRPC liveness and readiness probes" )
53
+ metricsPort = flag .Int (
54
+ "metricsPort" , 9090 , "The metrics port" )
45
55
logVerbosity = flag .Int ("v" , logging .DEFAULT , "number for the log level verbosity" )
46
56
47
57
setupLog = ctrl .Log .WithName ("setup" )
@@ -95,6 +105,11 @@ func run() error {
95
105
return err
96
106
}
97
107
108
+ // Register metrics handler.
109
+ if err := registerMetricsHandler (mgr , * metricsPort , cfg ); err != nil {
110
+ return err
111
+ }
112
+
98
113
// Start the manager. This blocks until a signal is received.
99
114
setupLog .Info ("Manager starting" )
100
115
if err := mgr .Start (ctx ); err != nil {
@@ -135,3 +150,58 @@ func initLogging(opts *zap.Options) {
135
150
logger := zap .New (zap .UseFlagOptions (opts ), zap .RawZapOpts (uberzap .AddCaller ()))
136
151
ctrl .SetLogger (logger )
137
152
}
153
+
154
+ const metricsEndpoint = "/metrics"
155
+
156
+ // registerMetricsHandler adds the metrics HTTP handler as a Runnable to the given manager.
157
+ func registerMetricsHandler (mgr manager.Manager , port int , cfg * rest.Config ) error {
158
+ metrics .Register ()
159
+
160
+ // Init HTTP server.
161
+ h , err := metricsHandlerWithAuthenticationAndAuthorization (cfg )
162
+ if err != nil {
163
+ return err
164
+ }
165
+
166
+ mux := http .NewServeMux ()
167
+ mux .Handle (metricsEndpoint , h )
168
+
169
+ srv := & http.Server {
170
+ Addr : net .JoinHostPort ("" , strconv .Itoa (port )),
171
+ Handler : mux ,
172
+ }
173
+
174
+ if err := mgr .Add (& manager.Server {
175
+ Name : "metrics" ,
176
+ Server : srv ,
177
+ }); err != nil {
178
+ setupLog .Error (err , "Failed to register metrics HTTP handler" )
179
+ return err
180
+ }
181
+ return nil
182
+ }
183
+
184
+ func metricsHandlerWithAuthenticationAndAuthorization (cfg * rest.Config ) (http.Handler , error ) {
185
+ h := promhttp .HandlerFor (
186
+ legacyregistry .DefaultGatherer ,
187
+ promhttp.HandlerOpts {},
188
+ )
189
+ httpClient , err := rest .HTTPClientFor (cfg )
190
+ if err != nil {
191
+ setupLog .Error (err , "Failed to create http client for metrics auth" )
192
+ return nil , err
193
+ }
194
+
195
+ filter , err := filters .WithAuthenticationAndAuthorization (cfg , httpClient )
196
+ if err != nil {
197
+ setupLog .Error (err , "Failed to create metrics filter for auth" )
198
+ return nil , err
199
+ }
200
+ metricsLogger := ctrl .Log .WithName ("metrics" ).WithValues ("path" , metricsEndpoint )
201
+ metricsAuthHandler , err := filter (metricsLogger , h )
202
+ if err != nil {
203
+ setupLog .Error (err , "Failed to create metrics auth handler" )
204
+ return nil , err
205
+ }
206
+ return metricsAuthHandler , nil
207
+ }
0 commit comments