Skip to content

Commit 3c8f347

Browse files
smiratalos-bot
authored andcommitted
feat: provide a way to configure logger for the loadbalancer
It was using `log.Printf` by default which was spamming stdout in Sfyra. Default is still to use same writer as `log` defaults. Signed-off-by: Andrey Smirnov <[email protected]>
1 parent da8e987 commit 3c8f347

File tree

3 files changed

+40
-13
lines changed

3 files changed

+40
-13
lines changed

loadbalancer/loadbalancer.go

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,22 @@ import (
2727
type TCP struct {
2828
tcpproxy.Proxy
2929

30+
Logger *log.Logger
31+
3032
routes map[string]*upstream.List
3133
}
3234

33-
type lbUpstream string
35+
type lbUpstream struct {
36+
upstream string
37+
logger *log.Logger
38+
}
3439

3540
func (upstream lbUpstream) HealthCheck(ctx context.Context) error {
3641
d := net.Dialer{}
3742

38-
c, err := d.DialContext(ctx, "tcp", string(upstream))
43+
c, err := d.DialContext(ctx, "tcp", upstream.upstream)
3944
if err != nil {
40-
log.Printf("healthcheck failed for %q: %s", string(upstream), err)
45+
upstream.logger.Printf("healthcheck failed for %q: %s", upstream.upstream, err)
4146

4247
return err
4348
}
@@ -46,27 +51,28 @@ func (upstream lbUpstream) HealthCheck(ctx context.Context) error {
4651
}
4752

4853
type lbTarget struct {
49-
list *upstream.List
54+
list *upstream.List
55+
logger *log.Logger
5056
}
5157

5258
func (target *lbTarget) HandleConn(conn net.Conn) {
5359
upstreamBackend, err := target.list.Pick()
5460
if err != nil {
55-
log.Printf("no upstreams available, closing connection from %s", conn.RemoteAddr())
61+
target.logger.Printf("no upstreams available, closing connection from %s", conn.RemoteAddr())
5662
conn.Close() //nolint: errcheck
5763

5864
return
5965
}
6066

61-
upstreamAddr := upstreamBackend.(lbUpstream) //nolint: errcheck
67+
upstream := upstreamBackend.(lbUpstream) //nolint: errcheck
6268

63-
log.Printf("proxying connection %s -> %s", conn.RemoteAddr(), string(upstreamAddr))
69+
target.logger.Printf("proxying connection %s -> %s", conn.RemoteAddr(), upstream.upstream)
6470

65-
upstreamTarget := tcpproxy.To(string(upstreamAddr))
71+
upstreamTarget := tcpproxy.To(upstream.upstream)
6672
upstreamTarget.OnDialError = func(src net.Conn, dstDialErr error) {
6773
src.Close() //nolint: errcheck
6874

69-
log.Printf("error dialing upstream %s: %s", string(upstreamAddr), dstDialErr)
75+
target.logger.Printf("error dialing upstream %s: %s", upstream.upstream, dstDialErr)
7076

7177
target.list.Down(upstreamBackend)
7278
}
@@ -79,13 +85,20 @@ func (target *lbTarget) HandleConn(conn net.Conn) {
7985
// TCP automatically does background health checks for the upstreams and picks only healthy
8086
// ones. Healthcheck is simple Dial attempt.
8187
func (t *TCP) AddRoute(ipPort string, upstreamAddrs []string, options ...upstream.ListOption) error {
88+
if t.Logger == nil {
89+
t.Logger = log.New(log.Writer(), "", log.Flags())
90+
}
91+
8292
if t.routes == nil {
8393
t.routes = make(map[string]*upstream.List)
8494
}
8595

8696
upstreams := make([]upstream.Backend, len(upstreamAddrs))
8797
for i := range upstreams {
88-
upstreams[i] = lbUpstream(upstreamAddrs[i])
98+
upstreams[i] = lbUpstream{
99+
upstream: upstreamAddrs[i],
100+
logger: t.Logger,
101+
}
89102
}
90103

91104
list, err := upstream.NewList(upstreams, options...)
@@ -95,7 +108,10 @@ func (t *TCP) AddRoute(ipPort string, upstreamAddrs []string, options ...upstrea
95108

96109
t.routes[ipPort] = list
97110

98-
t.Proxy.AddRoute(ipPort, &lbTarget{list: list})
111+
t.Proxy.AddRoute(ipPort, &lbTarget{
112+
list: list,
113+
logger: t.Logger,
114+
})
99115

100116
return nil
101117
}
@@ -113,7 +129,10 @@ func (t *TCP) ReconcileRoute(ipPort string, upstreamAddrs []string) error {
113129

114130
upstreams := make([]upstream.Backend, len(upstreamAddrs))
115131
for i := range upstreams {
116-
upstreams[i] = lbUpstream(upstreamAddrs[i])
132+
upstreams[i] = lbUpstream{
133+
upstream: upstreamAddrs[i],
134+
logger: t.Logger,
135+
}
117136
}
118137

119138
list.Reconcile(upstreams)

loadbalancer/loadbalancer_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ func (suite *TCPSuite) TestReconcile() {
149149
no, err := strconv.ParseInt(string(id), 10, 32)
150150
suite.Require().NoError(err)
151151

152+
suite.Assert().EqualValues(no, pivot+(i+pivot)%(upstreamCount-pivot))
153+
152154
suite.Assert().Less(no, int64(upstreamCount))
153155
suite.Assert().GreaterOrEqual(no, int64(pivot))
154156
upstreamsUsed[no]++

upstream/upstream.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,13 @@ func (list *List) Reconcile(upstreams []Backend) {
184184
i--
185185
}
186186

187-
for upstream := range newUpstreams {
187+
// make insert order predictable by going over the list once again,
188+
// as iterating over the map might lead to unpredictable order
189+
for _, upstream := range upstreams {
190+
if _, ok := newUpstreams[upstream]; !ok {
191+
continue
192+
}
193+
188194
list.nodes = append(list.nodes, node{
189195
backend: upstream,
190196
score: list.initialScore,

0 commit comments

Comments
 (0)