...
1
16
17 package log
18
19 import (
20 "sync"
21
22 "github.com/go-logr/logr"
23 )
24
25
26
27 type loggerPromise struct {
28 logger *delegatingLogSink
29 childPromises []*loggerPromise
30 promisesLock sync.Mutex
31
32 name *string
33 tags []interface{}
34 }
35
36 func (p *loggerPromise) WithName(l *delegatingLogSink, name string) *loggerPromise {
37 res := &loggerPromise{
38 logger: l,
39 name: &name,
40 promisesLock: sync.Mutex{},
41 }
42
43 p.promisesLock.Lock()
44 defer p.promisesLock.Unlock()
45 p.childPromises = append(p.childPromises, res)
46 return res
47 }
48
49
50 func (p *loggerPromise) WithValues(l *delegatingLogSink, tags ...interface{}) *loggerPromise {
51 res := &loggerPromise{
52 logger: l,
53 tags: tags,
54 promisesLock: sync.Mutex{},
55 }
56
57 p.promisesLock.Lock()
58 defer p.promisesLock.Unlock()
59 p.childPromises = append(p.childPromises, res)
60 return res
61 }
62
63
64 func (p *loggerPromise) Fulfill(parentLogSink logr.LogSink) {
65 sink := parentLogSink
66 if p.name != nil {
67 sink = sink.WithName(*p.name)
68 }
69
70 if p.tags != nil {
71 sink = sink.WithValues(p.tags...)
72 }
73
74 p.logger.lock.Lock()
75 p.logger.logger = sink
76 if withCallDepth, ok := sink.(logr.CallDepthLogSink); ok {
77 p.logger.logger = withCallDepth.WithCallDepth(1)
78 }
79 p.logger.promise = nil
80 p.logger.lock.Unlock()
81
82 for _, childPromise := range p.childPromises {
83 childPromise.Fulfill(sink)
84 }
85 }
86
87
88
89
90
91
92 type delegatingLogSink struct {
93 lock sync.RWMutex
94 logger logr.LogSink
95 promise *loggerPromise
96 info logr.RuntimeInfo
97 }
98
99
100 func (l *delegatingLogSink) Init(info logr.RuntimeInfo) {
101 eventuallyFulfillRoot()
102 l.lock.Lock()
103 defer l.lock.Unlock()
104 l.info = info
105 }
106
107
108
109
110 func (l *delegatingLogSink) Enabled(level int) bool {
111 eventuallyFulfillRoot()
112 l.lock.RLock()
113 defer l.lock.RUnlock()
114 return l.logger.Enabled(level)
115 }
116
117
118
119
120
121
122
123 func (l *delegatingLogSink) Info(level int, msg string, keysAndValues ...interface{}) {
124 eventuallyFulfillRoot()
125 l.lock.RLock()
126 defer l.lock.RUnlock()
127 l.logger.Info(level, msg, keysAndValues...)
128 }
129
130
131
132
133
134
135
136
137
138 func (l *delegatingLogSink) Error(err error, msg string, keysAndValues ...interface{}) {
139 eventuallyFulfillRoot()
140 l.lock.RLock()
141 defer l.lock.RUnlock()
142 l.logger.Error(err, msg, keysAndValues...)
143 }
144
145
146 func (l *delegatingLogSink) WithName(name string) logr.LogSink {
147 eventuallyFulfillRoot()
148 l.lock.RLock()
149 defer l.lock.RUnlock()
150
151 if l.promise == nil {
152 sink := l.logger.WithName(name)
153 if withCallDepth, ok := sink.(logr.CallDepthLogSink); ok {
154 sink = withCallDepth.WithCallDepth(-1)
155 }
156 return sink
157 }
158
159 res := &delegatingLogSink{logger: l.logger}
160 promise := l.promise.WithName(res, name)
161 res.promise = promise
162
163 return res
164 }
165
166
167 func (l *delegatingLogSink) WithValues(tags ...interface{}) logr.LogSink {
168 eventuallyFulfillRoot()
169 l.lock.RLock()
170 defer l.lock.RUnlock()
171
172 if l.promise == nil {
173 sink := l.logger.WithValues(tags...)
174 if withCallDepth, ok := sink.(logr.CallDepthLogSink); ok {
175 sink = withCallDepth.WithCallDepth(-1)
176 }
177 return sink
178 }
179
180 res := &delegatingLogSink{logger: l.logger}
181 promise := l.promise.WithValues(res, tags...)
182 res.promise = promise
183
184 return res
185 }
186
187
188
189
190 func (l *delegatingLogSink) Fulfill(actual logr.LogSink) {
191 if actual == nil {
192 actual = NullLogSink{}
193 }
194 if l.promise != nil {
195 l.promise.Fulfill(actual)
196 }
197 }
198
199
200
201 func newDelegatingLogSink(initial logr.LogSink) *delegatingLogSink {
202 l := &delegatingLogSink{
203 logger: initial,
204 promise: &loggerPromise{promisesLock: sync.Mutex{}},
205 }
206 l.promise.logger = l
207 return l
208 }
209
View as plain text