Skip to content

Commit 3fa1300

Browse files
author
ekarlso
committed
Switch to use slog and pass references of services
1 parent 022212d commit 3fa1300

File tree

15 files changed

+268
-186
lines changed

15 files changed

+268
-186
lines changed

Dockerfile

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
1-
# build stage
2-
FROM golang:1.24 AS builder
3-
WORKDIR /app
4-
COPY . .
5-
RUN go mod download
6-
RUN go mod vendor
7-
RUN go mod tidy
8-
RUN CGO_ENABLED=0 go build -o binance-proxy ./cmd/binance-proxy/main.go
9-
10-
# target stage
111
FROM alpine
12-
COPY --from=builder /app/binance-proxy /go/bin/binance-proxy
2+
3+
COPY bin/binance-proxy /binance-proxy
4+
135
EXPOSE 8090
146
EXPOSE 8091
15-
ENTRYPOINT ["/go/bin/binance-proxy"]
7+
8+
ENTRYPOINT ["/binance-proxy"]

Makefile

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ LD_FLAGS := -X main.Version='$(GOLDFLAGS_VERSION)' -X main.Buildtime='$(GOLD
77
SOURCE_FILES ?= ./internal/... ./pkg/... ./cmd/...
88
UNAME := $(uname -s)
99

10+
BIN_DIR := bin
11+
TOOLS_BIN_DIR := $(shell pwd)/$(BIN_DIR)
12+
$(TOOLS_BIN_DIR):
13+
mkdir -p $(TOOLS_BIN_DIR)
14+
15+
GOLANGCI_VER := 2.5.0
16+
GOLANGCI_BIN := golangci
17+
GOLANGCI := $(TOOLS_BIN_DIR)/$(GOLANGCI_BIN)-$(GOLANGCI_VER)
18+
1019
$(info GOLDFLAGS_VERSION=$(GOLDFLAGS_VERSION))
1120
$(info GOLDFLAGS_BUILD_TIME=$(GOLDFLAGS_BUILD_TIME))
1221
$(info LD_FLAGS=$(LD_FLAGS))
@@ -63,7 +72,9 @@ vet: ### Vet
6372

6473
### Lint
6574
.PHONY: lint
66-
lint: fmt vet
75+
lint: $(GOLANGCI) fmt vet
76+
$(GOLANGCI) run -c .golangci.yml -v
77+
6778

6879
### Clean test
6980
.PHONY: test-clean
@@ -77,3 +88,14 @@ test: lint ### Run tests
7788
.PHONY: cover
7889
cover: test ### Run tests and generate coverage
7990
@go tool cover -html=cover.out -o=cover.html
91+
92+
93+
$(GOLANGCI): $(TOOLS_BIN_DIR)
94+
ifeq (,$(wildcard $(GOLANGCI)))
95+
mkdir -p /tmp/golangci && \
96+
cd /tmp/golangci && \
97+
curl -L https://github.com/golangci/golangci-lint/releases/download/v$(GOLANGCI_VER)/golangci-lint-$(GOLANGCI_VER)-linux-amd64.tar.gz -o golangci-lint-$(GOLANGCI_VER)-linux-amd64.tar.gz && \
98+
tar xvf golangci-lint-$(GOLANGCI_VER)-linux-amd64.tar.gz && \
99+
mv golangci-lint-$(GOLANGCI_VER)-linux-amd64/golangci-lint $(GOLANGCI) && \
100+
ln -sf $(GOLANGCI) $(TOOLS_BIN_DIR)/$(GOLANGCI_BIN)
101+
endif

cmd/binance-proxy/main.go

Lines changed: 58 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -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

7678
func 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
}

internal/handler/exchangeinfo.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ func (s *Handler) exchangeInfo(w http.ResponseWriter) {
1313

1414
w.Header().Set("Content-Type", "application/json")
1515
w.Header().Set("Data-Source", "cache")
16+
1617
w.Write(data)
1718
}

0 commit comments

Comments
 (0)