mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Remove JSON logging performance regression
* Remove syncing info stream on error log by removing writeWithFlushing * Avoid splitting streams when JSON is enabled by passing nil to NewJSONLogger
This commit is contained in:
parent
c8c81cbfbb
commit
32b81ea0a0
@ -40,20 +40,8 @@ func NewJSONLogger(infoStream, errorStream zapcore.WriteSyncer) (logr.Logger, fu
|
||||
encoder := zapcore.NewJSONEncoder(encoderConfig)
|
||||
var core zapcore.Core
|
||||
if errorStream == nil {
|
||||
core = zapcore.NewCore(encoder, zapcore.AddSync(infoStream), zapcore.Level(-127))
|
||||
core = zapcore.NewCore(encoder, infoStream, zapcore.Level(-127))
|
||||
} else {
|
||||
// Set up writing of error messages to stderr and info messages
|
||||
// to stdout. Info messages get optionally buffered and flushed
|
||||
// - through klog.FlushLogs -> zapr Flush -> zap Sync
|
||||
// - when an error gets logged
|
||||
//
|
||||
// The later is important when both streams get merged into a single
|
||||
// stream by the consumer (same console for a command line tool, pod
|
||||
// log for a container) because without it, messages get reordered.
|
||||
flushError := writeWithFlushing{
|
||||
WriteSyncer: errorStream,
|
||||
other: infoStream,
|
||||
}
|
||||
highPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
|
||||
return lvl >= zapcore.ErrorLevel
|
||||
})
|
||||
@ -61,7 +49,7 @@ func NewJSONLogger(infoStream, errorStream zapcore.WriteSyncer) (logr.Logger, fu
|
||||
return lvl < zapcore.ErrorLevel
|
||||
})
|
||||
core = zapcore.NewTee(
|
||||
zapcore.NewCore(encoder, flushError, highPriority),
|
||||
zapcore.NewCore(encoder, errorStream, highPriority),
|
||||
zapcore.NewCore(encoder, infoStream, lowPriority),
|
||||
)
|
||||
}
|
||||
@ -92,36 +80,23 @@ type Factory struct{}
|
||||
var _ registry.LogFormatFactory = Factory{}
|
||||
|
||||
func (f Factory) Create(options config.FormatOptions) (logr.Logger, func()) {
|
||||
stderr := zapcore.Lock(os.Stderr)
|
||||
if options.JSON.SplitStream {
|
||||
// stdout for info messages, stderr for errors.
|
||||
infoStream := zapcore.Lock(os.Stdout)
|
||||
stdout := zapcore.Lock(os.Stdout)
|
||||
size := options.JSON.InfoBufferSize.Value()
|
||||
if size > 0 {
|
||||
// Prevent integer overflow.
|
||||
if size > 2*1024*1024*1024 {
|
||||
size = 2 * 1024 * 1024 * 1024
|
||||
}
|
||||
infoStream = &zapcore.BufferedWriteSyncer{
|
||||
WS: infoStream,
|
||||
stdout = &zapcore.BufferedWriteSyncer{
|
||||
WS: stdout,
|
||||
Size: int(size),
|
||||
}
|
||||
}
|
||||
return NewJSONLogger(infoStream, zapcore.Lock(os.Stderr))
|
||||
// stdout for info messages, stderr for errors.
|
||||
return NewJSONLogger(stdout, stderr)
|
||||
}
|
||||
// The default is to write to stderr (same as in klog's text output,
|
||||
// doesn't get mixed with normal program output).
|
||||
out := zapcore.Lock(os.Stderr)
|
||||
return NewJSONLogger(out, out)
|
||||
}
|
||||
|
||||
// writeWithFlushing is a wrapper around an output stream which flushes another
|
||||
// output stream before each write.
|
||||
type writeWithFlushing struct {
|
||||
zapcore.WriteSyncer
|
||||
other zapcore.WriteSyncer
|
||||
}
|
||||
|
||||
func (f writeWithFlushing) Write(bs []byte) (int, error) {
|
||||
f.other.Sync()
|
||||
return f.WriteSyncer.Write(bs)
|
||||
// Write info messages and errors to stderr to prevent mixing with normal program output.
|
||||
return NewJSONLogger(stderr, nil)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user