@@ -150,125 +150,149 @@ async fn run_app(hostname: String, port: u16, opts: Options) -> std::io::Result<
150150 fields : Mutex :: new ( HashMap :: new ( ) ) ,
151151 } ) ;
152152
153- info ! ( "Sumo Logic Mock is listening on 0.0.0.0:{}!" , port) ;
154- let result = actix_web:: HttpServer :: new ( move || {
155- actix_web:: App :: new ( )
156- // Middleware printing headers for all handlers.
157- // For a more robust middleware implementation (in its own type)
158- // one can take a look at https://actix.rs/docs/middleware/
159- . wrap_fn ( move |req, srv| {
160- if opts. print . headers {
161- let headers = req. headers ( ) ;
153+ let create_app = {
154+ let app_state = app_state. clone ( ) ;
155+ let app_metadata = app_metadata. clone ( ) ;
156+ let terraform_state = terraform_state. clone ( ) ;
157+ let opts = opts. clone ( ) ;
162158
163- router:: print_request_headers ( req. method ( ) , req. version ( ) , req. uri ( ) , headers) ;
164- }
159+ move || {
160+ actix_web:: App :: new ( )
161+ // Middleware printing headers for all handlers.
162+ // For a more robust middleware implementation (in its own type)
163+ // one can take a look at https://actix.rs/docs/middleware/
164+ . wrap_fn ( move |req, srv| {
165+ if opts. print . headers {
166+ let headers = req. headers ( ) ;
167+
168+ router:: print_request_headers ( req. method ( ) , req. version ( ) , req. uri ( ) , headers) ;
169+ }
170+
171+ thread:: sleep ( opts. delay_time ) ;
165172
166- thread:: sleep ( opts. delay_time ) ;
173+ actix_web:: dev:: Service :: call ( & srv, req)
174+ } )
175+ . app_data ( app_state. clone ( ) ) // Mutable shared state
176+ . app_data ( web:: Data :: new ( opts. clone ( ) ) )
177+ . route (
178+ "/spans-list" ,
179+ web:: get ( ) . to ( router:: traces_data:: handler_get_spans) ,
180+ )
181+ . route (
182+ "/traces-list" ,
183+ web:: get ( ) . to ( router:: traces_data:: handler_get_traces) ,
184+ )
185+ . route (
186+ "/metrics-reset" ,
187+ web:: post ( ) . to ( router:: metrics_data:: handler_metrics_reset) ,
188+ )
189+ . route (
190+ "/metrics-list" ,
191+ web:: get ( ) . to ( router:: metrics_data:: handler_metrics_list) ,
192+ )
193+ . route (
194+ "/metrics-ips" ,
195+ web:: get ( ) . to ( router:: metrics_data:: handler_metrics_ips) ,
196+ )
197+ . route (
198+ "/metrics-samples" ,
199+ web:: get ( ) . to ( router:: metrics_data:: handler_metrics_samples) ,
200+ )
201+ . route ( "/metrics" , web:: get ( ) . to ( router:: handler_metrics) )
202+ . route ( "/logs/count" , web:: get ( ) . to ( router:: handler_logs_count) )
203+ . service (
204+ web:: scope ( "/api/v1" )
205+ . route (
206+ "/collector/register" ,
207+ web:: post ( ) . to ( router:: api:: v1:: handler_collector_register) ,
208+ )
209+ . route (
210+ "/collector/heartbeat" ,
211+ web:: post ( ) . to ( router:: api:: v1:: handler_collector_heartbeat) ,
212+ )
213+ . route (
214+ "/otCollectors/metadata" ,
215+ web:: post ( ) . to ( router:: api:: v1:: handler_collector_metadata) ,
216+ )
217+ . route (
218+ "/collector/logs" ,
219+ web:: post ( ) . to ( router:: otlp:: handler_receiver_otlp_logs) ,
220+ )
221+ . route (
222+ "/collector/metrics" ,
223+ web:: post ( ) . to ( router:: otlp:: handler_receiver_otlp_metrics) ,
224+ )
225+ . route (
226+ "/collector/traces" ,
227+ web:: post ( ) . to ( router:: otlp:: handler_receiver_otlp_traces) ,
228+ ) ,
229+ )
230+ . service (
231+ web:: scope ( "/terraform" )
232+ . app_data ( app_metadata. clone ( ) )
233+ . app_data ( terraform_state. clone ( ) )
234+ . route (
235+ "/api/v1/fields/quota" ,
236+ web:: get ( ) . to ( router:: terraform:: handler_terraform_fields_quota) ,
237+ )
238+ . route (
239+ "/api/v1/fields/{field}" ,
240+ web:: get ( ) . to ( router:: terraform:: handler_terraform_field) ,
241+ )
242+ . route (
243+ "/api/v1/fields" ,
244+ web:: get ( ) . to ( router:: terraform:: handler_terraform_fields) ,
245+ )
246+ . route (
247+ "/api/v1/fields" ,
248+ web:: post ( ) . to ( router:: terraform:: handler_terraform_fields_create) ,
249+ )
250+ . default_service ( web:: get ( ) . to ( router:: terraform:: handler_terraform) ) ,
251+ )
252+ . route ( "/dump" , web:: post ( ) . to ( router:: handler_dump) )
253+ // OTLP
254+ . service (
255+ web:: scope ( "/receiver/v1" )
256+ . route (
257+ "/logs" ,
258+ web:: post ( ) . to ( router:: otlp:: handler_receiver_otlp_logs) ,
259+ )
260+ . route (
261+ "/metrics" ,
262+ web:: post ( ) . to ( router:: otlp:: handler_receiver_otlp_metrics) ,
263+ )
264+ . route (
265+ "/traces" ,
266+ web:: post ( ) . to ( router:: otlp:: handler_receiver_otlp_traces) ,
267+ ) ,
268+ )
269+ // Treat every other url as receiver endpoint
270+ . default_service ( web:: get ( ) . to ( router:: handler_receiver) )
271+ // Set metrics payload limit to 100MB
272+ . app_data ( web:: PayloadConfig :: default ( ) . limit ( 100 * 2 << 20 ) )
273+ }
274+ } ;
167275
168- actix_web:: dev:: Service :: call ( & srv, req)
169- } )
170- . app_data ( app_state. clone ( ) ) // Mutable shared state
171- . app_data ( web:: Data :: new ( opts. clone ( ) ) )
172- . route (
173- "/spans-list" ,
174- web:: get ( ) . to ( router:: traces_data:: handler_get_spans) ,
175- )
176- . route (
177- "/traces-list" ,
178- web:: get ( ) . to ( router:: traces_data:: handler_get_traces) ,
179- )
180- . route (
181- "/metrics-reset" ,
182- web:: post ( ) . to ( router:: metrics_data:: handler_metrics_reset) ,
183- )
184- . route (
185- "/metrics-list" ,
186- web:: get ( ) . to ( router:: metrics_data:: handler_metrics_list) ,
187- )
188- . route (
189- "/metrics-ips" ,
190- web:: get ( ) . to ( router:: metrics_data:: handler_metrics_ips) ,
191- )
192- . route (
193- "/metrics-samples" ,
194- web:: get ( ) . to ( router:: metrics_data:: handler_metrics_samples) ,
195- )
196- . route ( "/metrics" , web:: get ( ) . to ( router:: handler_metrics) )
197- . route ( "/logs/count" , web:: get ( ) . to ( router:: handler_logs_count) )
198- . service (
199- web:: scope ( "/api/v1" )
200- . route (
201- "/collector/register" ,
202- web:: post ( ) . to ( router:: api:: v1:: handler_collector_register) ,
203- )
204- . route (
205- "/collector/heartbeat" ,
206- web:: post ( ) . to ( router:: api:: v1:: handler_collector_heartbeat) ,
207- )
208- . route (
209- "/otCollectors/metadata" ,
210- web:: post ( ) . to ( router:: api:: v1:: handler_collector_metadata) ,
211- )
212- . route (
213- "/collector/logs" ,
214- web:: post ( ) . to ( router:: otlp:: handler_receiver_otlp_logs) ,
215- )
216- . route (
217- "/collector/metrics" ,
218- web:: post ( ) . to ( router:: otlp:: handler_receiver_otlp_metrics) ,
219- )
220- . route (
221- "/collector/traces" ,
222- web:: post ( ) . to ( router:: otlp:: handler_receiver_otlp_traces) ,
223- ) ,
224- )
225- . service (
226- web:: scope ( "/terraform" )
227- . app_data ( app_metadata. clone ( ) )
228- . app_data ( terraform_state. clone ( ) )
229- . route (
230- "/api/v1/fields/quota" ,
231- web:: get ( ) . to ( router:: terraform:: handler_terraform_fields_quota) ,
232- )
233- . route (
234- "/api/v1/fields/{field}" ,
235- web:: get ( ) . to ( router:: terraform:: handler_terraform_field) ,
236- )
237- . route (
238- "/api/v1/fields" ,
239- web:: get ( ) . to ( router:: terraform:: handler_terraform_fields) ,
240- )
241- . route (
242- "/api/v1/fields" ,
243- web:: post ( ) . to ( router:: terraform:: handler_terraform_fields_create) ,
244- )
245- . default_service ( web:: get ( ) . to ( router:: terraform:: handler_terraform) ) ,
246- )
247- . route ( "/dump" , web:: post ( ) . to ( router:: handler_dump) )
248- // OTLP
249- . service (
250- web:: scope ( "/receiver/v1" )
251- . route (
252- "/logs" ,
253- web:: post ( ) . to ( router:: otlp:: handler_receiver_otlp_logs) ,
254- )
255- . route (
256- "/metrics" ,
257- web:: post ( ) . to ( router:: otlp:: handler_receiver_otlp_metrics) ,
258- )
259- . route (
260- "/traces" ,
261- web:: post ( ) . to ( router:: otlp:: handler_receiver_otlp_traces) ,
262- ) ,
263- )
264- // Treat every other url as receiver endpoint
265- . default_service ( web:: get ( ) . to ( router:: handler_receiver) )
266- // Set metrics payload limit to 100MB
267- . app_data ( web:: PayloadConfig :: default ( ) . limit ( 100 * 2 << 20 ) )
268- } )
269- . bind ( format ! ( "0.0.0.0:{}" , port) ) ?
270- . run ( )
271- . await ;
276+ // Try to bind to [::] first, fallback to IPv4 if it fails
277+ let result = match actix_web:: HttpServer :: new ( create_app. clone ( ) ) . bind ( format ! ( "[::]:{}" , port) ) {
278+ Ok ( server) => {
279+ info ! ( "Sumo Logic Mock is listening on [::]:{}!" , port) ;
280+ server. run ( ) . await
281+ }
282+ Err ( _) => {
283+ info ! ( "Failed to bind to [::], falling back to 0.0.0.0:{}" , port) ;
284+ match actix_web:: HttpServer :: new ( create_app) . bind ( format ! ( "0.0.0.0:{}" , port) ) {
285+ Ok ( server) => {
286+ info ! ( "Sumo Logic Mock is listening on 0.0.0.0:{}!" , port) ;
287+ server. run ( ) . await
288+ }
289+ Err ( e) => {
290+ error ! ( "Failed to bind to both [::] and 0.0.0.0: {}" , e) ;
291+ return Err ( e) ;
292+ }
293+ }
294+ }
295+ } ;
272296
273297 match result {
274298 Ok ( result) => Ok ( result) ,
0 commit comments