@@ -29,21 +29,13 @@ var gatewayCmd = &cobra.Command{
2929 return fmt .Errorf ("failed to setup logger: %w" , err )
3030 }
3131
32- log .Info ().Str ("LogLevel" , log .GetLevel ().String ()).Msg ("Starting server..." )
32+ log .Info ().Str ("LogLevel" , log .GetLevel ().String ()).Msg ("Starting gateway server..." )
3333
3434 ctx , _ , shutdown := openmfpcontext .StartContext (log , appCfg , 1 * time .Second )
3535 defer shutdown ()
3636
37- if defaultCfg .Sentry .Dsn != "" {
38- err := sentry .Start (ctx ,
39- defaultCfg .Sentry .Dsn , defaultCfg .Environment , defaultCfg .Region ,
40- defaultCfg .Image .Name , defaultCfg .Image .Tag ,
41- )
42- if err != nil {
43- log .Fatal ().Err (err ).Msg ("Sentry init failed" )
44- }
45-
46- defer openmfpcontext .Recover (log )
37+ if err := initializeSentry (ctx , log ); err != nil {
38+ return err
4739 }
4840
4941 ctrl .SetLogger (log .Logr ())
@@ -54,78 +46,148 @@ var gatewayCmd = &cobra.Command{
5446 return fmt .Errorf ("failed to create gateway: %w" , err )
5547 }
5648
57- // Initialize tracing provider
58- var providerShutdown func (ctx context.Context ) error
59- if defaultCfg .Tracing .Enabled {
60- providerShutdown , err = traces .InitProvider (ctx , defaultCfg .Tracing .Collector )
61- if err != nil {
62- log .Fatal ().Err (err ).Msg ("unable to start gRPC-Sidecar TracerProvider" )
63- }
64- } else {
65- providerShutdown , err = traces .InitLocalProvider (ctx , defaultCfg .Tracing .Collector , false )
66- if err != nil {
67- log .Fatal ().Err (err ).Msg ("unable to start local TracerProvider" )
68- }
49+ tracingShutdown , err := initializeTracing (ctx , log )
50+ if err != nil {
51+ return err
6952 }
70-
7153 defer func () {
72- if err := providerShutdown (ctx ); err != nil {
73- log .Fatal ().Err (err ).Msg ("failed to shutdown TracerProvider" )
54+ if err := tracingShutdown (ctx ); err != nil {
55+ log .Error ().Err (err ).Msg ("failed to shutdown TracerProvider" )
7456 }
7557 }()
7658
77- defer func () {
78- if err := providerShutdown (ctx ); err != nil {
79- log .Fatal ().Err (err ).Msg ("failed to shutdown TracerProvider" )
80- }
81- }()
59+ return runServers (ctx , log , gatewayInstance )
60+ },
61+ }
62+
63+ func initializeSentry (ctx context.Context , log * logger.Logger ) error {
64+ if defaultCfg .Sentry .Dsn == "" {
65+ return nil
66+ }
67+
68+ err := sentry .Start (ctx ,
69+ defaultCfg .Sentry .Dsn , defaultCfg .Environment , defaultCfg .Region ,
70+ defaultCfg .Image .Name , defaultCfg .Image .Tag ,
71+ )
72+ if err != nil {
73+ log .Fatal ().Err (err ).Msg ("Sentry init failed" )
74+ return err
75+ }
76+
77+ defer openmfpcontext .Recover (log )
78+ return nil
79+ }
8280
83- // Set up HTTP handler
84- http .Handle ("/" , gatewayInstance )
85- http .HandleFunc ("/healthz" , func (w http.ResponseWriter , r * http.Request ) {
86- w .WriteHeader (http .StatusOK )
87- })
88- http .HandleFunc ("/readyz" , func (w http.ResponseWriter , r * http.Request ) {
89- w .WriteHeader (http .StatusOK )
90- })
91-
92- // Replace the /metrics endpoint handler
93- http .Handle ("/metrics" , promhttp .Handler ())
94-
95- // Start HTTP server with context
96- server := & http.Server {
97- Addr : fmt .Sprintf (":%s" , appCfg .Gateway .Port ),
98- Handler : nil ,
81+ func initializeTracing (ctx context.Context , log * logger.Logger ) (func (ctx context.Context ) error , error ) {
82+ if defaultCfg .Tracing .Enabled {
83+ shutdown , err := traces .InitProvider (ctx , defaultCfg .Tracing .Collector )
84+ if err != nil {
85+ log .Fatal ().Err (err ).Msg ("unable to start gRPC-Sidecar TracerProvider" )
86+ return nil , err
9987 }
88+ return shutdown , nil
89+ }
90+
91+ shutdown , err := traces .InitLocalProvider (ctx , defaultCfg .Tracing .Collector , false )
92+ if err != nil {
93+ log .Fatal ().Err (err ).Msg ("unable to start local TracerProvider" )
94+ return nil , err
95+ }
96+ return shutdown , nil
97+ }
10098
101- // Start the HTTP server in a goroutine so that we can listen for shutdown signals
102- go func () {
103- err := server .ListenAndServe ()
104- if err != nil && ! errors .Is (err , http .ErrServerClosed ) {
105- log .Error ().Err (err ).Msg ("Error starting HTTP server" )
106- }
107- }()
99+ func createServers (gatewayInstance http.Handler ) (* http.Server , * http.Server , * http.Server ) {
100+ // Main server for GraphQL
101+ mainMux := http .NewServeMux ()
102+ mainMux .Handle ("/" , gatewayInstance )
103+ mainServer := & http.Server {
104+ Addr : fmt .Sprintf (":%s" , appCfg .Gateway .Port ),
105+ Handler : mainMux ,
106+ }
107+
108+ // Metrics server
109+ metricsMux := http .NewServeMux ()
110+ metricsMux .Handle ("/metrics" , promhttp .Handler ())
111+ metricsServer := & http.Server {
112+ Addr : defaultCfg .Metrics .BindAddress ,
113+ Handler : metricsMux ,
114+ }
115+
116+ // Health server
117+ healthMux := http .NewServeMux ()
118+ healthMux .HandleFunc ("/healthz" , func (w http.ResponseWriter , r * http.Request ) {
119+ w .WriteHeader (http .StatusOK )
120+ })
121+ healthMux .HandleFunc ("/readyz" , func (w http.ResponseWriter , r * http.Request ) {
122+ w .WriteHeader (http .StatusOK )
123+ })
124+ healthServer := & http.Server {
125+ Addr : defaultCfg .HealthProbeBindAddress ,
126+ Handler : healthMux ,
127+ }
128+
129+ return mainServer , metricsServer , healthServer
130+ }
131+
132+ func shutdownServers (ctx context.Context , log * logger.Logger , mainServer , metricsServer , healthServer * http.Server ) {
133+ log .Info ().Msg ("Shutting down HTTP servers..." )
108134
109- // Wait for shutdown signal via the context
110- <- ctx .Done ()
135+ if err := mainServer .Shutdown (ctx ); err != nil {
136+ log .Error ().Err (err ).Msg ("Main HTTP server shutdown failed" )
137+ }
111138
112- shutdownCtx , cancel := context .WithTimeout (context .Background (), defaultCfg .ShutdownTimeout ) // ctx is closed, we need a new one
113- defer cancel ()
114- log .Info ().Msg ("Shutting down HTTP server..." )
115- if err := server .Shutdown (shutdownCtx ); err != nil {
116- log .Fatal ().Err (err ).Msg ("HTTP server shutdown failed" )
139+ if err := metricsServer .Shutdown (ctx ); err != nil {
140+ log .Error ().Err (err ).Msg ("Metrics HTTP server shutdown failed" )
141+ }
142+
143+ if err := healthServer .Shutdown (ctx ); err != nil {
144+ log .Error ().Err (err ).Msg ("Health HTTP server shutdown failed" )
145+ }
146+ }
147+
148+ func runServers (ctx context.Context , log * logger.Logger , gatewayInstance http.Handler ) error {
149+ mainServer , metricsServer , healthServer := createServers (gatewayInstance )
150+
151+ // Start main server (GraphQL)
152+ go func () {
153+ log .Info ().Str ("addr" , mainServer .Addr ).Msg ("Starting main HTTP server" )
154+ if err := mainServer .ListenAndServe (); err != nil && ! errors .Is (err , http .ErrServerClosed ) {
155+ log .Error ().Err (err ).Msg ("Error starting main HTTP server" )
117156 }
157+ }()
118158
119- if err := gatewayInstance .Close (); err != nil {
120- log .Error ().Err (err ).Msg ("Error closing gateway services" )
159+ // Start metrics server
160+ go func () {
161+ log .Info ().Str ("addr" , metricsServer .Addr ).Msg ("Starting metrics HTTP server" )
162+ if err := metricsServer .ListenAndServe (); err != nil && ! errors .Is (err , http .ErrServerClosed ) {
163+ log .Error ().Err (err ).Msg ("Error starting metrics HTTP server" )
121164 }
165+ }()
122166
123- // Call the shutdown cleanup
124- shutdown ()
167+ // Start health server
168+ go func () {
169+ log .Info ().Str ("addr" , healthServer .Addr ).Msg ("Starting health HTTP server" )
170+ if err := healthServer .ListenAndServe (); err != nil && ! errors .Is (err , http .ErrServerClosed ) {
171+ log .Error ().Err (err ).Msg ("Error starting health HTTP server" )
172+ }
173+ }()
125174
126- log .Info ().Msg ("Server shut down successfully" )
127- return nil
128- },
175+ // Wait for shutdown signal
176+ <- ctx .Done ()
177+
178+ shutdownCtx , cancel := context .WithTimeout (context .Background (), defaultCfg .ShutdownTimeout )
179+ defer cancel ()
180+
181+ shutdownServers (shutdownCtx , log , mainServer , metricsServer , healthServer )
182+
183+ if closer , ok := gatewayInstance .(interface { Close () error }); ok {
184+ if err := closer .Close (); err != nil {
185+ log .Error ().Err (err ).Msg ("Error closing gateway services" )
186+ }
187+ }
188+
189+ log .Info ().Msg ("Server shut down successfully" )
190+ return nil
129191}
130192
131193// setupLogger initializes the logger with the given log level
0 commit comments