Skip to content

Commit b2c3b97

Browse files
authored
Merge pull request #5286 from k8s-infra-cherrypick-robot/cherry-pick-5284-to-release-1.17
[release-1.17] fix ever-accumulating memory in logger
2 parents f7ba68f + 34032f6 commit b2c3b97

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

util/tele/span_logger.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,18 @@ func (s *spanLogSink) Error(err error, msg string, keysAndValues ...interface{})
8888
)
8989
}
9090

91-
func (s *spanLogSink) WithValues(keysAndValues ...interface{}) logr.LogSink {
92-
s.vals = append(s.vals, keysAndValues...)
93-
return s
91+
func (s spanLogSink) WithValues(keysAndValues ...interface{}) logr.LogSink {
92+
// always create a new slice to avoid multiple loggers writing to the same backing array
93+
vals := make([]interface{}, len(s.vals)+len(keysAndValues))
94+
copy(vals, s.vals)
95+
copy(vals[len(s.vals):], keysAndValues)
96+
s.vals = vals
97+
return &s
9498
}
9599

96-
func (s *spanLogSink) WithName(name string) logr.LogSink {
100+
func (s spanLogSink) WithName(name string) logr.LogSink {
97101
s.name = name
98-
return s
102+
return &s
99103
}
100104

101105
// NewSpanLogSink is the main entry-point to this implementation.

util/tele/span_logger_test.go

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package tele
18+
19+
import (
20+
"testing"
21+
22+
"github.com/go-logr/logr"
23+
. "github.com/onsi/gomega"
24+
)
25+
26+
func TestSpanLogSinkWithValues(t *testing.T) {
27+
g := NewGomegaWithT(t)
28+
29+
var log0 logr.LogSink = &spanLogSink{
30+
// simulating a slice with cap() > len() where an append() will not create a new array
31+
vals: make([]interface{}, 0, 4),
32+
}
33+
34+
log0 = log0.WithValues("k0", "v0")
35+
36+
g.Expect(log0.(*spanLogSink).vals).To(HaveExactElements("k0", "v0"))
37+
38+
log1 := log0.WithValues("k1", "v1")
39+
40+
g.Expect(log0.(*spanLogSink).vals).To(HaveExactElements("k0", "v0"))
41+
g.Expect(log1.(*spanLogSink).vals).To(HaveExactElements("k0", "v0", "k1", "v1"))
42+
43+
log2 := log0.WithValues("k2", "v2")
44+
45+
g.Expect(log0.(*spanLogSink).vals).To(HaveExactElements("k0", "v0"))
46+
g.Expect(log1.(*spanLogSink).vals).To(HaveExactElements("k0", "v0", "k1", "v1"))
47+
g.Expect(log2.(*spanLogSink).vals).To(HaveExactElements("k0", "v0", "k2", "v2"))
48+
}

0 commit comments

Comments
 (0)