vendor: k8s.io/klog/v2 v2.90.1

full diff: https://github.com/kubernetes/klog/compare/v2.80.1...v2.90.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2023-07-19 17:30:28 +02:00
parent 410a52b763
commit 7145129f27
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
9 changed files with 379 additions and 174 deletions

View file

@ -202,6 +202,6 @@ require (
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/klog/v2 v2.80.1 // indirect k8s.io/klog/v2 v2.90.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect sigs.k8s.io/yaml v1.3.0 // indirect
) )

View file

@ -2138,8 +2138,8 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=

30
vendor/k8s.io/klog/v2/contextual.go generated vendored
View file

@ -70,11 +70,14 @@ func SetLogger(logger logr.Logger) {
// routing log entries through klogr into klog and then into the actual Logger // routing log entries through klogr into klog and then into the actual Logger
// backend. // backend.
func SetLoggerWithOptions(logger logr.Logger, opts ...LoggerOption) { func SetLoggerWithOptions(logger logr.Logger, opts ...LoggerOption) {
logging.logger = &logger
logging.loggerOptions = loggerOptions{} logging.loggerOptions = loggerOptions{}
for _, opt := range opts { for _, opt := range opts {
opt(&logging.loggerOptions) opt(&logging.loggerOptions)
} }
logging.logger = &logWriter{
Logger: logger,
writeKlogBuffer: logging.loggerOptions.writeKlogBuffer,
}
} }
// ContextualLogger determines whether the logger passed to // ContextualLogger determines whether the logger passed to
@ -93,6 +96,22 @@ func FlushLogger(flush func()) LoggerOption {
} }
} }
// WriteKlogBuffer sets a callback that will be invoked by klog to write output
// produced by non-structured log calls like Infof.
//
// The buffer will contain exactly the same data that klog normally would write
// into its own output stream(s). In particular this includes the header, if
// klog is configured to write one. The callback then can divert that data into
// its own output streams. The buffer may or may not end in a line break.
//
// Without such a callback, klog will call the logger's Info or Error method
// with just the message string (i.e. no header).
func WriteKlogBuffer(write func([]byte)) LoggerOption {
return func(o *loggerOptions) {
o.writeKlogBuffer = write
}
}
// LoggerOption implements the functional parameter paradigm for // LoggerOption implements the functional parameter paradigm for
// SetLoggerWithOptions. // SetLoggerWithOptions.
type LoggerOption func(o *loggerOptions) type LoggerOption func(o *loggerOptions)
@ -100,6 +119,13 @@ type LoggerOption func(o *loggerOptions)
type loggerOptions struct { type loggerOptions struct {
contextualLogger bool contextualLogger bool
flush func() flush func()
writeKlogBuffer func([]byte)
}
// logWriter combines a logger (always set) with a write callback (optional).
type logWriter struct {
Logger
writeKlogBuffer func([]byte)
} }
// ClearLogger removes a backing Logger implementation if one was set earlier // ClearLogger removes a backing Logger implementation if one was set earlier
@ -152,7 +178,7 @@ func Background() Logger {
if logging.loggerOptions.contextualLogger { if logging.loggerOptions.contextualLogger {
// Is non-nil because logging.loggerOptions.contextualLogger is // Is non-nil because logging.loggerOptions.contextualLogger is
// only true if a logger was set. // only true if a logger was set.
return *logging.logger return logging.logger.Logger
} }
return klogLogger return klogLogger

View file

@ -40,44 +40,33 @@ type Buffer struct {
next *Buffer next *Buffer
} }
// Buffers manages the reuse of individual buffer instances. It is thread-safe. var buffers = sync.Pool{
type Buffers struct { New: func() interface{} {
// mu protects the free list. It is separate from the main mutex return new(Buffer)
// so buffers can be grabbed and printed to without holding the main lock, },
// for better parallelization.
mu sync.Mutex
// freeList is a list of byte buffers, maintained under mu.
freeList *Buffer
} }
// GetBuffer returns a new, ready-to-use buffer. // GetBuffer returns a new, ready-to-use buffer.
func (bl *Buffers) GetBuffer() *Buffer { func GetBuffer() *Buffer {
bl.mu.Lock() b := buffers.Get().(*Buffer)
b := bl.freeList
if b != nil {
bl.freeList = b.next
}
bl.mu.Unlock()
if b == nil {
b = new(Buffer)
} else {
b.next = nil
b.Reset() b.Reset()
}
return b return b
} }
// PutBuffer returns a buffer to the free list. // PutBuffer returns a buffer to the free list.
func (bl *Buffers) PutBuffer(b *Buffer) { func PutBuffer(b *Buffer) {
if b.Len() >= 256 { if b.Len() >= 256 {
// Let big buffers die a natural death. // Let big buffers die a natural death, without relying on
// sync.Pool behavior. The documentation implies that items may
// get deallocated while stored there ("If the Pool holds the
// only reference when this [= be removed automatically]
// happens, the item might be deallocated."), but
// https://github.com/golang/go/issues/23199 leans more towards
// having such a size limit.
return return
} }
bl.mu.Lock()
b.next = bl.freeList buffers.Put(b)
bl.freeList = b
bl.mu.Unlock()
} }
// Some custom tiny helper functions to print the log header efficiently. // Some custom tiny helper functions to print the log header efficiently.
@ -121,7 +110,8 @@ func (buf *Buffer) someDigits(i, d int) int {
return copy(buf.Tmp[i:], buf.Tmp[j:]) return copy(buf.Tmp[i:], buf.Tmp[j:])
} }
// FormatHeader formats a log header using the provided file name and line number. // FormatHeader formats a log header using the provided file name and line number
// and writes it into the buffer.
func (buf *Buffer) FormatHeader(s severity.Severity, file string, line int, now time.Time) { func (buf *Buffer) FormatHeader(s severity.Severity, file string, line int, now time.Time) {
if line < 0 { if line < 0 {
line = 0 // not a real line number, but acceptable to someDigits line = 0 // not a real line number, but acceptable to someDigits
@ -157,3 +147,30 @@ func (buf *Buffer) FormatHeader(s severity.Severity, file string, line int, now
buf.Tmp[n+2] = ' ' buf.Tmp[n+2] = ' '
buf.Write(buf.Tmp[:n+3]) buf.Write(buf.Tmp[:n+3])
} }
// SprintHeader formats a log header and returns a string. This is a simpler
// version of FormatHeader for use in ktesting.
func (buf *Buffer) SprintHeader(s severity.Severity, now time.Time) string {
if s > severity.FatalLog {
s = severity.InfoLog // for safety.
}
// Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand.
// It's worth about 3X. Fprintf is hard.
_, month, day := now.Date()
hour, minute, second := now.Clock()
// Lmmdd hh:mm:ss.uuuuuu threadid file:line]
buf.Tmp[0] = severity.Char[s]
buf.twoDigits(1, int(month))
buf.twoDigits(3, day)
buf.Tmp[5] = ' '
buf.twoDigits(6, hour)
buf.Tmp[8] = ':'
buf.twoDigits(9, minute)
buf.Tmp[11] = ':'
buf.twoDigits(12, second)
buf.Tmp[14] = '.'
buf.nDigits(6, 15, now.Nanosecond()/1000, '0')
buf.Tmp[21] = ']'
return string(buf.Tmp[:22])
}

View file

@ -24,6 +24,10 @@ import (
"github.com/go-logr/logr" "github.com/go-logr/logr"
) )
type textWriter interface {
WriteText(*bytes.Buffer)
}
// WithValues implements LogSink.WithValues. The old key/value pairs are // WithValues implements LogSink.WithValues. The old key/value pairs are
// assumed to be well-formed, the new ones are checked and padded if // assumed to be well-formed, the new ones are checked and padded if
// necessary. It returns a new slice. // necessary. It returns a new slice.
@ -91,11 +95,66 @@ func MergeKVs(first, second []interface{}) []interface{} {
return merged return merged
} }
type Formatter struct {
AnyToStringHook AnyToStringFunc
}
type AnyToStringFunc func(v interface{}) string
// MergeKVsInto is a variant of MergeKVs which directly formats the key/value
// pairs into a buffer.
func (f Formatter) MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) {
if len(first) == 0 && len(second) == 0 {
// Nothing to do at all.
return
}
if len(first) == 0 && len(second)%2 == 0 {
// Nothing to be overridden, second slice is well-formed
// and can be used directly.
for i := 0; i < len(second); i += 2 {
f.KVFormat(b, second[i], second[i+1])
}
return
}
// Determine which keys are in the second slice so that we can skip
// them when iterating over the first one. The code intentionally
// favors performance over completeness: we assume that keys are string
// constants and thus compare equal when the string values are equal. A
// string constant being overridden by, for example, a fmt.Stringer is
// not handled.
overrides := map[interface{}]bool{}
for i := 0; i < len(second); i += 2 {
overrides[second[i]] = true
}
for i := 0; i < len(first); i += 2 {
key := first[i]
if overrides[key] {
continue
}
f.KVFormat(b, key, first[i+1])
}
// Round down.
l := len(second)
l = l / 2 * 2
for i := 1; i < l; i += 2 {
f.KVFormat(b, second[i-1], second[i])
}
if len(second)%2 == 1 {
f.KVFormat(b, second[len(second)-1], missingValue)
}
}
func MergeAndFormatKVs(b *bytes.Buffer, first, second []interface{}) {
Formatter{}.MergeAndFormatKVs(b, first, second)
}
const missingValue = "(MISSING)" const missingValue = "(MISSING)"
// KVListFormat serializes all key/value pairs into the provided buffer. // KVListFormat serializes all key/value pairs into the provided buffer.
// A space gets inserted before the first pair and between each pair. // A space gets inserted before the first pair and between each pair.
func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { func (f Formatter) KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) {
for i := 0; i < len(keysAndValues); i += 2 { for i := 0; i < len(keysAndValues); i += 2 {
var v interface{} var v interface{}
k := keysAndValues[i] k := keysAndValues[i]
@ -104,6 +163,17 @@ func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) {
} else { } else {
v = missingValue v = missingValue
} }
f.KVFormat(b, k, v)
}
}
func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) {
Formatter{}.KVListFormat(b, keysAndValues...)
}
// KVFormat serializes one key/value pair into the provided buffer.
// A space gets inserted before the pair.
func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) {
b.WriteByte(' ') b.WriteByte(' ')
// Keys are assumed to be well-formed according to // Keys are assumed to be well-formed according to
// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments // https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments
@ -123,6 +193,8 @@ func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) {
// than plain strings // than plain strings
// (https://github.com/kubernetes/kubernetes/pull/106594#issuecomment-975526235). // (https://github.com/kubernetes/kubernetes/pull/106594#issuecomment-975526235).
switch v := v.(type) { switch v := v.(type) {
case textWriter:
writeTextWriterValue(b, v)
case fmt.Stringer: case fmt.Stringer:
writeStringValue(b, true, StringerToString(v)) writeStringValue(b, true, StringerToString(v))
case string: case string:
@ -145,7 +217,7 @@ func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) {
case string: case string:
writeStringValue(b, true, value) writeStringValue(b, true, value)
default: default:
writeStringValue(b, false, fmt.Sprintf("%+v", value)) writeStringValue(b, false, f.AnyToString(value))
} }
case []byte: case []byte:
// In https://github.com/kubernetes/klog/pull/237 it was decided // In https://github.com/kubernetes/klog/pull/237 it was decided
@ -162,9 +234,20 @@ func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) {
b.WriteByte('=') b.WriteByte('=')
b.WriteString(fmt.Sprintf("%+q", v)) b.WriteString(fmt.Sprintf("%+q", v))
default: default:
writeStringValue(b, false, fmt.Sprintf("%+v", v)) writeStringValue(b, false, f.AnyToString(v))
} }
} }
func KVFormat(b *bytes.Buffer, k, v interface{}) {
Formatter{}.KVFormat(b, k, v)
}
// AnyToString is the historic fallback formatter.
func (f Formatter) AnyToString(v interface{}) string {
if f.AnyToStringHook != nil {
return f.AnyToStringHook(v)
}
return fmt.Sprintf("%+v", v)
} }
// StringerToString converts a Stringer to a string, // StringerToString converts a Stringer to a string,
@ -203,6 +286,16 @@ func ErrorToString(err error) (ret string) {
return return
} }
func writeTextWriterValue(b *bytes.Buffer, v textWriter) {
b.WriteRune('=')
defer func() {
if err := recover(); err != nil {
fmt.Fprintf(b, `"<panic: %s>"`, err)
}
}()
v.WriteText(b)
}
func writeStringValue(b *bytes.Buffer, quote bool, v string) { func writeStringValue(b *bytes.Buffer, quote bool, v string) {
data := []byte(v) data := []byte(v)
index := bytes.IndexByte(data, '\n') index := bytes.IndexByte(data, '\n')

View file

@ -17,8 +17,10 @@ limitations under the License.
package klog package klog
import ( import (
"bytes"
"fmt" "fmt"
"reflect" "reflect"
"strings"
"github.com/go-logr/logr" "github.com/go-logr/logr"
) )
@ -31,11 +33,30 @@ type ObjectRef struct {
func (ref ObjectRef) String() string { func (ref ObjectRef) String() string {
if ref.Namespace != "" { if ref.Namespace != "" {
return fmt.Sprintf("%s/%s", ref.Namespace, ref.Name) var builder strings.Builder
builder.Grow(len(ref.Namespace) + len(ref.Name) + 1)
builder.WriteString(ref.Namespace)
builder.WriteRune('/')
builder.WriteString(ref.Name)
return builder.String()
} }
return ref.Name return ref.Name
} }
func (ref ObjectRef) WriteText(out *bytes.Buffer) {
out.WriteRune('"')
ref.writeUnquoted(out)
out.WriteRune('"')
}
func (ref ObjectRef) writeUnquoted(out *bytes.Buffer) {
if ref.Namespace != "" {
out.WriteString(ref.Namespace)
out.WriteRune('/')
}
out.WriteString(ref.Name)
}
// MarshalLog ensures that loggers with support for structured output will log // MarshalLog ensures that loggers with support for structured output will log
// as a struct by removing the String method via a custom type. // as a struct by removing the String method via a custom type.
func (ref ObjectRef) MarshalLog() interface{} { func (ref ObjectRef) MarshalLog() interface{} {
@ -117,31 +138,31 @@ var _ fmt.Stringer = kobjSlice{}
var _ logr.Marshaler = kobjSlice{} var _ logr.Marshaler = kobjSlice{}
func (ks kobjSlice) String() string { func (ks kobjSlice) String() string {
objectRefs, err := ks.process() objectRefs, errStr := ks.process()
if err != nil { if errStr != "" {
return err.Error() return errStr
} }
return fmt.Sprintf("%v", objectRefs) return fmt.Sprintf("%v", objectRefs)
} }
func (ks kobjSlice) MarshalLog() interface{} { func (ks kobjSlice) MarshalLog() interface{} {
objectRefs, err := ks.process() objectRefs, errStr := ks.process()
if err != nil { if errStr != "" {
return err.Error() return errStr
} }
return objectRefs return objectRefs
} }
func (ks kobjSlice) process() ([]interface{}, error) { func (ks kobjSlice) process() (objs []interface{}, err string) {
s := reflect.ValueOf(ks.arg) s := reflect.ValueOf(ks.arg)
switch s.Kind() { switch s.Kind() {
case reflect.Invalid: case reflect.Invalid:
// nil parameter, print as nil. // nil parameter, print as nil.
return nil, nil return nil, ""
case reflect.Slice: case reflect.Slice:
// Okay, handle below. // Okay, handle below.
default: default:
return nil, fmt.Errorf("<KObjSlice needs a slice, got type %T>", ks.arg) return nil, fmt.Sprintf("<KObjSlice needs a slice, got type %T>", ks.arg)
} }
objectRefs := make([]interface{}, 0, s.Len()) objectRefs := make([]interface{}, 0, s.Len())
for i := 0; i < s.Len(); i++ { for i := 0; i < s.Len(); i++ {
@ -151,8 +172,41 @@ func (ks kobjSlice) process() ([]interface{}, error) {
} else if v, ok := item.(KMetadata); ok { } else if v, ok := item.(KMetadata); ok {
objectRefs = append(objectRefs, KObj(v)) objectRefs = append(objectRefs, KObj(v))
} else { } else {
return nil, fmt.Errorf("<KObjSlice needs a slice of values implementing KMetadata, got type %T>", item) return nil, fmt.Sprintf("<KObjSlice needs a slice of values implementing KMetadata, got type %T>", item)
}
}
return objectRefs, ""
}
var nilToken = []byte("<nil>")
func (ks kobjSlice) WriteText(out *bytes.Buffer) {
s := reflect.ValueOf(ks.arg)
switch s.Kind() {
case reflect.Invalid:
// nil parameter, print as empty slice.
out.WriteString("[]")
return
case reflect.Slice:
// Okay, handle below.
default:
fmt.Fprintf(out, `"<KObjSlice needs a slice, got type %T>"`, ks.arg)
return
}
out.Write([]byte{'['})
defer out.Write([]byte{']'})
for i := 0; i < s.Len(); i++ {
if i > 0 {
out.Write([]byte{' '})
}
item := s.Index(i).Interface()
if item == nil {
out.Write(nilToken)
} else if v, ok := item.(KMetadata); ok {
KObj(v).writeUnquoted(out)
} else {
fmt.Fprintf(out, "<KObjSlice needs a slice of values implementing KMetadata, got type %T>", item)
return
} }
} }
return objectRefs, nil
} }

129
vendor/k8s.io/klog/v2/klog.go generated vendored
View file

@ -91,8 +91,6 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/go-logr/logr"
"k8s.io/klog/v2/internal/buffer" "k8s.io/klog/v2/internal/buffer"
"k8s.io/klog/v2/internal/clock" "k8s.io/klog/v2/internal/clock"
"k8s.io/klog/v2/internal/dbg" "k8s.io/klog/v2/internal/dbg"
@ -453,7 +451,7 @@ type settings struct {
// logger is the global Logger chosen by users of klog, nil if // logger is the global Logger chosen by users of klog, nil if
// none is available. // none is available.
logger *Logger logger *logWriter
// loggerOptions contains the options that were supplied for // loggerOptions contains the options that were supplied for
// globalLogger. // globalLogger.
@ -525,6 +523,11 @@ func (s settings) deepCopy() settings {
} }
s.vmodule.filter = filter s.vmodule.filter = filter
if s.logger != nil {
logger := *s.logger
s.logger = &logger
}
return s return s
} }
@ -532,11 +535,6 @@ func (s settings) deepCopy() settings {
type loggingT struct { type loggingT struct {
settings settings
// bufferCache maintains the free list. It uses its own mutex
// so buffers can be grabbed and printed to without holding the main lock,
// for better parallelization.
bufferCache buffer.Buffers
// flushD holds a flushDaemon that frequently flushes log file buffers. // flushD holds a flushDaemon that frequently flushes log file buffers.
// Uses its own mutex. // Uses its own mutex.
flushD *flushDaemon flushD *flushDaemon
@ -664,7 +662,7 @@ func (l *loggingT) header(s severity.Severity, depth int) (*buffer.Buffer, strin
// formatHeader formats a log header using the provided file name and line number. // formatHeader formats a log header using the provided file name and line number.
func (l *loggingT) formatHeader(s severity.Severity, file string, line int) *buffer.Buffer { func (l *loggingT) formatHeader(s severity.Severity, file string, line int) *buffer.Buffer {
buf := l.bufferCache.GetBuffer() buf := buffer.GetBuffer()
if l.skipHeaders { if l.skipHeaders {
return buf return buf
} }
@ -673,17 +671,18 @@ func (l *loggingT) formatHeader(s severity.Severity, file string, line int) *buf
return buf return buf
} }
func (l *loggingT) println(s severity.Severity, logger *logr.Logger, filter LogFilter, args ...interface{}) { func (l *loggingT) println(s severity.Severity, logger *logWriter, filter LogFilter, args ...interface{}) {
l.printlnDepth(s, logger, filter, 1, args...) l.printlnDepth(s, logger, filter, 1, args...)
} }
func (l *loggingT) printlnDepth(s severity.Severity, logger *logr.Logger, filter LogFilter, depth int, args ...interface{}) { func (l *loggingT) printlnDepth(s severity.Severity, logger *logWriter, filter LogFilter, depth int, args ...interface{}) {
buf, file, line := l.header(s, depth) buf, file, line := l.header(s, depth)
// if logger is set, we clear the generated header as we rely on the backing // If a logger is set and doesn't support writing a formatted buffer,
// logger implementation to print headers // we clear the generated header as we rely on the backing
if logger != nil { // logger implementation to print headers.
l.bufferCache.PutBuffer(buf) if logger != nil && logger.writeKlogBuffer == nil {
buf = l.bufferCache.GetBuffer() buffer.PutBuffer(buf)
buf = buffer.GetBuffer()
} }
if filter != nil { if filter != nil {
args = filter.Filter(args) args = filter.Filter(args)
@ -692,17 +691,18 @@ func (l *loggingT) printlnDepth(s severity.Severity, logger *logr.Logger, filter
l.output(s, logger, buf, depth, file, line, false) l.output(s, logger, buf, depth, file, line, false)
} }
func (l *loggingT) print(s severity.Severity, logger *logr.Logger, filter LogFilter, args ...interface{}) { func (l *loggingT) print(s severity.Severity, logger *logWriter, filter LogFilter, args ...interface{}) {
l.printDepth(s, logger, filter, 1, args...) l.printDepth(s, logger, filter, 1, args...)
} }
func (l *loggingT) printDepth(s severity.Severity, logger *logr.Logger, filter LogFilter, depth int, args ...interface{}) { func (l *loggingT) printDepth(s severity.Severity, logger *logWriter, filter LogFilter, depth int, args ...interface{}) {
buf, file, line := l.header(s, depth) buf, file, line := l.header(s, depth)
// if logr is set, we clear the generated header as we rely on the backing // If a logger is set and doesn't support writing a formatted buffer,
// logr implementation to print headers // we clear the generated header as we rely on the backing
if logger != nil { // logger implementation to print headers.
l.bufferCache.PutBuffer(buf) if logger != nil && logger.writeKlogBuffer == nil {
buf = l.bufferCache.GetBuffer() buffer.PutBuffer(buf)
buf = buffer.GetBuffer()
} }
if filter != nil { if filter != nil {
args = filter.Filter(args) args = filter.Filter(args)
@ -714,17 +714,18 @@ func (l *loggingT) printDepth(s severity.Severity, logger *logr.Logger, filter L
l.output(s, logger, buf, depth, file, line, false) l.output(s, logger, buf, depth, file, line, false)
} }
func (l *loggingT) printf(s severity.Severity, logger *logr.Logger, filter LogFilter, format string, args ...interface{}) { func (l *loggingT) printf(s severity.Severity, logger *logWriter, filter LogFilter, format string, args ...interface{}) {
l.printfDepth(s, logger, filter, 1, format, args...) l.printfDepth(s, logger, filter, 1, format, args...)
} }
func (l *loggingT) printfDepth(s severity.Severity, logger *logr.Logger, filter LogFilter, depth int, format string, args ...interface{}) { func (l *loggingT) printfDepth(s severity.Severity, logger *logWriter, filter LogFilter, depth int, format string, args ...interface{}) {
buf, file, line := l.header(s, depth) buf, file, line := l.header(s, depth)
// if logr is set, we clear the generated header as we rely on the backing // If a logger is set and doesn't support writing a formatted buffer,
// logr implementation to print headers // we clear the generated header as we rely on the backing
if logger != nil { // logger implementation to print headers.
l.bufferCache.PutBuffer(buf) if logger != nil && logger.writeKlogBuffer == nil {
buf = l.bufferCache.GetBuffer() buffer.PutBuffer(buf)
buf = buffer.GetBuffer()
} }
if filter != nil { if filter != nil {
format, args = filter.FilterF(format, args) format, args = filter.FilterF(format, args)
@ -739,13 +740,14 @@ func (l *loggingT) printfDepth(s severity.Severity, logger *logr.Logger, filter
// printWithFileLine behaves like print but uses the provided file and line number. If // printWithFileLine behaves like print but uses the provided file and line number. If
// alsoLogToStderr is true, the log message always appears on standard error; it // alsoLogToStderr is true, the log message always appears on standard error; it
// will also appear in the log file unless --logtostderr is set. // will also appear in the log file unless --logtostderr is set.
func (l *loggingT) printWithFileLine(s severity.Severity, logger *logr.Logger, filter LogFilter, file string, line int, alsoToStderr bool, args ...interface{}) { func (l *loggingT) printWithFileLine(s severity.Severity, logger *logWriter, filter LogFilter, file string, line int, alsoToStderr bool, args ...interface{}) {
buf := l.formatHeader(s, file, line) buf := l.formatHeader(s, file, line)
// if logr is set, we clear the generated header as we rely on the backing // If a logger is set and doesn't support writing a formatted buffer,
// logr implementation to print headers // we clear the generated header as we rely on the backing
if logger != nil { // logger implementation to print headers.
l.bufferCache.PutBuffer(buf) if logger != nil && logger.writeKlogBuffer == nil {
buf = l.bufferCache.GetBuffer() buffer.PutBuffer(buf)
buf = buffer.GetBuffer()
} }
if filter != nil { if filter != nil {
args = filter.Filter(args) args = filter.Filter(args)
@ -758,7 +760,7 @@ func (l *loggingT) printWithFileLine(s severity.Severity, logger *logr.Logger, f
} }
// if loggr is specified, will call loggr.Error, otherwise output with logging module. // if loggr is specified, will call loggr.Error, otherwise output with logging module.
func (l *loggingT) errorS(err error, logger *logr.Logger, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { func (l *loggingT) errorS(err error, logger *logWriter, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) {
if filter != nil { if filter != nil {
msg, keysAndValues = filter.FilterS(msg, keysAndValues) msg, keysAndValues = filter.FilterS(msg, keysAndValues)
} }
@ -770,7 +772,7 @@ func (l *loggingT) errorS(err error, logger *logr.Logger, filter LogFilter, dept
} }
// if loggr is specified, will call loggr.Info, otherwise output with logging module. // if loggr is specified, will call loggr.Info, otherwise output with logging module.
func (l *loggingT) infoS(logger *logr.Logger, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { func (l *loggingT) infoS(logger *logWriter, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) {
if filter != nil { if filter != nil {
msg, keysAndValues = filter.FilterS(msg, keysAndValues) msg, keysAndValues = filter.FilterS(msg, keysAndValues)
} }
@ -785,7 +787,7 @@ func (l *loggingT) infoS(logger *logr.Logger, filter LogFilter, depth int, msg s
// set log severity by s // set log severity by s
func (l *loggingT) printS(err error, s severity.Severity, depth int, msg string, keysAndValues ...interface{}) { func (l *loggingT) printS(err error, s severity.Severity, depth int, msg string, keysAndValues ...interface{}) {
// Only create a new buffer if we don't have one cached. // Only create a new buffer if we don't have one cached.
b := l.bufferCache.GetBuffer() b := buffer.GetBuffer()
// The message is always quoted, even if it contains line breaks. // The message is always quoted, even if it contains line breaks.
// If developers want multi-line output, they should use a small, fixed // If developers want multi-line output, they should use a small, fixed
// message and put the multi-line output into a value. // message and put the multi-line output into a value.
@ -796,7 +798,7 @@ func (l *loggingT) printS(err error, s severity.Severity, depth int, msg string,
serialize.KVListFormat(&b.Buffer, keysAndValues...) serialize.KVListFormat(&b.Buffer, keysAndValues...)
l.printDepth(s, logging.logger, nil, depth+1, &b.Buffer) l.printDepth(s, logging.logger, nil, depth+1, &b.Buffer)
// Make the buffer available for reuse. // Make the buffer available for reuse.
l.bufferCache.PutBuffer(b) buffer.PutBuffer(b)
} }
// redirectBuffer is used to set an alternate destination for the logs // redirectBuffer is used to set an alternate destination for the logs
@ -851,7 +853,7 @@ func LogToStderr(stderr bool) {
} }
// output writes the data to the log files and releases the buffer. // output writes the data to the log files and releases the buffer.
func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buffer, depth int, file string, line int, alsoToStderr bool) { func (l *loggingT) output(s severity.Severity, logger *logWriter, buf *buffer.Buffer, depth int, file string, line int, alsoToStderr bool) {
var isLocked = true var isLocked = true
l.mu.Lock() l.mu.Lock()
defer func() { defer func() {
@ -867,13 +869,17 @@ func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buf
} }
} }
data := buf.Bytes() data := buf.Bytes()
if log != nil { if logger != nil {
if logger.writeKlogBuffer != nil {
logger.writeKlogBuffer(data)
} else {
// TODO: set 'severity' and caller information as structured log info // TODO: set 'severity' and caller information as structured log info
// keysAndValues := []interface{}{"severity", severityName[s], "file", file, "line", line} // keysAndValues := []interface{}{"severity", severityName[s], "file", file, "line", line}
if s == severity.ErrorLog { if s == severity.ErrorLog {
logging.logger.WithCallDepth(depth+3).Error(nil, string(data)) logger.WithCallDepth(depth+3).Error(nil, string(data))
} else { } else {
log.WithCallDepth(depth + 3).Info(string(data)) logger.WithCallDepth(depth + 3).Info(string(data))
}
} }
} else if l.toStderr { } else if l.toStderr {
os.Stderr.Write(data) os.Stderr.Write(data)
@ -948,7 +954,7 @@ func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buf
timeoutFlush(ExitFlushTimeout) timeoutFlush(ExitFlushTimeout)
OsExit(255) // C++ uses -1, which is silly because it's anded with 255 anyway. OsExit(255) // C++ uses -1, which is silly because it's anded with 255 anyway.
} }
l.bufferCache.PutBuffer(buf) buffer.PutBuffer(buf)
if stats := severityStats[s]; stats != nil { if stats := severityStats[s]; stats != nil {
atomic.AddInt64(&stats.lines, 1) atomic.AddInt64(&stats.lines, 1)
@ -1282,7 +1288,7 @@ func (l *loggingT) setV(pc uintptr) Level {
// See the documentation of V for more information. // See the documentation of V for more information.
type Verbose struct { type Verbose struct {
enabled bool enabled bool
logr *logr.Logger logger *logWriter
} }
func newVerbose(level Level, b bool) Verbose { func newVerbose(level Level, b bool) Verbose {
@ -1290,7 +1296,7 @@ func newVerbose(level Level, b bool) Verbose {
return Verbose{b, nil} return Verbose{b, nil}
} }
v := logging.logger.V(int(level)) v := logging.logger.V(int(level))
return Verbose{b, &v} return Verbose{b, &logWriter{Logger: v, writeKlogBuffer: logging.loggerOptions.writeKlogBuffer}}
} }
// V reports whether verbosity at the call site is at least the requested level. // V reports whether verbosity at the call site is at least the requested level.
@ -1313,6 +1319,13 @@ func newVerbose(level Level, b bool) Verbose {
// less than or equal to the value of the -vmodule pattern matching the source file // less than or equal to the value of the -vmodule pattern matching the source file
// containing the call. // containing the call.
func V(level Level) Verbose { func V(level Level) Verbose {
return VDepth(1, level)
}
// VDepth is a variant of V that accepts a number of stack frames that will be
// skipped when checking the -vmodule patterns. VDepth(0) is equivalent to
// V().
func VDepth(depth int, level Level) Verbose {
// This function tries hard to be cheap unless there's work to do. // This function tries hard to be cheap unless there's work to do.
// The fast path is two atomic loads and compares. // The fast path is two atomic loads and compares.
@ -1329,7 +1342,7 @@ func V(level Level) Verbose {
// but if V logging is enabled we're slow anyway. // but if V logging is enabled we're slow anyway.
logging.mu.Lock() logging.mu.Lock()
defer logging.mu.Unlock() defer logging.mu.Unlock()
if runtime.Callers(2, logging.pcs[:]) == 0 { if runtime.Callers(2+depth, logging.pcs[:]) == 0 {
return newVerbose(level, false) return newVerbose(level, false)
} }
// runtime.Callers returns "return PCs", but we want // runtime.Callers returns "return PCs", but we want
@ -1357,7 +1370,7 @@ func (v Verbose) Enabled() bool {
// See the documentation of V for usage. // See the documentation of V for usage.
func (v Verbose) Info(args ...interface{}) { func (v Verbose) Info(args ...interface{}) {
if v.enabled { if v.enabled {
logging.print(severity.InfoLog, v.logr, logging.filter, args...) logging.print(severity.InfoLog, v.logger, logging.filter, args...)
} }
} }
@ -1365,7 +1378,7 @@ func (v Verbose) Info(args ...interface{}) {
// See the documentation of V for usage. // See the documentation of V for usage.
func (v Verbose) InfoDepth(depth int, args ...interface{}) { func (v Verbose) InfoDepth(depth int, args ...interface{}) {
if v.enabled { if v.enabled {
logging.printDepth(severity.InfoLog, v.logr, logging.filter, depth, args...) logging.printDepth(severity.InfoLog, v.logger, logging.filter, depth, args...)
} }
} }
@ -1373,7 +1386,7 @@ func (v Verbose) InfoDepth(depth int, args ...interface{}) {
// See the documentation of V for usage. // See the documentation of V for usage.
func (v Verbose) Infoln(args ...interface{}) { func (v Verbose) Infoln(args ...interface{}) {
if v.enabled { if v.enabled {
logging.println(severity.InfoLog, v.logr, logging.filter, args...) logging.println(severity.InfoLog, v.logger, logging.filter, args...)
} }
} }
@ -1381,7 +1394,7 @@ func (v Verbose) Infoln(args ...interface{}) {
// See the documentation of V for usage. // See the documentation of V for usage.
func (v Verbose) InfolnDepth(depth int, args ...interface{}) { func (v Verbose) InfolnDepth(depth int, args ...interface{}) {
if v.enabled { if v.enabled {
logging.printlnDepth(severity.InfoLog, v.logr, logging.filter, depth, args...) logging.printlnDepth(severity.InfoLog, v.logger, logging.filter, depth, args...)
} }
} }
@ -1389,7 +1402,7 @@ func (v Verbose) InfolnDepth(depth int, args ...interface{}) {
// See the documentation of V for usage. // See the documentation of V for usage.
func (v Verbose) Infof(format string, args ...interface{}) { func (v Verbose) Infof(format string, args ...interface{}) {
if v.enabled { if v.enabled {
logging.printf(severity.InfoLog, v.logr, logging.filter, format, args...) logging.printf(severity.InfoLog, v.logger, logging.filter, format, args...)
} }
} }
@ -1397,7 +1410,7 @@ func (v Verbose) Infof(format string, args ...interface{}) {
// See the documentation of V for usage. // See the documentation of V for usage.
func (v Verbose) InfofDepth(depth int, format string, args ...interface{}) { func (v Verbose) InfofDepth(depth int, format string, args ...interface{}) {
if v.enabled { if v.enabled {
logging.printfDepth(severity.InfoLog, v.logr, logging.filter, depth, format, args...) logging.printfDepth(severity.InfoLog, v.logger, logging.filter, depth, format, args...)
} }
} }
@ -1405,7 +1418,7 @@ func (v Verbose) InfofDepth(depth int, format string, args ...interface{}) {
// See the documentation of V for usage. // See the documentation of V for usage.
func (v Verbose) InfoS(msg string, keysAndValues ...interface{}) { func (v Verbose) InfoS(msg string, keysAndValues ...interface{}) {
if v.enabled { if v.enabled {
logging.infoS(v.logr, logging.filter, 0, msg, keysAndValues...) logging.infoS(v.logger, logging.filter, 0, msg, keysAndValues...)
} }
} }
@ -1419,14 +1432,14 @@ func InfoSDepth(depth int, msg string, keysAndValues ...interface{}) {
// See the documentation of V for usage. // See the documentation of V for usage.
func (v Verbose) InfoSDepth(depth int, msg string, keysAndValues ...interface{}) { func (v Verbose) InfoSDepth(depth int, msg string, keysAndValues ...interface{}) {
if v.enabled { if v.enabled {
logging.infoS(v.logr, logging.filter, depth, msg, keysAndValues...) logging.infoS(v.logger, logging.filter, depth, msg, keysAndValues...)
} }
} }
// Deprecated: Use ErrorS instead. // Deprecated: Use ErrorS instead.
func (v Verbose) Error(err error, msg string, args ...interface{}) { func (v Verbose) Error(err error, msg string, args ...interface{}) {
if v.enabled { if v.enabled {
logging.errorS(err, v.logr, logging.filter, 0, msg, args...) logging.errorS(err, v.logger, logging.filter, 0, msg, args...)
} }
} }
@ -1434,7 +1447,7 @@ func (v Verbose) Error(err error, msg string, args ...interface{}) {
// See the documentation of V for usage. // See the documentation of V for usage.
func (v Verbose) ErrorS(err error, msg string, keysAndValues ...interface{}) { func (v Verbose) ErrorS(err error, msg string, keysAndValues ...interface{}) {
if v.enabled { if v.enabled {
logging.errorS(err, v.logr, logging.filter, 0, msg, keysAndValues...) logging.errorS(err, v.logger, logging.filter, 0, msg, keysAndValues...)
} }
} }

12
vendor/k8s.io/klog/v2/klogr.go generated vendored
View file

@ -42,19 +42,21 @@ func (l *klogger) Init(info logr.RuntimeInfo) {
l.callDepth += info.CallDepth l.callDepth += info.CallDepth
} }
func (l klogger) Info(level int, msg string, kvList ...interface{}) { func (l *klogger) Info(level int, msg string, kvList ...interface{}) {
merged := serialize.MergeKVs(l.values, kvList) merged := serialize.MergeKVs(l.values, kvList)
if l.prefix != "" { if l.prefix != "" {
msg = l.prefix + ": " + msg msg = l.prefix + ": " + msg
} }
V(Level(level)).InfoSDepth(l.callDepth+1, msg, merged...) // Skip this function.
VDepth(l.callDepth+1, Level(level)).InfoSDepth(l.callDepth+1, msg, merged...)
} }
func (l klogger) Enabled(level int) bool { func (l *klogger) Enabled(level int) bool {
return V(Level(level)).Enabled() // Skip this function and logr.Logger.Info where Enabled is called.
return VDepth(l.callDepth+2, Level(level)).Enabled()
} }
func (l klogger) Error(err error, msg string, kvList ...interface{}) { func (l *klogger) Error(err error, msg string, kvList ...interface{}) {
merged := serialize.MergeKVs(l.values, kvList) merged := serialize.MergeKVs(l.values, kvList)
if l.prefix != "" { if l.prefix != "" {
msg = l.prefix + ": " + msg msg = l.prefix + ": " + msg

2
vendor/modules.txt vendored
View file

@ -1379,7 +1379,7 @@ gotest.tools/v3/internal/format
gotest.tools/v3/internal/source gotest.tools/v3/internal/source
gotest.tools/v3/poll gotest.tools/v3/poll
gotest.tools/v3/skip gotest.tools/v3/skip
# k8s.io/klog/v2 v2.80.1 # k8s.io/klog/v2 v2.90.1
## explicit; go 1.13 ## explicit; go 1.13
k8s.io/klog/v2 k8s.io/klog/v2
k8s.io/klog/v2/internal/buffer k8s.io/klog/v2/internal/buffer