mirror of
https://github.com/resmoio/kubernetes-event-exporter.git
synced 2026-08-24 01:06:22 +00:00
102 lines
2.5 KiB
Go
102 lines
2.5 KiB
Go
package kube
|
|
|
|
import (
|
|
"github.com/rs/zerolog/log"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/client-go/informers"
|
|
"k8s.io/client-go/kubernetes"
|
|
"k8s.io/client-go/rest"
|
|
"k8s.io/client-go/tools/cache"
|
|
"time"
|
|
)
|
|
|
|
type EventHandler func(event *EnhancedEvent)
|
|
|
|
type EventWatcher struct {
|
|
informer cache.SharedInformer
|
|
stopper chan struct{}
|
|
labelCache *LabelCache
|
|
annotationCache *AnnotationCache
|
|
fn EventHandler
|
|
}
|
|
|
|
func NewEventWatcher(config *rest.Config, namespace string, fn EventHandler) *EventWatcher {
|
|
clientset := kubernetes.NewForConfigOrDie(config)
|
|
factory := informers.NewSharedInformerFactoryWithOptions(clientset, 0, informers.WithNamespace(namespace))
|
|
informer := factory.Core().V1().Events().Informer()
|
|
|
|
watcher := &EventWatcher{
|
|
informer: informer,
|
|
stopper: make(chan struct{}),
|
|
labelCache: NewLabelCache(config),
|
|
annotationCache: NewAnnotationCache(config),
|
|
fn: fn,
|
|
}
|
|
|
|
informer.AddEventHandler(watcher)
|
|
|
|
return watcher
|
|
}
|
|
|
|
func (e *EventWatcher) OnAdd(obj interface{}) {
|
|
event := obj.(*corev1.Event)
|
|
e.onEvent(event)
|
|
}
|
|
|
|
func (e *EventWatcher) OnUpdate(oldObj, newObj interface{}) {
|
|
event := newObj.(*corev1.Event)
|
|
e.onEvent(event)
|
|
}
|
|
|
|
func (e *EventWatcher) onEvent(event *corev1.Event) {
|
|
// TODO: Re-enable this after development
|
|
// It's probably an old event we are catching, it's not the best way but anyways
|
|
if time.Now().Sub(event.CreationTimestamp.Time) > time.Second*5 {
|
|
return
|
|
}
|
|
|
|
log.Debug().
|
|
Str("msg", event.Message).
|
|
Str("namespace", event.Namespace).
|
|
Str("reason", event.Reason).
|
|
Str("involvedObject", event.InvolvedObject.Name).
|
|
Msg("Received event")
|
|
|
|
ev := &EnhancedEvent{
|
|
Event: *event.DeepCopy(),
|
|
}
|
|
|
|
labels, err := e.labelCache.GetLabelsWithCache(&event.InvolvedObject)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Cannot list labels of the object")
|
|
// Ignoring error, but log it anyways
|
|
} else {
|
|
ev.InvolvedObject.Labels = labels
|
|
ev.InvolvedObject.ObjectReference = *event.InvolvedObject.DeepCopy()
|
|
}
|
|
|
|
annotations, err := e.annotationCache.GetAnnotationsWithCache(&event.InvolvedObject)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Cannot list annotations of the object")
|
|
} else {
|
|
ev.InvolvedObject.Annotations = annotations
|
|
ev.InvolvedObject.ObjectReference = *event.InvolvedObject.DeepCopy()
|
|
}
|
|
|
|
e.fn(ev)
|
|
return
|
|
}
|
|
|
|
func (e *EventWatcher) OnDelete(obj interface{}) {
|
|
// Ignore deletes
|
|
}
|
|
|
|
func (e *EventWatcher) Start() {
|
|
go e.informer.Run(e.stopper)
|
|
}
|
|
|
|
func (e *EventWatcher) Stop() {
|
|
e.stopper <- struct{}{}
|
|
close(e.stopper)
|
|
}
|