diff --git a/staging/src/k8s.io/apiextensions-apiserver/go.sum b/staging/src/k8s.io/apiextensions-apiserver/go.sum index 333440ddfd0..b9ba502e5b5 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/go.sum +++ b/staging/src/k8s.io/apiextensions-apiserver/go.sum @@ -153,6 +153,7 @@ github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= diff --git a/staging/src/k8s.io/apiserver/go.sum b/staging/src/k8s.io/apiserver/go.sum index 97d6da005bb..f5969550016 100644 --- a/staging/src/k8s.io/apiserver/go.sum +++ b/staging/src/k8s.io/apiserver/go.sum @@ -166,6 +166,7 @@ github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= diff --git a/staging/src/k8s.io/cloud-provider/go.sum b/staging/src/k8s.io/cloud-provider/go.sum index 42f0052728d..5c63dc6fb2a 100644 --- a/staging/src/k8s.io/cloud-provider/go.sum +++ b/staging/src/k8s.io/cloud-provider/go.sum @@ -124,6 +124,7 @@ github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= diff --git a/staging/src/k8s.io/component-base/logs/api/v1/options.go b/staging/src/k8s.io/component-base/logs/api/v1/options.go index 6270b2eb96f..9990e31fff2 100644 --- a/staging/src/k8s.io/component-base/logs/api/v1/options.go +++ b/staging/src/k8s.io/component-base/logs/api/v1/options.go @@ -19,7 +19,9 @@ package v1 import ( "flag" "fmt" + "io" "math" + "os" "strings" "time" @@ -31,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" cliflag "k8s.io/component-base/cli/flag" "k8s.io/component-base/featuregate" + "k8s.io/component-base/logs/internal/setverbositylevel" "k8s.io/component-base/logs/klogflags" ) @@ -62,18 +65,41 @@ func NewLoggingConfiguration() *LoggingConfiguration { // The optional FeatureGate controls logging features. If nil, the default for // these features is used. func ValidateAndApply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { - return ValidateAndApplyAsField(c, featureGate, nil) + return validateAndApply(c, nil, featureGate, nil) +} + +// ValidateAndApplyWithOptions is a variant of ValidateAndApply which accepts +// additional options beyond those that can be configured through the API. This +// is meant for testing. +func ValidateAndApplyWithOptions(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate) error { + return validateAndApply(c, options, featureGate, nil) +} + +// +k8s:deepcopy-gen=false + +// LoggingOptions can be used with ValidateAndApplyWithOptions to override +// certain global defaults. +type LoggingOptions struct { + // ErrorStream can be used to override the os.Stderr default. + ErrorStream io.Writer + + // InfoStream can be used to override the os.Stdout default. + InfoStream io.Writer } // ValidateAndApplyAsField is a variant of ValidateAndApply that should be used // when the LoggingConfiguration is embedded in some larger configuration // structure. func ValidateAndApplyAsField(c *LoggingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) error { + return validateAndApply(c, nil, featureGate, fldPath) +} + +func validateAndApply(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate, fldPath *field.Path) error { errs := Validate(c, featureGate, fldPath) if len(errs) > 0 { return errs.ToAggregate() } - return apply(c, featureGate) + return apply(c, options, featureGate) } // Validate can be used to check for invalid settings without applying them. @@ -156,7 +182,7 @@ func featureEnabled(featureGate featuregate.FeatureGate, feature featuregate.Fea return enabled } -func apply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { +func apply(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate) error { contextualLoggingEnabled := contextualLoggingDefault if featureGate != nil { contextualLoggingEnabled = featureGate.Enabled(ContextualLogging) @@ -167,8 +193,19 @@ func apply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { if format.factory == nil { klog.ClearLogger() } else { - log, flush := format.factory.Create(*c) - klog.SetLoggerWithOptions(log, klog.ContextualLogger(contextualLoggingEnabled), klog.FlushLogger(flush)) + if options == nil { + options = &LoggingOptions{ + ErrorStream: os.Stderr, + InfoStream: os.Stdout, + } + } + log, control := format.factory.Create(*c, *options) + if control.SetVerbosityLevel != nil { + setverbositylevel.Mutex.Lock() + defer setverbositylevel.Mutex.Unlock() + setverbositylevel.Callbacks = append(setverbositylevel.Callbacks, control.SetVerbosityLevel) + } + klog.SetLoggerWithOptions(log, klog.ContextualLogger(contextualLoggingEnabled), klog.FlushLogger(control.Flush)) } if err := loggingFlags.Lookup("v").Value.Set(VerbosityLevelPflag(&c.Verbosity).String()); err != nil { return fmt.Errorf("internal error while setting klog verbosity: %v", err) diff --git a/staging/src/k8s.io/component-base/logs/api/v1/registry.go b/staging/src/k8s.io/component-base/logs/api/v1/registry.go index 78bc8f8853f..f8fc1f2cae1 100644 --- a/staging/src/k8s.io/component-base/logs/api/v1/registry.go +++ b/staging/src/k8s.io/component-base/logs/api/v1/registry.go @@ -39,14 +39,29 @@ type logFormat struct { feature featuregate.Feature } +// +k8s:deepcopy-gen=false + +// RuntimeControl provides operations that aren't available through the normal +// Logger or LogSink API. +type RuntimeControl struct { + // Flush ensures that all in-memory data is written. + // May be nil. + Flush func() + + // SetVerbosityLevel changes the level for all Logger instances + // derived from the initial one. May be nil. + // + // The parameter is intentionally a plain uint32 instead of + // VerbosityLevel to enable implementations that don't need to import + // the API (helps avoid circular dependencies). + SetVerbosityLevel func(v uint32) error +} + // LogFormatFactory provides support for a certain additional, // non-default log format. type LogFormatFactory interface { // Create returns a logger with the requested configuration. - // Returning a flush function for the logger is optional. - // If provided, the caller must ensure that it is called - // periodically (if desired) and at program exit. - Create(c LoggingConfiguration) (log logr.Logger, flush func()) + Create(c LoggingConfiguration, o LoggingOptions) (logr.Logger, RuntimeControl) } // RegisterLogFormat registers support for a new logging format. This must be called diff --git a/staging/src/k8s.io/component-base/logs/internal/setverbositylevel/setverbositylevel.go b/staging/src/k8s.io/component-base/logs/internal/setverbositylevel/setverbositylevel.go new file mode 100644 index 00000000000..c643bae9bc3 --- /dev/null +++ b/staging/src/k8s.io/component-base/logs/internal/setverbositylevel/setverbositylevel.go @@ -0,0 +1,34 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package setverbositylevel stores callbacks that will be invoked by logs.GlogLevel. +// +// This is a separate package to avoid a dependency from +// k8s.io/component-base/logs (uses the callbacks) to +// k8s.io/component-base/logs/api/v1 (adds them). Not all users of the logs +// package also use the API. +package setverbositylevel + +import ( + "sync" +) + +var ( + // Mutex controls access to the callbacks. + Mutex sync.Mutex + + Callbacks []func(v uint32) error +) diff --git a/staging/src/k8s.io/component-base/logs/json/json.go b/staging/src/k8s.io/component-base/logs/json/json.go index 1ccd0f3de64..20723687e98 100644 --- a/staging/src/k8s.io/component-base/logs/json/json.go +++ b/staging/src/k8s.io/component-base/logs/json/json.go @@ -14,11 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -package logs +package json import ( "io" - "os" + "sync/atomic" "time" "github.com/go-logr/logr" @@ -35,12 +35,32 @@ var ( timeNow = time.Now ) -// NewJSONLogger creates a new json logr.Logger and its associated -// flush function. The separate error stream is optional and may be nil. -// The encoder config is also optional. -func NewJSONLogger(v logsapi.VerbosityLevel, infoStream, errorStream zapcore.WriteSyncer, encoderConfig *zapcore.EncoderConfig) (logr.Logger, func()) { +type runtime struct { + v uint32 +} + +func (r *runtime) ZapV() zapcore.Level { // zap levels are inverted: everything with a verbosity >= threshold gets logged. - zapV := -zapcore.Level(v) + return -zapcore.Level(atomic.LoadUint32(&r.v)) +} + +// Enabled implements the zapcore.LevelEnabler interface. +func (r *runtime) Enabled(level zapcore.Level) bool { + return level >= r.ZapV() +} + +func (r *runtime) SetVerbosityLevel(v uint32) error { + atomic.StoreUint32(&r.v, v) + return nil +} + +var _ zapcore.LevelEnabler = &runtime{} + +// NewJSONLogger creates a new json logr.Logger and its associated +// control interface. The separate error stream is optional and may be nil. +// The encoder config is also optional. +func NewJSONLogger(v logsapi.VerbosityLevel, infoStream, errorStream zapcore.WriteSyncer, encoderConfig *zapcore.EncoderConfig) (logr.Logger, logsapi.RuntimeControl) { + r := &runtime{v: uint32(v)} if encoderConfig == nil { encoderConfig = &zapcore.EncoderConfig{ @@ -57,13 +77,13 @@ func NewJSONLogger(v logsapi.VerbosityLevel, infoStream, errorStream zapcore.Wri encoder := zapcore.NewJSONEncoder(*encoderConfig) var core zapcore.Core if errorStream == nil { - core = zapcore.NewCore(encoder, infoStream, zapV) + core = zapcore.NewCore(encoder, infoStream, r) } else { highPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { - return lvl >= zapcore.ErrorLevel && lvl >= zapV + return lvl >= zapcore.ErrorLevel && r.Enabled(lvl) }) lowPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { - return lvl < zapcore.ErrorLevel && lvl >= zapV + return lvl < zapcore.ErrorLevel && r.Enabled(lvl) }) core = zapcore.NewTee( zapcore.NewCore(encoder, errorStream, highPriority), @@ -71,9 +91,13 @@ func NewJSONLogger(v logsapi.VerbosityLevel, infoStream, errorStream zapcore.Wri ) } l := zap.New(core, zap.WithCaller(true)) - return zapr.NewLoggerWithOptions(l, zapr.LogInfoLevel("v"), zapr.ErrorKey("err")), func() { - l.Sync() - } + return zapr.NewLoggerWithOptions(l, zapr.LogInfoLevel("v"), zapr.ErrorKey("err")), + logsapi.RuntimeControl{ + SetVerbosityLevel: r.SetVerbosityLevel, + Flush: func() { + _ = l.Sync() + }, + } } func epochMillisTimeEncoder(_ time.Time, enc zapcore.PrimitiveArrayEncoder) { @@ -91,7 +115,7 @@ func (f Factory) Feature() featuregate.Feature { return logsapi.LoggingBetaOptions } -func (f Factory) Create(c logsapi.LoggingConfiguration) (logr.Logger, func()) { +func (f Factory) Create(c logsapi.LoggingConfiguration, o logsapi.LoggingOptions) (logr.Logger, logsapi.RuntimeControl) { // We intentionally avoid all os.File.Sync calls. Output is unbuffered, // therefore we don't need to flush, and calling the underlying fsync // would just slow down writing. @@ -100,9 +124,9 @@ func (f Factory) Create(c logsapi.LoggingConfiguration) (logr.Logger, func()) { // written to the output stream before the process terminates, but // doesn't need to worry about data not being written because of a // system crash or powerloss. - stderr := zapcore.Lock(AddNopSync(os.Stderr)) + stderr := zapcore.Lock(AddNopSync(o.ErrorStream)) if c.Options.JSON.SplitStream { - stdout := zapcore.Lock(AddNopSync(os.Stdout)) + stdout := zapcore.Lock(AddNopSync(o.InfoStream)) size := c.Options.JSON.InfoBufferSize.Value() if size > 0 { // Prevent integer overflow. diff --git a/staging/src/k8s.io/component-base/logs/json/json_benchmark_test.go b/staging/src/k8s.io/component-base/logs/json/json_benchmark_test.go index 76b9fad3429..67e16b83b0d 100644 --- a/staging/src/k8s.io/component-base/logs/json/json_benchmark_test.go +++ b/staging/src/k8s.io/component-base/logs/json/json_benchmark_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package logs +package json import ( "fmt" diff --git a/staging/src/k8s.io/component-base/logs/json/json_test.go b/staging/src/k8s.io/component-base/logs/json/json_test.go index e0492505759..88bba09ef7e 100644 --- a/staging/src/k8s.io/component-base/logs/json/json_test.go +++ b/staging/src/k8s.io/component-base/logs/json/json_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package logs +package json import ( "bytes" diff --git a/staging/src/k8s.io/component-base/logs/json/klog_test.go b/staging/src/k8s.io/component-base/logs/json/klog_test.go index a9a54fc19c4..1439ee3f9e3 100644 --- a/staging/src/k8s.io/component-base/logs/json/klog_test.go +++ b/staging/src/k8s.io/component-base/logs/json/klog_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package logs +package json import ( "bytes" diff --git a/staging/src/k8s.io/component-base/logs/logs.go b/staging/src/k8s.io/component-base/logs/logs.go index 886c154e4bf..7fda0f9117f 100644 --- a/staging/src/k8s.io/component-base/logs/logs.go +++ b/staging/src/k8s.io/component-base/logs/logs.go @@ -23,10 +23,12 @@ import ( "flag" "fmt" "log" + "strconv" "time" "github.com/spf13/pflag" logsapi "k8s.io/component-base/logs/api/v1" + "k8s.io/component-base/logs/internal/setverbositylevel" "k8s.io/component-base/logs/klogflags" "k8s.io/klog/v2" ) @@ -182,11 +184,26 @@ func NewLogger(prefix string) *log.Logger { return log.New(KlogWriter{}, prefix, 0) } -// GlogSetter is a setter to set glog level. +// GlogSetter modifies the verbosity threshold for the entire program. +// Some components have HTTP-based APIs for invoking this at runtime. func GlogSetter(val string) (string, error) { + v, err := strconv.ParseUint(val, 10, 32) + if err != nil { + return "", err + } + var level klog.Level if err := level.Set(val); err != nil { return "", fmt.Errorf("failed set klog.logging.verbosity %s: %v", val, err) } + + setverbositylevel.Mutex.Lock() + defer setverbositylevel.Mutex.Unlock() + for _, cb := range setverbositylevel.Callbacks { + if err := cb(uint32(v)); err != nil { + return "", err + } + } + return fmt.Sprintf("successfully set klog.logging.verbosity to %s", val), nil } diff --git a/staging/src/k8s.io/component-base/logs/logs_test.go b/staging/src/k8s.io/component-base/logs/logs_test.go new file mode 100644 index 00000000000..01f543f12ca --- /dev/null +++ b/staging/src/k8s.io/component-base/logs/logs_test.go @@ -0,0 +1,114 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package logs_test + +import ( + "os" + "path" + "testing" + + "k8s.io/component-base/logs" + logsapi "k8s.io/component-base/logs/api/v1" + _ "k8s.io/component-base/logs/json/register" + "k8s.io/klog/v2" +) + +func TestGlogSetter(t *testing.T) { + testcases := map[string]struct { + init func(t *testing.T) + // write must write at verbosity level 1. + write func() + }{ + "klog": { + init: func(t *testing.T) {}, + write: func() { + klog.V(1).Info("hello") + }, + }, + "json": { + init: func(t *testing.T) { + c := logsapi.NewLoggingConfiguration() + c.Format = "json" + if err := logsapi.ValidateAndApply(c, nil /* feature gates */); err != nil { + t.Fatalf("Unexpected error enabling json output: %v", err) + } + }, + write: func() { + klog.Background().V(1).Info("hello") + }, + }, + "text": { + init: func(t *testing.T) { + c := logsapi.NewLoggingConfiguration() + c.Format = "text" + if err := logsapi.ValidateAndApply(c, nil /* feature gates */); err != nil { + t.Fatalf("Unexpected error enabling text output: %v", err) + } + }, + write: func() { + klog.Background().V(1).Info("hello") + }, + }, + } + + for name, tc := range testcases { + t.Run(name, func(t *testing.T) { + state := klog.CaptureState() + t.Cleanup(state.Restore) + tmpdir := t.TempDir() + tmpfile := path.Join(tmpdir, "stderr.log") + oldStderr := os.Stderr + defer func() { + os.Stderr = oldStderr + }() + newStderr, err := os.Create(tmpfile) + if err != nil { + t.Fatalf("Unexpected error creating temp file: %v", err) + } + os.Stderr = newStderr + + tc.init(t) + + // First write with default verbosity level of 0 -> no output. + tc.write() + klog.Flush() + out, err := os.ReadFile(tmpfile) + if err != nil { + t.Fatalf("Unexpected error reading temp file: %v", err) + } + if len(out) > 0 { + t.Fatalf("Info message should have been discarded, got instead:\n%s", string(out)) + } + + // Increase verbosity at runtime. + if _, err := logs.GlogSetter("1"); err != nil { + t.Fatalf("Unexpected error setting verbosity level: %v", err) + } + + // Now write again -> output. + tc.write() + klog.Flush() + out, err = os.ReadFile(tmpfile) + if err != nil { + t.Fatalf("Unexpected error reading temp file: %v", err) + } + if len(out) == 0 { + t.Fatal("Info message should have been written, got empty file instead.") + } + }) + } +} diff --git a/staging/src/k8s.io/controller-manager/go.sum b/staging/src/k8s.io/controller-manager/go.sum index 0f50c2d182c..70c25be79f0 100644 --- a/staging/src/k8s.io/controller-manager/go.sum +++ b/staging/src/k8s.io/controller-manager/go.sum @@ -120,6 +120,7 @@ github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= diff --git a/staging/src/k8s.io/kube-aggregator/go.sum b/staging/src/k8s.io/kube-aggregator/go.sum index e67d7be010b..9876f7a1547 100644 --- a/staging/src/k8s.io/kube-aggregator/go.sum +++ b/staging/src/k8s.io/kube-aggregator/go.sum @@ -122,6 +122,7 @@ github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= diff --git a/staging/src/k8s.io/sample-apiserver/go.sum b/staging/src/k8s.io/sample-apiserver/go.sum index a3b42e04ca5..dfd69e67adc 100644 --- a/staging/src/k8s.io/sample-apiserver/go.sum +++ b/staging/src/k8s.io/sample-apiserver/go.sum @@ -122,6 +122,7 @@ github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= diff --git a/test/integration/logs/benchmark/benchmark_test.go b/test/integration/logs/benchmark/benchmark_test.go index 91bc8348997..6c071ce38cd 100644 --- a/test/integration/logs/benchmark/benchmark_test.go +++ b/test/integration/logs/benchmark/benchmark_test.go @@ -32,7 +32,6 @@ import ( "testing" "time" - "github.com/go-logr/logr" logsapi "k8s.io/component-base/logs/api/v1" logsjson "k8s.io/component-base/logs/json" "k8s.io/klog/v2" @@ -175,9 +174,6 @@ func benchmarkOutputFormats(b *testing.B, config loadGeneratorConfig, discard bo generateOutput(b, config, nil, out) }) b.Run("JSON", func(b *testing.B) { - c := logsapi.NewLoggingConfiguration() - var logger logr.Logger - var flush func() var out1, out2 *os.File if !discard { var err error @@ -192,38 +188,30 @@ func benchmarkOutputFormats(b *testing.B, config loadGeneratorConfig, discard bo } defer out2.Close() } + o := logsapi.LoggingOptions{} + if discard { + o.ErrorStream = io.Discard + o.InfoStream = io.Discard + } else { + o.ErrorStream = out1 + o.InfoStream = out1 + } + b.Run("single-stream", func(b *testing.B) { - if discard { - logger, flush = logsjson.NewJSONLogger(c.Verbosity, logsjson.AddNopSync(&output), nil, nil) - } else { - stderr := os.Stderr - os.Stderr = out1 - defer func() { - os.Stderr = stderr - }() - logger, flush = logsjson.Factory{}.Create(*c) - } + c := logsapi.NewLoggingConfiguration() + logger, control := logsjson.Factory{}.Create(*c, o) klog.SetLogger(logger) defer klog.ClearLogger() - generateOutput(b, config, flush, out1) + generateOutput(b, config, control.Flush, out1) }) b.Run("split-stream", func(b *testing.B) { - if discard { - logger, flush = logsjson.NewJSONLogger(c.Verbosity, logsjson.AddNopSync(&output), logsjson.AddNopSync(&output), nil) - } else { - stdout, stderr := os.Stdout, os.Stderr - os.Stdout, os.Stderr = out1, out2 - defer func() { - os.Stdout, os.Stderr = stdout, stderr - }() - c := logsapi.NewLoggingConfiguration() - c.Options.JSON.SplitStream = true - logger, flush = logsjson.Factory{}.Create(*c) - } + c := logsapi.NewLoggingConfiguration() + c.Options.JSON.SplitStream = true + logger, control := logsjson.Factory{}.Create(*c, o) klog.SetLogger(logger) defer klog.ClearLogger() - generateOutput(b, config, flush, out1, out2) + generateOutput(b, config, control.Flush, out1, out2) }) }) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 273473d1e76..2f8ee36c383 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1998,6 +1998,7 @@ k8s.io/component-base/featuregate k8s.io/component-base/featuregate/testing k8s.io/component-base/logs k8s.io/component-base/logs/api/v1 +k8s.io/component-base/logs/internal/setverbositylevel k8s.io/component-base/logs/json k8s.io/component-base/logs/json/register k8s.io/component-base/logs/klogflags