@@ -81,27 +81,27 @@ type EventSinkImpl struct {
81
81
}
82
82
83
83
// Create takes the representation of a event and creates it. Returns the server's representation of the event, and an error, if there is any.
84
- func (e * EventSinkImpl ) Create (event * eventsv1.Event ) (* eventsv1.Event , error ) {
84
+ func (e * EventSinkImpl ) Create (ctx context. Context , event * eventsv1.Event ) (* eventsv1.Event , error ) {
85
85
if event .Namespace == "" {
86
86
return nil , fmt .Errorf ("can't create an event with empty namespace" )
87
87
}
88
- return e .Interface .Events (event .Namespace ).Create (context . TODO () , event , metav1.CreateOptions {})
88
+ return e .Interface .Events (event .Namespace ).Create (ctx , event , metav1.CreateOptions {})
89
89
}
90
90
91
91
// Update takes the representation of a event and updates it. Returns the server's representation of the event, and an error, if there is any.
92
- func (e * EventSinkImpl ) Update (event * eventsv1.Event ) (* eventsv1.Event , error ) {
92
+ func (e * EventSinkImpl ) Update (ctx context. Context , event * eventsv1.Event ) (* eventsv1.Event , error ) {
93
93
if event .Namespace == "" {
94
94
return nil , fmt .Errorf ("can't update an event with empty namespace" )
95
95
}
96
- return e .Interface .Events (event .Namespace ).Update (context . TODO () , event , metav1.UpdateOptions {})
96
+ return e .Interface .Events (event .Namespace ).Update (ctx , event , metav1.UpdateOptions {})
97
97
}
98
98
99
99
// Patch applies the patch and returns the patched event, and an error, if there is any.
100
- func (e * EventSinkImpl ) Patch (event * eventsv1.Event , data []byte ) (* eventsv1.Event , error ) {
100
+ func (e * EventSinkImpl ) Patch (ctx context. Context , event * eventsv1.Event , data []byte ) (* eventsv1.Event , error ) {
101
101
if event .Namespace == "" {
102
102
return nil , fmt .Errorf ("can't patch an event with empty namespace" )
103
103
}
104
- return e .Interface .Events (event .Namespace ).Patch (context . TODO () , event .Name , types .StrategicMergePatchType , data , metav1.PatchOptions {})
104
+ return e .Interface .Events (event .Namespace ).Patch (ctx , event .Name , types .StrategicMergePatchType , data , metav1.PatchOptions {})
105
105
}
106
106
107
107
// NewBroadcaster Creates a new event broadcaster.
@@ -124,13 +124,13 @@ func (e *eventBroadcasterImpl) Shutdown() {
124
124
}
125
125
126
126
// refreshExistingEventSeries refresh events TTL
127
- func (e * eventBroadcasterImpl ) refreshExistingEventSeries () {
127
+ func (e * eventBroadcasterImpl ) refreshExistingEventSeries (ctx context. Context ) {
128
128
// TODO: Investigate whether lock contention won't be a problem
129
129
e .mu .Lock ()
130
130
defer e .mu .Unlock ()
131
131
for isomorphicKey , event := range e .eventCache {
132
132
if event .Series != nil {
133
- if recordedEvent , retry := recordEvent (e .sink , event ); ! retry {
133
+ if recordedEvent , retry := recordEvent (ctx , e .sink , event ); ! retry {
134
134
if recordedEvent != nil {
135
135
e .eventCache [isomorphicKey ] = recordedEvent
136
136
}
@@ -142,15 +142,15 @@ func (e *eventBroadcasterImpl) refreshExistingEventSeries() {
142
142
// finishSeries checks if a series has ended and either:
143
143
// - write final count to the apiserver
144
144
// - delete a singleton event (i.e. series field is nil) from the cache
145
- func (e * eventBroadcasterImpl ) finishSeries () {
145
+ func (e * eventBroadcasterImpl ) finishSeries (ctx context. Context ) {
146
146
// TODO: Investigate whether lock contention won't be a problem
147
147
e .mu .Lock ()
148
148
defer e .mu .Unlock ()
149
149
for isomorphicKey , event := range e .eventCache {
150
150
eventSerie := event .Series
151
151
if eventSerie != nil {
152
152
if eventSerie .LastObservedTime .Time .Before (time .Now ().Add (- finishTime )) {
153
- if _ , retry := recordEvent (e .sink , event ); ! retry {
153
+ if _ , retry := recordEvent (ctx , e .sink , event ); ! retry {
154
154
delete (e .eventCache , isomorphicKey )
155
155
}
156
156
}
@@ -161,13 +161,13 @@ func (e *eventBroadcasterImpl) finishSeries() {
161
161
}
162
162
163
163
// NewRecorder returns an EventRecorder that records events with the given event source.
164
- func (e * eventBroadcasterImpl ) NewRecorder (scheme * runtime.Scheme , reportingController string ) EventRecorder {
164
+ func (e * eventBroadcasterImpl ) NewRecorder (scheme * runtime.Scheme , reportingController string ) EventRecorderLogger {
165
165
hostname , _ := os .Hostname ()
166
166
reportingInstance := reportingController + "-" + hostname
167
- return & recorderImpl {scheme , reportingController , reportingInstance , e .Broadcaster , clock.RealClock {}}
167
+ return & recorderImplLogger { recorderImpl : & recorderImpl {scheme , reportingController , reportingInstance , e .Broadcaster , clock.RealClock {}}, logger : klog . Background () }
168
168
}
169
169
170
- func (e * eventBroadcasterImpl ) recordToSink (event * eventsv1.Event , clock clock.Clock ) {
170
+ func (e * eventBroadcasterImpl ) recordToSink (ctx context. Context , event * eventsv1.Event , clock clock.Clock ) {
171
171
// Make a copy before modification, because there could be multiple listeners.
172
172
eventCopy := event .DeepCopy ()
173
173
go func () {
@@ -197,48 +197,53 @@ func (e *eventBroadcasterImpl) recordToSink(event *eventsv1.Event, clock clock.C
197
197
}()
198
198
if evToRecord != nil {
199
199
// TODO: Add a metric counting the number of recording attempts
200
- e .attemptRecording (evToRecord )
200
+ e .attemptRecording (ctx , evToRecord )
201
201
// We don't want the new recorded Event to be reflected in the
202
202
// client's cache because server-side mutations could mess with the
203
203
// aggregation mechanism used by the client.
204
204
}
205
205
}()
206
206
}
207
207
208
- func (e * eventBroadcasterImpl ) attemptRecording (event * eventsv1. Event ) * eventsv1.Event {
208
+ func (e * eventBroadcasterImpl ) attemptRecording (ctx context. Context , event * eventsv1.Event ) {
209
209
tries := 0
210
210
for {
211
- if recordedEvent , retry := recordEvent (e .sink , event ); ! retry {
212
- return recordedEvent
211
+ if _ , retry := recordEvent (ctx , e .sink , event ); ! retry {
212
+ return
213
213
}
214
214
tries ++
215
215
if tries >= maxTriesPerEvent {
216
- klog .Errorf ( "Unable to write event '%#v' (retry limit exceeded!)" , event )
217
- return nil
216
+ klog .FromContext ( ctx ). Error ( nil , "Unable to write event (retry limit exceeded!)" , "event " , event )
217
+ return
218
218
}
219
219
// Randomize sleep so that various clients won't all be
220
- // synced up if the master goes down.
221
- time .Sleep (wait .Jitter (e .sleepDuration , 0.25 ))
220
+ // synced up if the master goes down. Give up when
221
+ // the context is canceled.
222
+ select {
223
+ case <- ctx .Done ():
224
+ return
225
+ case <- time .After (wait .Jitter (e .sleepDuration , 0.25 )):
226
+ }
222
227
}
223
228
}
224
229
225
- func recordEvent (sink EventSink , event * eventsv1.Event ) (* eventsv1.Event , bool ) {
230
+ func recordEvent (ctx context. Context , sink EventSink , event * eventsv1.Event ) (* eventsv1.Event , bool ) {
226
231
var newEvent * eventsv1.Event
227
232
var err error
228
233
isEventSeries := event .Series != nil
229
234
if isEventSeries {
230
235
patch , patchBytesErr := createPatchBytesForSeries (event )
231
236
if patchBytesErr != nil {
232
- klog .Errorf ( "Unable to calculate diff, no merge is possible: %v" , patchBytesErr )
237
+ klog .FromContext ( ctx ). Error ( patchBytesErr , "Unable to calculate diff, no merge is possible" )
233
238
return nil , false
234
239
}
235
- newEvent , err = sink .Patch (event , patch )
240
+ newEvent , err = sink .Patch (ctx , event , patch )
236
241
}
237
242
// Update can fail because the event may have been removed and it no longer exists.
238
243
if ! isEventSeries || (isEventSeries && util .IsKeyNotFoundError (err )) {
239
244
// Making sure that ResourceVersion is empty on creation
240
245
event .ResourceVersion = ""
241
- newEvent , err = sink .Create (event )
246
+ newEvent , err = sink .Create (ctx , event )
242
247
}
243
248
if err == nil {
244
249
return newEvent , false
@@ -248,7 +253,7 @@ func recordEvent(sink EventSink, event *eventsv1.Event) (*eventsv1.Event, bool)
248
253
switch err .(type ) {
249
254
case * restclient.RequestConstructionError :
250
255
// We will construct the request the same next time, so don't keep trying.
251
- klog .Errorf ( "Unable to construct event '%#v': '%v' (will not retry!)" , event , err )
256
+ klog .FromContext ( ctx ). Error ( err , "Unable to construct event (will not retry!)" , " event" , event )
252
257
return nil , false
253
258
case * errors.StatusError :
254
259
if errors .IsAlreadyExists (err ) {
@@ -260,9 +265,9 @@ func recordEvent(sink EventSink, event *eventsv1.Event) (*eventsv1.Event, bool)
260
265
if isEventSeries {
261
266
return nil , true
262
267
}
263
- klog .V (5 ).Infof ("Server rejected event '%#v': '%v' (will not retry!)" , event , err )
268
+ klog .FromContext ( ctx ). V (5 ).Info ("Server rejected event (will not retry!)" , " event" , event , "err" , err )
264
269
} else {
265
- klog .Errorf ( "Server rejected event '%#v': '%v' (will not retry!)" , event , err )
270
+ klog .FromContext ( ctx ). Error ( err , "Server rejected event (will not retry!)" , " event" , event )
266
271
}
267
272
return nil , false
268
273
case * errors.UnexpectedObjectError :
@@ -271,7 +276,7 @@ func recordEvent(sink EventSink, event *eventsv1.Event) (*eventsv1.Event, bool)
271
276
default :
272
277
// This case includes actual http transport errors. Go ahead and retry.
273
278
}
274
- klog .Errorf ( "Unable to write event: '%v' (may retry after sleeping)" , err )
279
+ klog .FromContext ( ctx ). Error ( err , "Unable to write event (may retry after sleeping)" )
275
280
return nil , true
276
281
}
277
282
@@ -307,29 +312,38 @@ func getKey(event *eventsv1.Event) eventKey {
307
312
// StartStructuredLogging starts sending events received from this EventBroadcaster to the structured logging function.
308
313
// The return value can be ignored or used to stop recording, if desired.
309
314
// TODO: this function should also return an error.
315
+ //
316
+ // Deprecated: use StartLogging instead.
310
317
func (e * eventBroadcasterImpl ) StartStructuredLogging (verbosity klog.Level ) func () {
311
- stopWatcher , err := e .StartEventWatcher (
318
+ logger := klog .Background ().V (int (verbosity ))
319
+ stopWatcher , err := e .StartLogging (logger )
320
+ if err != nil {
321
+ logger .Error (err , "Failed to start event watcher" )
322
+ return func () {}
323
+ }
324
+ return stopWatcher
325
+ }
326
+
327
+ // StartLogging starts sending events received from this EventBroadcaster to the structured logger.
328
+ // To adjust verbosity, use the logger's V method (i.e. pass `logger.V(3)` instead of `logger`).
329
+ // The returned function can be ignored or used to stop recording, if desired.
330
+ func (e * eventBroadcasterImpl ) StartLogging (logger klog.Logger ) (func (), error ) {
331
+ return e .StartEventWatcher (
312
332
func (obj runtime.Object ) {
313
333
event , ok := obj .(* eventsv1.Event )
314
334
if ! ok {
315
- klog . Errorf ( "unexpected type, expected eventsv1.Event" )
335
+ logger . Error ( nil , "unexpected type, expected eventsv1.Event" )
316
336
return
317
337
}
318
- klog . V ( verbosity ). InfoS ("Event occurred" , "object" , klog .KRef (event .Regarding .Namespace , event .Regarding .Name ), "kind" , event .Regarding .Kind , "apiVersion" , event .Regarding .APIVersion , "type" , event .Type , "reason" , event .Reason , "action" , event .Action , "note" , event .Note )
338
+ logger . Info ("Event occurred" , "object" , klog .KRef (event .Regarding .Namespace , event .Regarding .Name ), "kind" , event .Regarding .Kind , "apiVersion" , event .Regarding .APIVersion , "type" , event .Type , "reason" , event .Reason , "action" , event .Action , "note" , event .Note )
319
339
})
320
- if err != nil {
321
- klog .Errorf ("failed to start event watcher: '%v'" , err )
322
- return func () {}
323
- }
324
- return stopWatcher
325
340
}
326
341
327
342
// StartEventWatcher starts sending events received from this EventBroadcaster to the given event handler function.
328
343
// The return value is used to stop recording
329
344
func (e * eventBroadcasterImpl ) StartEventWatcher (eventHandler func (event runtime.Object )) (func (), error ) {
330
345
watcher , err := e .Watch ()
331
346
if err != nil {
332
- klog .Errorf ("Unable start event watcher: '%v' (will not retry!)" , err )
333
347
return nil , err
334
348
}
335
349
go func () {
@@ -345,37 +359,42 @@ func (e *eventBroadcasterImpl) StartEventWatcher(eventHandler func(event runtime
345
359
return watcher .Stop , nil
346
360
}
347
361
348
- func (e * eventBroadcasterImpl ) startRecordingEvents (stopCh <- chan struct {} ) error {
362
+ func (e * eventBroadcasterImpl ) startRecordingEvents (ctx context. Context ) error {
349
363
eventHandler := func (obj runtime.Object ) {
350
364
event , ok := obj .(* eventsv1.Event )
351
365
if ! ok {
352
- klog .Errorf ( "unexpected type, expected eventsv1.Event" )
366
+ klog .FromContext ( ctx ). Error ( nil , "unexpected type, expected eventsv1.Event" )
353
367
return
354
368
}
355
- e .recordToSink (event , clock.RealClock {})
369
+ e .recordToSink (ctx , event , clock.RealClock {})
356
370
}
357
371
stopWatcher , err := e .StartEventWatcher (eventHandler )
358
372
if err != nil {
359
373
return err
360
374
}
361
375
go func () {
362
- <- stopCh
376
+ <- ctx . Done ()
363
377
stopWatcher ()
364
378
}()
365
379
return nil
366
380
}
367
381
368
382
// StartRecordingToSink starts sending events received from the specified eventBroadcaster to the given sink.
383
+ // Deprecated: use StartRecordingToSinkWithContext instead.
369
384
func (e * eventBroadcasterImpl ) StartRecordingToSink (stopCh <- chan struct {}) {
370
- go wait .Until (e .refreshExistingEventSeries , refreshTime , stopCh )
371
- go wait .Until (e .finishSeries , finishTime , stopCh )
372
- err := e .startRecordingEvents (stopCh )
385
+ err := e .StartRecordingToSinkWithContext (wait .ContextForChannel (stopCh ))
373
386
if err != nil {
374
- klog .Errorf ("unexpected type, expected eventsv1.Event" )
375
- return
387
+ klog .Background ().Error (err , "Failed to start recording to sink" )
376
388
}
377
389
}
378
390
391
+ // StartRecordingToSinkWithContext starts sending events received from the specified eventBroadcaster to the given sink.
392
+ func (e * eventBroadcasterImpl ) StartRecordingToSinkWithContext (ctx context.Context ) error {
393
+ go wait .UntilWithContext (ctx , e .refreshExistingEventSeries , refreshTime )
394
+ go wait .UntilWithContext (ctx , e .finishSeries , finishTime )
395
+ return e .startRecordingEvents (ctx )
396
+ }
397
+
379
398
type eventBroadcasterAdapterImpl struct {
380
399
coreClient typedv1core.EventsGetter
381
400
coreBroadcaster record.EventBroadcaster
@@ -409,14 +428,14 @@ func (e *eventBroadcasterAdapterImpl) StartRecordingToSink(stopCh <-chan struct{
409
428
}
410
429
}
411
430
412
- func (e * eventBroadcasterAdapterImpl ) NewRecorder (name string ) EventRecorder {
431
+ func (e * eventBroadcasterAdapterImpl ) NewRecorder (name string ) EventRecorderLogger {
413
432
if e .eventsv1Broadcaster != nil && e .eventsv1Client != nil {
414
433
return e .eventsv1Broadcaster .NewRecorder (scheme .Scheme , name )
415
434
}
416
435
return record .NewEventRecorderAdapter (e .DeprecatedNewLegacyRecorder (name ))
417
436
}
418
437
419
- func (e * eventBroadcasterAdapterImpl ) DeprecatedNewLegacyRecorder (name string ) record.EventRecorder {
438
+ func (e * eventBroadcasterAdapterImpl ) DeprecatedNewLegacyRecorder (name string ) record.EventRecorderLogger {
420
439
return e .coreBroadcaster .NewRecorder (scheme .Scheme , corev1.EventSource {Component : name })
421
440
}
422
441
0 commit comments