@@ -5,8 +5,10 @@ import (
55 "binance-proxy/internal/logcache"
66 "binance-proxy/internal/service"
77 "context"
8+ "errors"
89 "fmt"
910 stdlog "log"
11+ "log/slog"
1012 "net/http"
1113 "os"
1214 "os/signal"
@@ -16,13 +18,12 @@ import (
1618 _ "net/http/pprof"
1719
1820 "github.com/jessevdk/go-flags"
19- log "github.com/sirupsen/logrus"
2021)
2122
22- func startProxy (ctx context.Context , port int , class service.Class , disablefakekline bool , alwaysshowforwards bool ) {
23+ func startProxy (ctx context.Context , logger * slog. Logger , bd * service. BanDetector , port int , class service.Class , disablefakekline bool , alwaysshowforwards bool , errChan chan <- error ) {
2324 mux := http .NewServeMux ()
2425 address := fmt .Sprintf (":%d" , port )
25- mux .HandleFunc ("/" , handler .NewHandler (ctx , class , ! disablefakekline , alwaysshowforwards ))
26+ mux .HandleFunc ("/" , handler .NewHandler (ctx , logger , bd , class , ! disablefakekline , alwaysshowforwards ))
2627
2728 // Create an HTTP server with a custom ErrorLog that suppresses repeated lines
2829 srv := & http.Server {
@@ -38,9 +39,10 @@ func startProxy(ctx context.Context, port int, class service.Class, disablefakek
3839 ),
3940 }
4041
41- log .Infof ("%s websocket proxy starting on port %d." , class , port )
42- if err := srv .ListenAndServe (); err != nil {
43- log .Fatalf ("%s websocket proxy start failed (error: %s)." , class , err )
42+ logger .Info ("websocket proxy starting" , "class" , class , "port" , port )
43+ if err := srv .ListenAndServe (); err != nil && err != http .ErrServerClosed {
44+ logger .Error ("websocket proxy start failed" , "class" , class , "error" , err )
45+ errChan <- fmt .Errorf ("%s proxy failed: %w" , class , err )
4446 }
4547}
4648
@@ -74,75 +76,93 @@ var (
7476)
7577
7678func main () {
77- log .SetFormatter (& log.TextFormatter {
78- DisableColors : true ,
79- FullTimestamp : true ,
80- })
79+ logger := slog .New (slog .NewTextHandler (os .Stdout , & slog.HandlerOptions {Level : slog .LevelInfo }))
80+ slog .SetDefault (logger )
8181
82- // Route logcache output through logrus for consistent formatting/levels
8382 logcache .SetLoggerHook (func (level , msg string ) {
8483 switch level {
8584 case "warn" :
86- log .Warn (msg )
85+ logger .Warn (msg )
8786 case "error" :
88- log .Error (msg )
87+ logger .Error (msg )
8988 case "info" :
90- log .Info (msg )
89+ logger .Info (msg )
9190 default :
92- log . Print (msg )
91+ logger . Info (msg )
9392 }
9493 })
9594 logcache .SetWriterHook (func (msg string ) {
9695 // net/http ErrorLog messages typically include trailing newlines
9796 if len (msg ) > 0 && msg [len (msg )- 1 ] == '\n' {
9897 msg = msg [:len (msg )- 1 ]
9998 }
100- log .Warnf ("http: %s" , msg )
99+
100+ logger .Warn ("http request" , "msg" , msg )
101101 })
102102
103- log . Infof ("Binance proxy version %s, build time %s" , Version , Buildtime )
103+ logger . Info ("Binance proxy version" , "version" , Version , "build" , Buildtime )
104104
105105 if _ , err := parser .Parse (); err != nil {
106106 if flagsErr , ok := err .(* flags.Error ); ok && flagsErr .Type == flags .ErrHelp {
107107 os .Exit (0 )
108108 } else {
109- log . Fatalf ( "%s - %s " , err , flagsErr .Type )
109+ logger . Error ( "failed parsing flags " , "error" , err , "type" , flagsErr .Type )
110110 }
111111 }
112-
113- if len (config .Verbose ) >= 2 {
114- log .SetLevel (log .TraceLevel )
115- } else if len (config .Verbose ) == 1 {
116- log .SetLevel (log .DebugLevel )
117- } else {
118- log .SetLevel (log .InfoLevel )
119- }
120-
121- if log .GetLevel () > log .InfoLevel {
122- log .Infof ("Set level to %s" , log .GetLevel ())
123- }
124-
125112 if config .DisableSpot && config .DisableFutures {
126- log .Fatal ("can't start if both SPOT and FUTURES are disabled!" )
113+ logger .Error ("can't start if both SPOT and FUTURES are disabled!" )
114+ os .Exit (1 )
127115 }
128116
129117 if ! config .DisableFakeKline {
130- log . Infof ("Fake candles are enabled for faster processing, the feature can be disabled with --disable-fake-candles or -c" )
118+ logger . Info ("Fake candles are enabled for faster processing, the feature can be disabled with --disable-fake-candles or -c" )
131119 }
132120
133121 if config .AlwaysShowForwards {
134- log . Infof ("Always show forwards is enabled, all API requests, that can't be served from websockets cached will be logged." )
122+ logger . Info ("Always show forwards is enabled, all API requests, that can't be served from websockets cached will be logged." )
135123 }
136124
137125 go handleSignal ()
138126
127+ // Channel to collect errors from proxy goroutines
128+ errChan := make (chan error , 2 ) // Buffer for up to 2 proxies
129+ var proxyCount int
130+
131+ banDetector := service .NewBanDetector (logger )
132+
139133 if ! config .DisableSpot {
140- go startProxy (ctx , config .SpotAddress , service .SPOT , config .DisableFakeKline , config .AlwaysShowForwards )
134+ proxyCount ++
135+ go startProxy (ctx , logger , banDetector , config .SpotAddress , service .SPOT , config .DisableFakeKline , config .AlwaysShowForwards , errChan )
141136 }
137+
142138 if ! config .DisableFutures {
143- go startProxy (ctx , config .FuturesAddress , service .FUTURES , config .DisableFakeKline , config .AlwaysShowForwards )
139+ proxyCount ++
140+ go startProxy (ctx , logger , banDetector , config .FuturesAddress , service .FUTURES , config .DisableFakeKline , config .AlwaysShowForwards , errChan )
144141 }
145- <- ctx .Done ()
146142
147- log .Info ("SIGINT received, aborting ..." )
143+ // Wait for either context cancellation or errors from proxies
144+ var collectedErrors []error
145+ done := false
146+
147+ for ! done {
148+ select {
149+ case <- ctx .Done ():
150+ logger .Info ("SIGINT received, aborting ..." )
151+ done = true
152+ case err := <- errChan :
153+ if err != nil {
154+ collectedErrors = append (collectedErrors , err )
155+ // If all proxies have failed, exit
156+ if len (collectedErrors ) >= proxyCount {
157+ done = true
158+ }
159+ }
160+ }
161+ }
162+
163+ // Log any collected errors
164+ if len (collectedErrors ) > 0 {
165+ combinedErr := errors .Join (collectedErrors ... )
166+ logger .Error ("Proxy errors occurred" , "error" , combinedErr )
167+ }
148168}
0 commit comments