Skip to content

Commit dfa4855

Browse files
feat: when using unix socket allow serving monitoring on http (#4445)
Kubernetes for example only supports health checking via http not using sockets, same goes for most prometheus scrapers.
1 parent 21fdd5d commit dfa4855

File tree

4 files changed

+100
-10
lines changed

4 files changed

+100
-10
lines changed

cmd/relayproxy/api/server.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,12 @@ func (s *Server) startUnixSocketServer(ctx context.Context) {
143143
}
144144
}
145145

146+
// Start a http server for monitoring if monitoringport is configured
147+
if s.monitoringEcho != nil && s.config.GetMonitoringPort(s.zapLog) > 0 {
148+
go s.startMonitoringServer()
149+
defer func() { _ = s.monitoringEcho.Close() }()
150+
}
151+
146152
lc := net.ListenConfig{}
147153
listener, err := lc.Listen(ctx, "unix", socketPath)
148154
if err != nil {
@@ -171,16 +177,7 @@ func (s *Server) startUnixSocketServer(ctx context.Context) {
171177
func (s *Server) startAsHTTPServer() {
172178
// starting the monitoring server on a different port if configured
173179
if s.monitoringEcho != nil {
174-
go func() {
175-
addressMonitoring := fmt.Sprintf("%s:%d", s.config.GetServerHost(), s.config.GetMonitoringPort(s.zapLog))
176-
s.zapLog.Info(
177-
"Starting monitoring",
178-
zap.String("address", addressMonitoring))
179-
err := s.monitoringEcho.Start(addressMonitoring)
180-
if err != nil && !errors.Is(err, http.ErrServerClosed) {
181-
s.zapLog.Fatal("Error starting monitoring", zap.Error(err))
182-
}
183-
}()
180+
go s.startMonitoringServer()
184181
defer func() { _ = s.monitoringEcho.Close() }()
185182
}
186183

@@ -196,6 +193,17 @@ func (s *Server) startAsHTTPServer() {
196193
}
197194
}
198195

196+
func (s *Server) startMonitoringServer() {
197+
addressMonitoring := fmt.Sprintf("%s:%d", s.config.GetServerHost(), s.config.GetMonitoringPort(s.zapLog))
198+
s.zapLog.Info(
199+
"Starting monitoring",
200+
zap.String("address", addressMonitoring))
201+
err := s.monitoringEcho.Start(addressMonitoring)
202+
if err != nil && !errors.Is(err, http.ErrServerClosed) {
203+
s.zapLog.Fatal("Error starting monitoring", zap.Error(err))
204+
}
205+
}
206+
199207
// startAwsLambda is starting the relay proxy as an AWS Lambda
200208
func (s *Server) startAwsLambda() {
201209
lambda.Start(s.getLambdaHandler())

cmd/relayproxy/api/server_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,86 @@ func Test_Starting_RelayProxy_UnixSocket(t *testing.T) {
577577
assert.Equal(t, http.StatusOK, responseI.StatusCode)
578578
}
579579

580+
func Test_Starting_RelayProxy_UnixSocket_MonitoringPort(t *testing.T) {
581+
// Create a temporary directory for the socket
582+
tempDir, err := os.MkdirTemp("", "goff-test-socket-*")
583+
require.NoError(t, err)
584+
defer os.RemoveAll(tempDir)
585+
586+
socketPath := filepath.Join(tempDir, "goff-test.sock")
587+
588+
proxyConf := &config.Config{
589+
CommonFlagSet: config.CommonFlagSet{
590+
Retrievers: &[]retrieverconf.RetrieverConf{
591+
{
592+
Kind: "file",
593+
Path: "../../../testdata/flag-config.yaml",
594+
},
595+
},
596+
},
597+
Server: config.Server{
598+
Mode: config.ServerModeUnixSocket,
599+
UnixSocketPath: socketPath,
600+
MonitoringPort: 11026,
601+
},
602+
}
603+
log := log.InitLogger()
604+
defer func() { _ = log.ZapLogger.Sync() }()
605+
606+
metricsV2, err := metric.NewMetrics()
607+
if err != nil {
608+
log.ZapLogger.Error("impossible to initialize prometheus metrics", zap.Error(err))
609+
}
610+
wsService := service.NewWebsocketService()
611+
defer wsService.Close()
612+
prometheusNotifier := metric.NewPrometheusNotifier(metricsV2)
613+
proxyNotifier := service.NewNotifierWebsocket(wsService)
614+
flagsetManager, err := service.NewFlagsetManager(proxyConf, log.ZapLogger, []notifier.Notifier{
615+
prometheusNotifier,
616+
proxyNotifier,
617+
})
618+
require.NoError(t, err)
619+
620+
services := service.Services{
621+
MonitoringService: service.NewMonitoring(flagsetManager),
622+
WebsocketService: wsService,
623+
FlagsetManager: flagsetManager,
624+
Metrics: metricsV2,
625+
}
626+
627+
s := api.New(proxyConf, services, log.ZapLogger)
628+
go func() { s.StartWithContext(context.Background()) }()
629+
defer s.Stop(context.Background())
630+
631+
// Wait for the socket to be created
632+
require.Eventually(t, func() bool {
633+
_, err := os.Stat(socketPath)
634+
return err == nil
635+
}, 1*time.Second, 10*time.Millisecond, "unix socket file was not created in time")
636+
637+
// Verify socket file exists
638+
_, err = os.Stat(socketPath)
639+
assert.NoError(t, err, "Unix socket file should exist")
640+
641+
// Test health endpoint
642+
responseH1, err := http.Get("http://localhost:11026/health")
643+
assert.NoError(t, err)
644+
defer responseH1.Body.Close()
645+
assert.Equal(t, http.StatusOK, responseH1.StatusCode)
646+
647+
// Test metrics endpoint
648+
responseM1, err := http.Get("http://localhost:11026/metrics")
649+
assert.NoError(t, err)
650+
defer responseM1.Body.Close()
651+
assert.Equal(t, http.StatusOK, responseM1.StatusCode)
652+
653+
// Test info endpoint
654+
responseI, err := http.Get("http://localhost:11026/info")
655+
assert.NoError(t, err)
656+
defer responseI.Body.Close()
657+
assert.Equal(t, http.StatusOK, responseI.StatusCode)
658+
}
659+
580660
func Test_Starting_RelayProxy_UnixSocket_OFREP_API(t *testing.T) {
581661
// Create a temporary directory for the socket
582662
tempDir, err := os.MkdirTemp("", "goff-test-socket-*")

cmd/relayproxy/testdata/config/valid-file.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
server:
22
mode: http
33
port: 1031
4+
45
pollingInterval: 1000
56
startWithRetrieverError: false
67
retriever:

website/docs/relay-proxy/configure-relay-proxy.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,7 @@ The execution mode of the relay proxy, you can choose to start the relay-proxy i
492492
#### `server.unixSocketPath`
493493

494494
The path where the Unix socket file will be created when the relay proxy is started in `unixsocket` mode.
495+
If used in combination with `server.monitoringPort` monitoring endpoints will be served via http on the provided port.
495496

496497
- option name: `unixSocketPath`
497498
- type: **string**

0 commit comments

Comments
 (0)