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
This commit is contained in:
Francis Lavoie 2025-09-15 11:29:50 -04:00 committed by GitHub
parent 0ba8786b35
commit 39ace450de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 37 additions and 6 deletions

View file

@ -182,6 +182,9 @@ func cmdRun(fl Flags) (int, error) {
undoMaxProcs := setResourceLimits(logger) undoMaxProcs := setResourceLimits(logger)
defer undoMaxProcs() defer undoMaxProcs()
// release the local reference to the undo function so it can be GC'd;
// the deferred call above has already captured the actual function value.
undoMaxProcs = nil //nolint:ineffassign,wastedassign
configFlag := fl.String("config") configFlag := fl.String("config")
configAdapterFlag := fl.String("adapter") configAdapterFlag := fl.String("adapter")
@ -252,12 +255,16 @@ func cmdRun(fl Flags) (int, error) {
logBuffer.FlushTo(defaultLogger) logBuffer.FlushTo(defaultLogger)
return caddy.ExitCodeFailedStartup, fmt.Errorf("loading initial config: %v", err) return caddy.ExitCodeFailedStartup, fmt.Errorf("loading initial config: %v", err)
} }
// release the reference to the config so it can be GC'd
config = nil //nolint:ineffassign,wastedassign
// at this stage the config will have replaced // at this stage the config will have replaced the
// the default logger to the configured one, so // default logger to the configured one, so we can
// we can now flush the buffered logs, then log // log normally, now that the config is running.
// that the config is running. // also clear our ref to the buffer so it can get GC'd
logBuffer.FlushTo(caddy.Log()) logger = caddy.Log()
defaultLogger = nil //nolint:ineffassign,wastedassign
logBuffer = nil //nolint:wastedassign,ineffassign
logger.Info("serving initial configuration") logger.Info("serving initial configuration")
// if we are to report to another process the successful start // if we are to report to another process the successful start
@ -273,12 +280,16 @@ func cmdRun(fl Flags) (int, error) {
return caddy.ExitCodeFailedStartup, return caddy.ExitCodeFailedStartup,
fmt.Errorf("dialing confirmation address: %v", err) fmt.Errorf("dialing confirmation address: %v", err)
} }
defer conn.Close()
_, err = conn.Write(confirmationBytes) _, err = conn.Write(confirmationBytes)
if err != nil { if err != nil {
return caddy.ExitCodeFailedStartup, return caddy.ExitCodeFailedStartup,
fmt.Errorf("writing confirmation bytes to %s: %v", pingbackFlag, err) fmt.Errorf("writing confirmation bytes to %s: %v", pingbackFlag, err)
} }
// close (non-defer because we `select {}` below)
// and release references so they can be GC'd
conn.Close()
confirmationBytes = nil //nolint:ineffassign,wastedassign
conn = nil //nolint:wastedassign,ineffassign
} }
// if enabled, reload config file automatically on changes // if enabled, reload config file automatically on changes
@ -306,6 +317,9 @@ func cmdRun(fl Flags) (int, error) {
} }
} }
// release the last local logger reference
logger = nil //nolint:wastedassign,ineffassign
select {} select {}
} }

View file

@ -29,6 +29,11 @@ type LogBufferCore struct {
level zapcore.LevelEnabler level zapcore.LevelEnabler
} }
type LogBufferCoreInterface interface {
zapcore.Core
FlushTo(*zap.Logger)
}
func NewLogBufferCore(level zapcore.LevelEnabler) *LogBufferCore { func NewLogBufferCore(level zapcore.LevelEnabler) *LogBufferCore {
return &LogBufferCore{ return &LogBufferCore{
level: level, level: level,
@ -70,3 +75,8 @@ func (c *LogBufferCore) FlushTo(logger *zap.Logger) {
c.entries = nil c.entries = nil
c.fields = nil c.fields = nil
} }
var (
_ zapcore.Core = (*LogBufferCore)(nil)
_ LogBufferCoreInterface = (*LogBufferCore)(nil)
)

View file

@ -192,6 +192,13 @@ func (logging *Logging) setupNewDefault(ctx Context) error {
) )
} }
// if we had a buffered core, flush its contents ASAP
// before we try to log anything else, so the order of
// logs is preserved
if oldBufferCore, ok := oldDefault.logger.Core().(*internal.LogBufferCore); ok {
oldBufferCore.FlushTo(newDefault.logger)
}
return nil return nil
} }