@@ -25,6 +25,7 @@ import (
2525
2626 "github.com/go-logr/logr"
2727 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
28+ "k8s.io/apimachinery/pkg/util/uuid"
2829 "k8s.io/client-go/util/workqueue"
2930 "sigs.k8s.io/controller-runtime/pkg/handler"
3031 ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/internal/controller/metrics"
@@ -83,8 +84,11 @@ type Controller struct {
8384 // startWatches maintains a list of sources, handlers, and predicates to start when the controller is started.
8485 startWatches []watchDescription
8586
86- // Log is used to log messages to users during reconciliation, or for example when a watch is started.
87- Log logr.Logger
87+ // LogConstructor is used to construct a logger to then log messages to users during reconciliation,
88+ // or for example when a watch is started.
89+ // Note: LogConstructor has to be able to handle nil requests as we are also using it
90+ // outside the context of a reconciliation.
91+ LogConstructor func (request * reconcile.Request ) logr.Logger
8892
8993 // RecoverPanic indicates whether the panic caused by reconcile should be recovered.
9094 RecoverPanic bool
@@ -99,7 +103,6 @@ type watchDescription struct {
99103
100104// Reconcile implements reconcile.Reconciler.
101105func (c * Controller ) Reconcile (ctx context.Context , req reconcile.Request ) (_ reconcile.Result , err error ) {
102- log := c .Log .WithValues ("name" , req .Name , "namespace" , req .Namespace )
103106 defer func () {
104107 if r := recover (); r != nil {
105108 if c .RecoverPanic {
@@ -110,11 +113,11 @@ func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (_ re
110113 return
111114 }
112115
116+ log := logf .FromContext (ctx )
113117 log .Info (fmt .Sprintf ("Observed a panic in reconciler: %v" , r ))
114118 panic (r )
115119 }
116120 }()
117- ctx = logf .IntoContext (ctx , log )
118121 return c .Do .Reconcile (ctx , req )
119122}
120123
@@ -144,7 +147,7 @@ func (c *Controller) Watch(src source.Source, evthdler handler.EventHandler, prc
144147 return nil
145148 }
146149
147- c .Log .Info ("Starting EventSource" , "source" , src )
150+ c .LogConstructor ( nil ) .Info ("Starting EventSource" , "source" , src )
148151 return src .Start (c .ctx , evthdler , c .Queue , prct ... )
149152}
150153
@@ -179,15 +182,15 @@ func (c *Controller) Start(ctx context.Context) error {
179182 // caches to sync so that they have a chance to register their intendeded
180183 // caches.
181184 for _ , watch := range c .startWatches {
182- c .Log .Info ("Starting EventSource" , "source" , fmt .Sprintf ("%s" , watch .src ))
185+ c .LogConstructor ( nil ) .Info ("Starting EventSource" , "source" , fmt .Sprintf ("%s" , watch .src ))
183186
184187 if err := watch .src .Start (ctx , watch .handler , c .Queue , watch .predicates ... ); err != nil {
185188 return err
186189 }
187190 }
188191
189192 // Start the SharedIndexInformer factories to begin populating the SharedIndexInformer caches
190- c .Log .Info ("Starting Controller" )
193+ c .LogConstructor ( nil ) .Info ("Starting Controller" )
191194
192195 for _ , watch := range c .startWatches {
193196 syncingSource , ok := watch .src .(source.SyncingSource )
@@ -204,7 +207,7 @@ func (c *Controller) Start(ctx context.Context) error {
204207 // is an error or a timeout
205208 if err := syncingSource .WaitForSync (sourceStartCtx ); err != nil {
206209 err := fmt .Errorf ("failed to wait for %s caches to sync: %w" , c .Name , err )
207- c .Log .Error (err , "Could not wait for Cache to sync" )
210+ c .LogConstructor ( nil ) .Error (err , "Could not wait for Cache to sync" )
208211 return err
209212 }
210213
@@ -221,7 +224,7 @@ func (c *Controller) Start(ctx context.Context) error {
221224 c .startWatches = nil
222225
223226 // Launch workers to process resources
224- c .Log .Info ("Starting workers" , "worker count" , c .MaxConcurrentReconciles )
227+ c .LogConstructor ( nil ) .Info ("Starting workers" , "worker count" , c .MaxConcurrentReconciles )
225228 wg .Add (c .MaxConcurrentReconciles )
226229 for i := 0 ; i < c .MaxConcurrentReconciles ; i ++ {
227230 go func () {
@@ -241,9 +244,9 @@ func (c *Controller) Start(ctx context.Context) error {
241244 }
242245
243246 <- ctx .Done ()
244- c .Log .Info ("Shutdown signal received, waiting for all workers to finish" )
247+ c .LogConstructor ( nil ) .Info ("Shutdown signal received, waiting for all workers to finish" )
245248 wg .Wait ()
246- c .Log .Info ("All workers finished" )
249+ c .LogConstructor ( nil ) .Info ("All workers finished" )
247250 return nil
248251}
249252
@@ -295,19 +298,21 @@ func (c *Controller) reconcileHandler(ctx context.Context, obj interface{}) {
295298 c .updateMetrics (time .Since (reconcileStartTS ))
296299 }()
297300
298- // Make sure that the the object is a valid request.
301+ // Make sure that the object is a valid request.
299302 req , ok := obj .(reconcile.Request )
300303 if ! ok {
301304 // As the item in the workqueue is actually invalid, we call
302305 // Forget here else we'd go into a loop of attempting to
303306 // process a work item that is invalid.
304307 c .Queue .Forget (obj )
305- c .Log .Error (nil , "Queue item was not a Request" , "type" , fmt .Sprintf ("%T" , obj ), "value" , obj )
308+ c .LogConstructor ( nil ) .Error (nil , "Queue item was not a Request" , "type" , fmt .Sprintf ("%T" , obj ), "value" , obj )
306309 // Return true, don't take a break
307310 return
308311 }
309312
310- log := c .Log .WithValues ("name" , req .Name , "namespace" , req .Namespace )
313+ log := c .LogConstructor (& req )
314+
315+ log = log .WithValues ("reconcileID" , uuid .NewUUID ())
311316 ctx = logf .IntoContext (ctx , log )
312317
313318 // RunInformersAndControllers the syncHandler, passing it the Namespace/Name string of the
@@ -340,7 +345,7 @@ func (c *Controller) reconcileHandler(ctx context.Context, obj interface{}) {
340345
341346// GetLogger returns this controller's logger.
342347func (c * Controller ) GetLogger () logr.Logger {
343- return c .Log
348+ return c .LogConstructor ( nil )
344349}
345350
346351// InjectFunc implement SetFields.Injector.
0 commit comments