2 Copyright 2018 The Kubernetes Authors.
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
20 "github.com/go-logr/logr"
23 // loggerPromise knows how to populate a concrete logr.Logger
24 // with options, given an actual base logger later on down the line.
25 type loggerPromise struct {
26 logger *DelegatingLogger
27 childPromises []*loggerPromise
33 // WithName provides a new Logger with the name appended
34 func (p *loggerPromise) WithName(l *DelegatingLogger, name string) *loggerPromise {
35 res := &loggerPromise{
39 p.childPromises = append(p.childPromises, res)
43 // WithValues provides a new Logger with the tags appended
44 func (p *loggerPromise) WithValues(l *DelegatingLogger, tags ...interface{}) *loggerPromise {
45 res := &loggerPromise{
49 p.childPromises = append(p.childPromises, res)
53 // Fulfill instantiates the Logger with the provided logger
54 func (p *loggerPromise) Fulfill(parentLogger logr.Logger) {
55 var logger = parentLogger
57 logger = logger.WithName(*p.name)
61 logger = logger.WithValues(p.tags...)
64 p.logger.Logger = logger
65 p.logger.promise = nil
67 for _, childPromise := range p.childPromises {
68 childPromise.Fulfill(logger)
72 // DelegatingLogger is a logr.Logger that delegates to another logr.Logger.
73 // If the underlying promise is not nil, it registers calls to sub-loggers with
74 // the logging factory to be populated later, and returns a new delegating
75 // logger. It expects to have *some* logr.Logger set at all times (generally
76 // a no-op logger before the promises are fulfilled).
77 type DelegatingLogger struct {
79 promise *loggerPromise
82 // WithName provides a new Logger with the name appended
83 func (l *DelegatingLogger) WithName(name string) logr.Logger {
85 return l.Logger.WithName(name)
88 res := &DelegatingLogger{Logger: l.Logger}
89 promise := l.promise.WithName(res, name)
95 // WithValues provides a new Logger with the tags appended
96 func (l *DelegatingLogger) WithValues(tags ...interface{}) logr.Logger {
98 return l.Logger.WithValues(tags...)
101 res := &DelegatingLogger{Logger: l.Logger}
102 promise := l.promise.WithValues(res, tags...)
103 res.promise = promise
108 // Fulfill switches the logger over to use the actual logger
109 // provided, instead of the temporary initial one, if this method
110 // has not been previously called.
111 func (l *DelegatingLogger) Fulfill(actual logr.Logger) {
112 if l.promise != nil {
113 l.promise.Fulfill(actual)
117 // NewDelegatingLogger constructs a new DelegatingLogger which uses
118 // the given logger before it's promise is fulfilled.
119 func NewDelegatingLogger(initial logr.Logger) *DelegatingLogger {
120 l := &DelegatingLogger{
122 promise: &loggerPromise{},