Skip to content

Commit 9422ec2

Browse files
committed
common: fix unclosed logrus logging pipes
1 parent c3cb3ba commit 9422ec2

File tree

4 files changed

+67
-36
lines changed

4 files changed

+67
-36
lines changed

cmd/osbuild-composer/main.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,12 @@ func main() {
8080
}
8181

8282
logrus.Info("Loaded configuration:")
83-
err = DumpConfig(*config, logrus.StandardLogger().WriterLevel(logrus.InfoLevel))
83+
dumpWriter := logrus.StandardLogger().WriterLevel(logrus.DebugLevel)
84+
err = DumpConfig(*config, dumpWriter)
8485
if err != nil {
8586
logrus.Fatalf("Error printing configuration: %v", err)
8687
}
88+
dumpWriter.Close()
8789

8890
if config.DeploymentChannel != "" {
8991
logrus.AddHook(&slogger.EnvironmentHook{Channel: config.DeploymentChannel})

cmd/osbuild-worker/main.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,13 @@ var run = func() {
190190
}
191191

192192
logrus.Info("Composer configuration:")
193-
encoder := toml.NewEncoder(logrus.StandardLogger().WriterLevel(logrus.InfoLevel))
193+
configWriter := logrus.StandardLogger().WriterLevel(logrus.DebugLevel)
194+
encoder := toml.NewEncoder(configWriter)
194195
err = encoder.Encode(&config)
195196
if err != nil {
196197
logrus.Fatalf("Could not print config: %v", err)
197198
}
199+
configWriter.Close()
198200

199201
if config.DeploymentChannel != "" {
200202
logrus.AddHook(&slogger.EnvironmentHook{Channel: config.DeploymentChannel})

internal/common/echo_logrus.go

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,41 @@ import (
44
"context"
55
"encoding/json"
66
"io"
7+
"runtime"
78

89
lslog "github.com/labstack/gommon/log"
910
"github.com/sirupsen/logrus"
1011
)
1112

12-
// EchoLogrusLogger extend logrus.Logger
13+
// EchoLogrusLogger extend logrus.Logger to implement Echo's Logger interface.
1314
type EchoLogrusLogger struct {
14-
*logrus.Logger
15-
Ctx context.Context
15+
logger *logrus.Logger
16+
ctx context.Context
17+
writer *io.PipeWriter
18+
}
19+
20+
// NewEchoLogrusLogger creates a new EchoLogrusLogger instance. Logger must be closed
21+
// with Close() method to avoid memory leaks.
22+
func NewEchoLogrusLogger(logger *logrus.Logger, ctx context.Context) *EchoLogrusLogger {
23+
return &EchoLogrusLogger{
24+
logger: logger,
25+
ctx: ctx,
26+
writer: logger.Writer(),
27+
}
28+
}
29+
30+
var commonLogger *EchoLogrusLogger
31+
32+
func init() {
33+
commonLogger = NewEchoLogrusLogger(logrus.StandardLogger(), context.Background())
34+
runtime.SetFinalizer(commonLogger, close)
1635
}
1736

18-
var commonLogger = &EchoLogrusLogger{
19-
Logger: logrus.StandardLogger(),
20-
Ctx: context.Background(),
37+
func close(l *EchoLogrusLogger) {
38+
l.Close()
2139
}
2240

41+
// Logger returns the common logger configured with logrus StandardLogger and context.Background().
2342
func Logger() *EchoLogrusLogger {
2443
return commonLogger
2544
}
@@ -39,16 +58,23 @@ func toEchoLevel(level logrus.Level) lslog.Lvl {
3958
return lslog.OFF
4059
}
4160

61+
func (l *EchoLogrusLogger) Close() {
62+
if l.writer != nil {
63+
l.writer.Close()
64+
l.writer = nil
65+
}
66+
}
67+
4268
func (l *EchoLogrusLogger) Output() io.Writer {
43-
return l.Out
69+
return l.writer
4470
}
4571

4672
func (l *EchoLogrusLogger) SetOutput(w io.Writer) {
4773
// disable operations that would change behavior of global logrus logger.
4874
}
4975

5076
func (l *EchoLogrusLogger) Level() lslog.Lvl {
51-
return toEchoLevel(l.Logger.Level)
77+
return toEchoLevel(l.logger.Level)
5278
}
5379

5480
func (l *EchoLogrusLogger) SetLevel(v lslog.Lvl) {
@@ -66,117 +92,119 @@ func (l *EchoLogrusLogger) SetPrefix(p string) {
6692
}
6793

6894
func (l *EchoLogrusLogger) Print(i ...interface{}) {
69-
l.Logger.WithContext(l.Ctx).Print(i...)
95+
l.logger.WithContext(l.ctx).Print(i...)
7096
}
7197

7298
func (l *EchoLogrusLogger) Printf(format string, args ...interface{}) {
73-
l.Logger.WithContext(l.Ctx).Printf(format, args...)
99+
l.logger.WithContext(l.ctx).Printf(format, args...)
74100
}
75101

76102
func (l *EchoLogrusLogger) Printj(j lslog.JSON) {
77103
b, err := json.Marshal(j)
78104
if err != nil {
79105
panic(err)
80106
}
81-
l.Logger.WithContext(l.Ctx).Println(string(b))
107+
l.logger.WithContext(l.ctx).Println(string(b))
82108
}
83109

84110
func (l *EchoLogrusLogger) Debug(i ...interface{}) {
85-
l.Logger.WithContext(l.Ctx).Debug(i...)
111+
l.logger.WithContext(l.ctx).Debug(i...)
86112
}
87113

88114
func (l *EchoLogrusLogger) Debugf(format string, args ...interface{}) {
89-
l.Logger.WithContext(l.Ctx).Debugf(format, args...)
115+
l.logger.WithContext(l.ctx).Debugf(format, args...)
90116
}
91117

92118
func (l *EchoLogrusLogger) Debugj(j lslog.JSON) {
93119
b, err := json.Marshal(j)
94120
if err != nil {
95121
panic(err)
96122
}
97-
l.Logger.WithContext(l.Ctx).Debugln(string(b))
123+
l.logger.WithContext(l.ctx).Debugln(string(b))
98124
}
99125

100126
func (l *EchoLogrusLogger) Info(i ...interface{}) {
101-
l.Logger.WithContext(l.Ctx).Info(i...)
127+
l.logger.WithContext(l.ctx).Info(i...)
102128
}
103129

104130
func (l *EchoLogrusLogger) Infof(format string, args ...interface{}) {
105-
l.Logger.WithContext(l.Ctx).Infof(format, args...)
131+
l.logger.WithContext(l.ctx).Infof(format, args...)
106132
}
107133

108134
func (l *EchoLogrusLogger) Infoj(j lslog.JSON) {
109135
b, err := json.Marshal(j)
110136
if err != nil {
111137
panic(err)
112138
}
113-
l.Logger.WithContext(l.Ctx).Infoln(string(b))
139+
l.logger.WithContext(l.ctx).Infoln(string(b))
114140
}
115141

116142
func (l *EchoLogrusLogger) Warn(i ...interface{}) {
117-
l.Logger.WithContext(l.Ctx).Warn(i...)
143+
l.logger.WithContext(l.ctx).Warn(i...)
118144
}
119145

120146
func (l *EchoLogrusLogger) Warnf(format string, args ...interface{}) {
121-
l.Logger.WithContext(l.Ctx).Warnf(format, args...)
147+
l.logger.WithContext(l.ctx).Warnf(format, args...)
122148
}
123149

124150
func (l *EchoLogrusLogger) Warnj(j lslog.JSON) {
125151
b, err := json.Marshal(j)
126152
if err != nil {
127153
panic(err)
128154
}
129-
l.Logger.WithContext(l.Ctx).Warnln(string(b))
155+
l.logger.WithContext(l.ctx).Warnln(string(b))
130156
}
131157

132158
func (l *EchoLogrusLogger) Error(i ...interface{}) {
133-
l.Logger.WithContext(l.Ctx).Error(i...)
159+
l.logger.WithContext(l.ctx).Error(i...)
134160
}
135161

136162
func (l *EchoLogrusLogger) Errorf(format string, args ...interface{}) {
137-
l.Logger.WithContext(l.Ctx).Errorf(format, args...)
163+
l.logger.WithContext(l.ctx).Errorf(format, args...)
138164
}
139165

140166
func (l *EchoLogrusLogger) Errorj(j lslog.JSON) {
141167
b, err := json.Marshal(j)
142168
if err != nil {
143169
panic(err)
144170
}
145-
l.Logger.WithContext(l.Ctx).Errorln(string(b))
171+
l.logger.WithContext(l.ctx).Errorln(string(b))
146172
}
147173

148174
func (l *EchoLogrusLogger) Fatal(i ...interface{}) {
149-
l.Logger.WithContext(l.Ctx).Fatal(i...)
175+
l.logger.WithContext(l.ctx).Fatal(i...)
150176
}
151177

152178
func (l *EchoLogrusLogger) Fatalf(format string, args ...interface{}) {
153-
l.Logger.WithContext(l.Ctx).Fatalf(format, args...)
179+
l.logger.WithContext(l.ctx).Fatalf(format, args...)
154180
}
155181

156182
func (l *EchoLogrusLogger) Fatalj(j lslog.JSON) {
157183
b, err := json.Marshal(j)
158184
if err != nil {
159185
panic(err)
160186
}
161-
l.Logger.WithContext(l.Ctx).Fatalln(string(b))
187+
l.logger.WithContext(l.ctx).Fatalln(string(b))
162188
}
163189

164190
func (l *EchoLogrusLogger) Panic(i ...interface{}) {
165-
l.Logger.WithContext(l.Ctx).Panic(i...)
191+
l.logger.WithContext(l.ctx).Panic(i...)
166192
}
167193

168194
func (l *EchoLogrusLogger) Panicf(format string, args ...interface{}) {
169-
l.Logger.WithContext(l.Ctx).Panicf(format, args...)
195+
l.logger.WithContext(l.ctx).Panicf(format, args...)
170196
}
171197

172198
func (l *EchoLogrusLogger) Panicj(j lslog.JSON) {
173199
b, err := json.Marshal(j)
174200
if err != nil {
175201
panic(err)
176202
}
177-
l.Logger.WithContext(l.Ctx).Panicln(string(b))
203+
l.logger.WithContext(l.ctx).Panicln(string(b))
178204
}
179205

206+
// Write method is heavily used by the stdlib log package and called
207+
// from the weldr API.
180208
func (l *EchoLogrusLogger) Write(p []byte) (n int, err error) {
181-
return l.Logger.WithContext(l.Ctx).Writer().Write(p)
209+
return l.writer.Write(p)
182210
}

internal/common/logger_middleware.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ import (
88
// Store context in request logger to propagate correlation ids
99
func LoggerMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
1010
return func(c echo.Context) error {
11-
c.SetLogger(&EchoLogrusLogger{
12-
Logger: logrus.StandardLogger(),
13-
Ctx: c.Request().Context(),
14-
})
11+
ell := NewEchoLogrusLogger(logrus.StandardLogger(), c.Request().Context())
12+
defer ell.Close()
1513

14+
c.SetLogger(ell)
1615
return next(c)
1716
}
1817
}

0 commit comments

Comments
 (0)