@marcel91200 / caddy Mirror · read-only / commits / 39ace450
Fork 0

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