Skip to content

Commit 0354f47

Browse files
authored
Merge pull request #3149 from sbueringer/pr-adopt-ctx-logging
⚠ Improve logging by adopting contextual logging
2 parents 2366fb2 + 32fa5a8 commit 0354f47

File tree

8 files changed

+69
-26
lines changed

8 files changed

+69
-26
lines changed

pkg/cache/cache.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ type Informer interface {
113113
// the handler again and an error if the handler cannot be added.
114114
AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) (toolscache.ResourceEventHandlerRegistration, error)
115115

116+
// AddEventHandlerWithOptions is a variant of AddEventHandlerWithResyncPeriod where
117+
// all optional parameters are passed in as a struct.
118+
AddEventHandlerWithOptions(handler toolscache.ResourceEventHandler, options toolscache.HandlerOptions) (toolscache.ResourceEventHandlerRegistration, error)
119+
116120
// RemoveEventHandler removes a previously added event handler given by
117121
// its registration handle.
118122
// This function is guaranteed to be idempotent and thread-safe.
@@ -207,11 +211,11 @@ type Options struct {
207211
// to reduce the caches memory usage.
208212
DefaultTransform toolscache.TransformFunc
209213

210-
// DefaultWatchErrorHandler will be used to the WatchErrorHandler which is called
214+
// DefaultWatchErrorHandler will be used to set the WatchErrorHandler which is called
211215
// whenever ListAndWatch drops the connection with an error.
212216
//
213217
// After calling this handler, the informer will backoff and retry.
214-
DefaultWatchErrorHandler toolscache.WatchErrorHandler
218+
DefaultWatchErrorHandler toolscache.WatchErrorHandlerWithContext
215219

216220
// DefaultUnsafeDisableDeepCopy is the default for UnsafeDisableDeepCopy
217221
// for everything that doesn't specify this.

pkg/cache/internal/informers.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,26 @@ import (
2525
"sync"
2626
"time"
2727

28+
"github.com/go-logr/logr"
2829
apierrors "k8s.io/apimachinery/pkg/api/errors"
2930
"k8s.io/apimachinery/pkg/api/meta"
3031
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3132
"k8s.io/apimachinery/pkg/runtime"
3233
"k8s.io/apimachinery/pkg/runtime/schema"
3334
"k8s.io/apimachinery/pkg/runtime/serializer"
35+
"k8s.io/apimachinery/pkg/util/wait"
3436
"k8s.io/apimachinery/pkg/watch"
3537
"k8s.io/client-go/dynamic"
3638
"k8s.io/client-go/metadata"
3739
"k8s.io/client-go/rest"
3840
"k8s.io/client-go/tools/cache"
3941
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
42+
logf "sigs.k8s.io/controller-runtime/pkg/internal/log"
4043
"sigs.k8s.io/controller-runtime/pkg/internal/syncs"
4144
)
4245

46+
var log = logf.RuntimeLog.WithName("cache")
47+
4348
// InformersOpts configures an InformerMap.
4449
type InformersOpts struct {
4550
HTTPClient *http.Client
@@ -52,7 +57,7 @@ type InformersOpts struct {
5257
Transform cache.TransformFunc
5358
UnsafeDisableDeepCopy bool
5459
EnableWatchBookmarks bool
55-
WatchErrorHandler cache.WatchErrorHandler
60+
WatchErrorHandler cache.WatchErrorHandlerWithContext
5661
}
5762

5863
// NewInformers creates a new InformersMap that can create informers under the hood.
@@ -105,7 +110,8 @@ func (c *Cache) Start(stop <-chan struct{}) {
105110
// Stop on either the whole map stopping or just this informer being removed.
106111
internalStop, cancel := syncs.MergeChans(stop, c.stop)
107112
defer cancel()
108-
c.Informer.Run(internalStop)
113+
// Convert the stop channel to a context and then add the logger.
114+
c.Informer.RunWithContext(logr.NewContext(wait.ContextForChannel(internalStop), log))
109115
}
110116

111117
type tracker struct {
@@ -181,10 +187,10 @@ type Informers struct {
181187
// NewInformer allows overriding of the shared index informer constructor for testing.
182188
newInformer func(cache.ListerWatcher, runtime.Object, time.Duration, cache.Indexers) cache.SharedIndexInformer
183189

184-
// WatchErrorHandler allows the shared index informer's
190+
// watchErrorHandler allows the shared index informer's
185191
// watchErrorHandler to be set by overriding the options
186192
// or to use the default watchErrorHandler
187-
watchErrorHandler cache.WatchErrorHandler
193+
watchErrorHandler cache.WatchErrorHandlerWithContext
188194
}
189195

190196
// Start calls Run on each of the informers and sets started to true. Blocks on the context.
@@ -376,7 +382,7 @@ func (ip *Informers) addInformerToMap(gvk schema.GroupVersionKind, obj runtime.O
376382

377383
// Set WatchErrorHandler on SharedIndexInformer if set
378384
if ip.watchErrorHandler != nil {
379-
if err := sharedIndexInformer.SetWatchErrorHandler(ip.watchErrorHandler); err != nil {
385+
if err := sharedIndexInformer.SetWatchErrorHandlerWithContext(ip.watchErrorHandler); err != nil {
380386
return nil, false, err
381387
}
382388
}

pkg/cache/multi_namespace_cache.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,23 @@ func (i *multiNamespaceInformer) AddEventHandlerWithResyncPeriod(handler toolsca
390390
return handles, nil
391391
}
392392

393+
// AddEventHandlerWithOptions adds the handler with options to each namespaced informer.
394+
func (i *multiNamespaceInformer) AddEventHandlerWithOptions(handler toolscache.ResourceEventHandler, options toolscache.HandlerOptions) (toolscache.ResourceEventHandlerRegistration, error) {
395+
handles := handlerRegistration{
396+
handles: make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer)),
397+
}
398+
399+
for ns, informer := range i.namespaceToInformer {
400+
registration, err := informer.AddEventHandlerWithOptions(handler, options)
401+
if err != nil {
402+
return nil, err
403+
}
404+
handles.handles[ns] = registration
405+
}
406+
407+
return handles, nil
408+
}
409+
393410
// RemoveEventHandler removes a previously added event handler given by its registration handle.
394411
func (i *multiNamespaceInformer) RemoveEventHandler(h toolscache.ResourceEventHandlerRegistration) error {
395412
handles, ok := h.(handlerRegistration)

pkg/controller/controllertest/util.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,24 @@ func (f *FakeInformer) HasSynced() bool {
9999
return f.Synced
100100
}
101101

102-
// AddEventHandler implements the Informer interface. Adds an EventHandler to the fake Informers. TODO(community): Implement Registration.
102+
// AddEventHandler implements the Informer interface. Adds an EventHandler to the fake Informers. TODO(community): Implement Registration.
103103
func (f *FakeInformer) AddEventHandler(handler cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) {
104104
f.handlers = append(f.handlers, eventHandlerWrapper{handler})
105105
return nil, nil
106106
}
107107

108+
// AddEventHandlerWithResyncPeriod implements the Informer interface. Adds an EventHandler to the fake Informers (ignores resyncPeriod). TODO(community): Implement Registration.
109+
func (f *FakeInformer) AddEventHandlerWithResyncPeriod(handler cache.ResourceEventHandler, _ time.Duration) (cache.ResourceEventHandlerRegistration, error) {
110+
f.handlers = append(f.handlers, eventHandlerWrapper{handler})
111+
return nil, nil
112+
}
113+
114+
// AddEventHandlerWithOptions implements the Informer interface. Adds an EventHandler to the fake Informers (ignores options). TODO(community): Implement Registration.
115+
func (f *FakeInformer) AddEventHandlerWithOptions(handler cache.ResourceEventHandler, _ cache.HandlerOptions) (cache.ResourceEventHandlerRegistration, error) {
116+
f.handlers = append(f.handlers, eventHandlerWrapper{handler})
117+
return nil, nil
118+
}
119+
108120
// Run implements the Informer interface. Increments f.RunCount.
109121
func (f *FakeInformer) Run(<-chan struct{}) {
110122
f.RunCount++
@@ -135,15 +147,6 @@ func (f *FakeInformer) Delete(obj metav1.Object) {
135147
}
136148
}
137149

138-
// AddEventHandlerWithResyncPeriod does nothing. TODO(community): Implement this.
139-
func (f *FakeInformer) AddEventHandlerWithResyncPeriod(handler cache.ResourceEventHandler, resyncPeriod time.Duration) (cache.ResourceEventHandlerRegistration, error) {
140-
return nil, nil
141-
}
142-
143-
func (f *FakeInformer) AddEventHandlerWithOptions(handler cache.ResourceEventHandler, options cache.HandlerOptions) (cache.ResourceEventHandlerRegistration, error) {
144-
return nil, nil
145-
}
146-
147150
// RemoveEventHandler does nothing. TODO(community): Implement this.
148151
func (f *FakeInformer) RemoveEventHandler(handle cache.ResourceEventHandlerRegistration) error {
149152
return nil
@@ -169,7 +172,8 @@ func (f *FakeInformer) SetWatchErrorHandler(cache.WatchErrorHandler) error {
169172
return nil
170173
}
171174

172-
func (f *FakeInformer) SetWatchErrorHandlerWithContext(handler cache.WatchErrorHandlerWithContext) error {
175+
// SetWatchErrorHandlerWithContext does nothing. TODO(community): Implement this.
176+
func (f *FakeInformer) SetWatchErrorHandlerWithContext(cache.WatchErrorHandlerWithContext) error {
173177
return nil
174178
}
175179

pkg/internal/controller/controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func (c *Controller[request]) Start(ctx context.Context) error {
168168
defer c.mu.Unlock()
169169

170170
// TODO(pwittrock): Reconsider HandleCrash
171-
defer utilruntime.HandleCrash()
171+
defer utilruntime.HandleCrashWithLogger(c.LogConstructor(nil))
172172

173173
// NB(directxman12): launch the sources *before* trying to wait for the
174174
// caches to sync so that they have a chance to register their intended

pkg/internal/source/kind.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@ import (
1010
"k8s.io/apimachinery/pkg/api/meta"
1111
"k8s.io/apimachinery/pkg/runtime"
1212
"k8s.io/apimachinery/pkg/util/wait"
13+
toolscache "k8s.io/client-go/tools/cache"
1314
"k8s.io/client-go/util/workqueue"
15+
logf "sigs.k8s.io/controller-runtime/pkg/internal/log"
1416

1517
"sigs.k8s.io/controller-runtime/pkg/cache"
1618
"sigs.k8s.io/controller-runtime/pkg/client"
1719
"sigs.k8s.io/controller-runtime/pkg/handler"
1820
"sigs.k8s.io/controller-runtime/pkg/predicate"
1921
)
2022

23+
var logKind = logf.RuntimeLog.WithName("source").WithName("Kind")
24+
2125
// Kind is used to provide a source of events originating inside the cluster from Watches (e.g. Pod Create).
2226
type Kind[object client.Object, request comparable] struct {
2327
// Type is the type of object to watch. e.g. &v1.Pod{}
@@ -68,12 +72,12 @@ func (ks *Kind[object, request]) Start(ctx context.Context, queue workqueue.Type
6872
kindMatchErr := &meta.NoKindMatchError{}
6973
switch {
7074
case errors.As(lastErr, &kindMatchErr):
71-
log.Error(lastErr, "if kind is a CRD, it should be installed before calling Start",
75+
logKind.Error(lastErr, "if kind is a CRD, it should be installed before calling Start",
7276
"kind", kindMatchErr.GroupKind)
7377
case runtime.IsNotRegisteredError(lastErr):
74-
log.Error(lastErr, "kind must be registered to the Scheme")
78+
logKind.Error(lastErr, "kind must be registered to the Scheme")
7579
default:
76-
log.Error(lastErr, "failed to get informer from cache")
80+
logKind.Error(lastErr, "failed to get informer from cache")
7781
}
7882
return false, nil // Retry.
7983
}
@@ -87,7 +91,9 @@ func (ks *Kind[object, request]) Start(ctx context.Context, queue workqueue.Type
8791
return
8892
}
8993

90-
_, err := i.AddEventHandler(NewEventHandler(ctx, queue, ks.Handler, ks.Predicates).HandlerFuncs())
94+
_, err := i.AddEventHandlerWithOptions(NewEventHandler(ctx, queue, ks.Handler, ks.Predicates).HandlerFuncs(), toolscache.HandlerOptions{
95+
Logger: &logKind,
96+
})
9197
if err != nil {
9298
ks.startedErr <- err
9399
return

pkg/log/log_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,12 @@ var _ = Describe("logging", func() {
194194
}()
195195
go func() {
196196
defer GinkgoRecover()
197-
delegLog.WithValues("with-value")
197+
delegLog.WithValues("key", "with-value")
198198
close(withValuesDone)
199199
}()
200200
go func() {
201201
defer GinkgoRecover()
202-
child.WithValues("grandchild")
202+
child.WithValues("key", "grandchild")
203203
close(grandChildDone)
204204
}()
205205
go func() {

pkg/source/source.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,22 @@ import (
2222
"fmt"
2323
"sync"
2424

25+
toolscache "k8s.io/client-go/tools/cache"
2526
"k8s.io/client-go/util/workqueue"
2627
"k8s.io/utils/ptr"
2728
"sigs.k8s.io/controller-runtime/pkg/client"
2829
"sigs.k8s.io/controller-runtime/pkg/event"
2930
"sigs.k8s.io/controller-runtime/pkg/handler"
31+
logf "sigs.k8s.io/controller-runtime/pkg/internal/log"
3032
internal "sigs.k8s.io/controller-runtime/pkg/internal/source"
3133
"sigs.k8s.io/controller-runtime/pkg/reconcile"
3234

3335
"sigs.k8s.io/controller-runtime/pkg/cache"
3436
"sigs.k8s.io/controller-runtime/pkg/predicate"
3537
)
3638

39+
var logInformer = logf.RuntimeLog.WithName("source").WithName("Informer")
40+
3741
// Source is a source of events (e.g. Create, Update, Delete operations on Kubernetes Objects, Webhook callbacks, etc)
3842
// which should be processed by event.EventHandlers to enqueue reconcile.Requests.
3943
//
@@ -282,7 +286,9 @@ func (is *Informer) Start(ctx context.Context, queue workqueue.TypedRateLimiting
282286
return errors.New("must specify Informer.Handler")
283287
}
284288

285-
_, err := is.Informer.AddEventHandler(internal.NewEventHandler(ctx, queue, is.Handler, is.Predicates).HandlerFuncs())
289+
_, err := is.Informer.AddEventHandlerWithOptions(internal.NewEventHandler(ctx, queue, is.Handler, is.Predicates).HandlerFuncs(), toolscache.HandlerOptions{
290+
Logger: &logInformer,
291+
})
286292
if err != nil {
287293
return err
288294
}

0 commit comments

Comments
 (0)