Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 11, 21:00 UTC
logging: Adjustments to BufferedLog to keep logs in the correct order (#7257)
* logging: Adjustments to BufferedLog to keep logs in the correct order * Ignore lints
Francis Lavoie committed
Sep 15, 2025 at 11:29 UTC
39ace450deb23a8ebb4f41ff4d8cfe2800d68118
3 files changed
+37
-6
cmd/commandfuncs.go
+20
-6
@@ -182,6 +182,9 @@ func cmdRun(fl Flags) (int, error) {
182
183
undoMaxProcs := setResourceLimits(logger)
184
defer undoMaxProcs()
185
+ // release the local reference to the undo function so it can be GC'd;
186
+ // the deferred call above has already captured the actual function value.
187
+ undoMaxProcs = nil //nolint:ineffassign,wastedassign
188
189
configFlag := fl.String("config")
190
configAdapterFlag := fl.String("adapter")
@@ -252,12 +255,16 @@ func cmdRun(fl Flags) (int, error) {
255
logBuffer.FlushTo(defaultLogger)
256
return caddy.ExitCodeFailedStartup, fmt.Errorf("loading initial config: %v", err)
257
}
258
+ // release the reference to the config so it can be GC'd
259
+ config = nil //nolint:ineffassign,wastedassign
260
256
- // at this stage the config will have replaced
257
- // the default logger to the configured one, so
258
- // we can now flush the buffered logs, then log
259
- // that the config is running.
260
- logBuffer.FlushTo(caddy.Log())
261
+ // at this stage the config will have replaced the
262
+ // default logger to the configured one, so we can
263
+ // log normally, now that the config is running.
264
+ // also clear our ref to the buffer so it can get GC'd
265
+ logger = caddy.Log()
266
+ defaultLogger = nil //nolint:ineffassign,wastedassign
267
+ logBuffer = nil //nolint:wastedassign,ineffassign
268
logger.Info("serving initial configuration")
269
270
// if we are to report to another process the successful start
@@ -273,12 +280,16 @@ func cmdRun(fl Flags) (int, error) {
280
return caddy.ExitCodeFailedStartup,
281
fmt.Errorf("dialing confirmation address: %v", err)
282
}
276
- defer conn.Close()
283
_, err = conn.Write(confirmationBytes)
284
if err != nil {
285
return caddy.ExitCodeFailedStartup,
286
fmt.Errorf("writing confirmation bytes to %s: %v", pingbackFlag, err)
287
}
288
+ // close (non-defer because we `select {}` below)
289
+ // and release references so they can be GC'd
290
+ conn.Close()
291
+ confirmationBytes = nil //nolint:ineffassign,wastedassign
292
+ conn = nil //nolint:wastedassign,ineffassign
293
}
294
295
// if enabled, reload config file automatically on changes
@@ -306,6 +317,9 @@ func cmdRun(fl Flags) (int, error) {
317
}
318
}
319
320
+ // release the last local logger reference
321
+ logger = nil //nolint:wastedassign,ineffassign
322
+
323
select {}
324
}
325
internal/logbuffer.go
+10
@@ -29,6 +29,11 @@ type LogBufferCore struct {
29
level zapcore.LevelEnabler
30
}
31
32
+type LogBufferCoreInterface interface {
33
+ zapcore.Core
34
+ FlushTo(*zap.Logger)
35
+}
36
+
37
func NewLogBufferCore(level zapcore.LevelEnabler) *LogBufferCore {
38
return &LogBufferCore{
39
level: level,
@@ -70,3 +75,8 @@ func (c *LogBufferCore) FlushTo(logger *zap.Logger) {
75
c.entries = nil
76
c.fields = nil
77
}
78
+
79
+var (
80
+ _ zapcore.Core = (*LogBufferCore)(nil)
81
+ _ LogBufferCoreInterface = (*LogBufferCore)(nil)
82
+)
logging.go
+7
@@ -192,6 +192,13 @@ func (logging *Logging) setupNewDefault(ctx Context) error {
192
)
193
}
194
195
+ // if we had a buffered core, flush its contents ASAP
196
+ // before we try to log anything else, so the order of
197
+ // logs is preserved
198
+ if oldBufferCore, ok := oldDefault.logger.Core().(*internal.LogBufferCore); ok {
199
+ oldBufferCore.FlushTo(newDefault.logger)
200
+ }
201
+
202
return nil
203
}
204