Skip to content

Commit eb87bdf

Browse files
authored
🐛 logs Fix missing writer close skip (#660)
<!-- Copyright (C) 2020-2022 Arm Limited or its affiliates and Contributors. All rights reserved. SPDX-License-Identifier: Apache-2.0 --> ### Description <!-- Please add any detail or context that would be useful to a reviewer. --> ### Test Coverage <!-- Please put an `x` in the correct box e.g. `[x]` to indicate the testing coverage of this change. --> - [ ] This change is covered by existing or additional automated tests. - [ ] Manual testing has been performed (and evidence provided) as automated testing was not feasible. - [ ] Additional tests are not required for this change (e.g. documentation update).
1 parent 4be515d commit eb87bdf

File tree

5 files changed

+17
-20
lines changed

5 files changed

+17
-20
lines changed

changes/20250729175928.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:bug: `logs` Fix missing writer close skip

utils/logs/json_logger.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func (l *JSONLoggers) GetSource() string {
4545
defer l.mu.RUnlock()
4646
return l.source
4747
}
48+
4849
func (l *JSONLoggers) GetLoggerSource() string {
4950
l.mu.RLock()
5051
defer l.mu.RUnlock()
@@ -71,15 +72,15 @@ func (l *JSONLoggers) Configure() error {
7172
}
7273

7374
// Log logs to the output stream.
74-
func (l *JSONLoggers) Log(output ...interface{}) {
75+
func (l *JSONLoggers) Log(output ...any) {
7576
if len(output) == 1 && output[0] == "\n" {
7677
return
7778
}
7879
l.zerologger.Info().Str("source", l.GetLoggerSource()).Msg(fmt.Sprint(output...))
7980
}
8081

8182
// LogError logs to the error stream.
82-
func (l *JSONLoggers) LogError(err ...interface{}) {
83+
func (l *JSONLoggers) LogError(err ...any) {
8384
if len(err) == 1 && err[0] == "\n" {
8485
return
8586
}
@@ -98,7 +99,7 @@ func NewJSONLogger(writer WriterWithSource, loggerSource string, source string)
9899
return newJSONLogger(true, writer, loggerSource, source)
99100
}
100101

101-
// NewJSONLogger creates a Json logger. It is similar to NewJSONLogger but does not close the writer on Close().
102+
// NewJSONLoggerWithWriter creates a Json logger. It is similar to NewJSONLogger but does not close the writer on Close().
102103
func NewJSONLoggerWithWriter(writer WriterWithSource, loggerSource string, source string) (Loggers, error) {
103104
return newJSONLogger(false, writer, loggerSource, source)
104105
}
@@ -156,5 +157,10 @@ func NewJSONLoggerForSlowWriter(slowWriter WriterWithSource, ringBufferSize int,
156157
// droppedMessagesLogger : logger for dropped messages
157158
// If pollInterval is greater than 0, a poller is used otherwise a waiter is used.
158159
func NewJSONLoggerForSlowWriterWithoutClosingWriter(slowWriter WriterWithSource, ringBufferSize int, pollInterval time.Duration, loggerSource string, source string, droppedMessagesLogger Loggers) (loggers Loggers, err error) {
160+
// We call NewJSONLogger which closes the writer, because in this case the writer is a DiodeWriter that doesn't close the writer that is passed to it.
161+
// JSONLogger.Close()
162+
// -> DiodeWriterWithoutClosing.Close()
163+
// -> does the proper steps for closing it's own goroutines
164+
// -> does not close the writer passed as it's passed a non-closeable writer
159165
return NewJSONLogger(NewDiodeWriterForSlowWriterWithoutClosing(slowWriter, ringBufferSize, pollInterval, droppedMessagesLogger), loggerSource, source)
160166
}

utils/logs/json_logger_test.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@ func TestLogMessage(t *testing.T) {
2121
})
2222
t.Run("without writer closing", func(t *testing.T) {
2323
writer := NewStdWriterWithSource()
24-
defer func() { _ = writer.Close() }()
24+
defer func() { require.NoError(t, writer.Close()) }()
2525
loggers, err := NewJSONLoggerWithWriter(writer, "Test", "TestLogMessage")
2626
require.NoError(t, err)
2727
testLog(t, loggers)
28-
require.NoError(t, writer.Close())
2928
})
3029
}
3130

@@ -34,7 +33,6 @@ func TestLogMessageToSlowLogger(t *testing.T) {
3433
stdloggers, err := NewStdLogger("ERR:")
3534
require.NoError(t, err)
3635

37-
defer goleak.VerifyNone(t)
3836
t.Run("with writer closing", func(t *testing.T) {
3937
loggers, err := NewJSONLoggerForSlowWriter(NewTestSlowWriter(t), 1024, 2*time.Millisecond, "Test", "TestLogMessageToSlowLogger", stdloggers)
4038
require.NoError(t, err)
@@ -43,11 +41,10 @@ func TestLogMessageToSlowLogger(t *testing.T) {
4341
})
4442
t.Run("without writer closing", func(t *testing.T) {
4543
writer := NewTestSlowWriter(t)
46-
defer func() { _ = writer.Close() }()
44+
defer func() { require.NoError(t, writer.Close()) }()
4745
loggers, err := NewJSONLoggerForSlowWriterWithoutClosingWriter(writer, 1024, 2*time.Millisecond, "Test", "TestLogMessageToSlowLogger", stdloggers)
4846
require.NoError(t, err)
4947
testLog(t, loggers)
5048
time.Sleep(100 * time.Millisecond)
51-
require.NoError(t, writer.Close())
5249
})
5350
}

utils/logs/log_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func testLog(t *testing.T, loggers Loggers) {
2727
t.Helper()
2828
err := loggers.Check()
2929
require.NoError(t, err)
30-
defer func() { _ = loggers.Close() }()
30+
defer func() { require.NoError(t, loggers.Close()) }()
3131

3232
err = loggers.SetLogSource("source1")
3333
require.NoError(t, err)
@@ -60,6 +60,4 @@ func testLog(t *testing.T, loggers Loggers) {
6060
loggers.LogError(commonerrors.ErrUnexpected, "some error")
6161
loggers.LogError("some error", commonerrors.ErrUnexpected)
6262
loggers.LogError(nil, "no error")
63-
err = loggers.Close()
64-
require.NoError(t, err)
6563
}

utils/logs/writer.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,10 @@ func (w *DiodeWriter) Write(p []byte) (n int, err error) {
110110
}
111111

112112
func (w *DiodeWriter) Close() error {
113-
err := w.slowWriter.Close()
114-
if err != nil {
115-
return err
116-
}
117-
if diodeCloser, ok := w.diodeWriter.(io.Closer); ok {
118-
return diodeCloser.Close()
113+
if w.closeStore == nil {
114+
return nil
119115
}
120-
return err
116+
return w.closeStore.Close()
121117
}
122118

123119
func (w *DiodeWriter) SetSource(source string) error {
@@ -150,8 +146,7 @@ func newDiodeWriterForSlowWriter(closeWriterOnClose bool, slowWriter WriterWithS
150146

151147
// We pass a wrapper that "overrides" the close method to do nothing,
152148
// this is because we control the writer's close behaviour through the `closeWriterOnClose` check
153-
ncw := nonCloseableWriter{slowWriter}
154-
d := diode.NewWriter(ncw, ringBufferSize, pollInterval, func(missed int) {
149+
d := diode.NewWriter(nonCloseableWriter{Writer: slowWriter}, ringBufferSize, pollInterval, func(missed int) {
155150
if droppedMessagesLogger != nil {
156151
droppedMessagesLogger.LogError(fmt.Sprintf("Logger dropped %d messages", missed))
157152
}

0 commit comments

Comments
 (0)