Skip to content

Commit

Permalink
contextual logging: SetContextualLogger -> SetLoggerWithOptions
Browse files Browse the repository at this point in the history
The advantage of SetLoggerWithOptions is that it can be used as a drop-in
replacement for SetLogger, which allows us to deprecate SetLogger. Whether we
actually do that is kept open for now.
  • Loading branch information
pohly committed Mar 11, 2022
1 parent df761fd commit 9bfd948
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
34 changes: 32 additions & 2 deletions contextual.go
Expand Up @@ -56,7 +56,7 @@ var (
// verbosity checks before calling logger.V().Info. logger.Error is always
// called, regardless of the klog verbosity settings.
//
// If set, all log lines will be suppressed from the regular Output, and
// If set, all log lines will be suppressed from the regular output, and
// redirected to the logr implementation.
// Use as:
// ...
Expand All @@ -68,8 +68,38 @@ var (
// Modifying the logger is not thread-safe and should be done while no other
// goroutines invoke log calls, usually during program initialization.
func SetLogger(logger logr.Logger) {
SetLoggerWithOptions(logger)
}

// SetLoggerWithOptions is a more flexible version of SetLogger. Without
// additional options, it behaves exactly like SetLogger. By passing
// ContextualLogger(true) as option, it can be used to set a logger that then
// will also get called directly by applications which retrieve it via
// FromContext, Background, or TODO.
func SetLoggerWithOptions(logger logr.Logger, opts ...LoggerOption) {
globalLogger = &logger
contextualLogger = false
var o loggerOptions
for _, opt := range opts {
opt(&o)
}
contextualLogger = o.contextualLogger
}

// ContextualLogger determines whether the logger passed to
// SetLoggerWithOptions may also get called directly. Such a logger cannot rely
// on verbosity checking in klog.
func ContextualLogger(enabled bool) LoggerOption {
return func(o *loggerOptions) {
o.contextualLogger = enabled
}
}

// LoggerOption implements the functional parameter paradigm for
// SetLoggerWithOptions.
type LoggerOption func(o *loggerOptions)

type loggerOptions struct {
contextualLogger bool
}

// SetContextualLogger does the same as SetLogger, but in addition the
Expand Down
43 changes: 43 additions & 0 deletions contextual_test.go
@@ -0,0 +1,43 @@
/*
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 klog_test

import (
"fmt"

"github.com/go-logr/logr"
"k8s.io/klog/v2"
)

func ExampleSetLogger() {
// Logger is only used as backend, Background() returns klogr.
klog.SetLogger(logr.Discard())
fmt.Printf("logger after SetLogger: %T\n", klog.Background().GetSink())

// Logger is only used as backend, Background() returns klogr.
klog.SetLoggerWithOptions(logr.Discard(), klog.ContextualLogger(false))
fmt.Printf("logger after SetLoggerWithOptions with ContextualLogger(false): %T\n", klog.Background().GetSink())

// Logger is used as backend and directly.
klog.SetLoggerWithOptions(logr.Discard(), klog.ContextualLogger(true))
fmt.Printf("logger after SetLoggerWithOptions with ContextualLogger(true): %T\n", klog.Background().GetSink())

// Output:
// logger after SetLogger: *klog.klogger
// logger after SetLoggerWithOptions with ContextualLogger(false): *klog.klogger
// logger after SetLoggerWithOptions with ContextualLogger(true): logr.discardLogSink
}

0 comments on commit 9bfd948

Please sign in to comment.