@@ -23,27 +23,41 @@ import (
2323 "k8s.io/apimachinery/pkg/types"
2424)
2525
26+ var _ logr.LogSink = (* KubeAwareLogSink )(nil )
27+
28+ // KubeAwareLogSink is a Kubernetes-aware logr.LogSink.
29+ // zapcore.ObjectMarshaler would be bypassed when using zapr and WithValues.
30+ // It would use a wrapper implements logr.Marshaler instead of using origin Kubernetes objects.
2631type KubeAwareLogSink struct {
2732 sink logr.LogSink
2833 kubeAwareEnabled * atomic.Bool
2934}
3035
36+ // NewKubeAwareLogger return the wrapper with existed logr.Logger.
37+ // logger is the backend logger.
38+ // kubeAwareEnabled is the flag to enable kube aware logging.
3139func NewKubeAwareLogger (logger logr.Logger , kubeAwareEnabled bool ) logr.Logger {
3240 return logr .New (NewKubeAwareLogSink (logger .GetSink (), kubeAwareEnabled ))
3341}
3442
43+ // NewKubeAwareLogSink return the wrapper with existed logr.LogSink.
44+ // sink is the backend logr.LogSink.
45+ // kubeAwareEnabled is the flag to enable kube aware logging.
3546func NewKubeAwareLogSink (logSink logr.LogSink , kubeAwareEnabled bool ) * KubeAwareLogSink {
3647 return & KubeAwareLogSink {sink : logSink , kubeAwareEnabled : atomic .NewBool (kubeAwareEnabled )}
3748}
3849
50+ // Init implements logr.LogSink.
3951func (k * KubeAwareLogSink ) Init (info logr.RuntimeInfo ) {
4052 k .sink .Init (info )
4153}
4254
55+ // Enabled implements logr.LogSink.
4356func (k * KubeAwareLogSink ) Enabled (level int ) bool {
4457 return k .sink .Enabled (level )
4558}
4659
60+ // Info implements logr.LogSink.
4761func (k * KubeAwareLogSink ) Info (level int , msg string , keysAndValues ... interface {}) {
4862 if ! k .KubeAwareEnabled () {
4963 k .sink .Info (level , msg , keysAndValues ... )
@@ -53,6 +67,7 @@ func (k *KubeAwareLogSink) Info(level int, msg string, keysAndValues ...interfac
5367 k .sink .Info (level , msg , k .wrapKeyAndValues (keysAndValues )... )
5468}
5569
70+ // Error implements logr.LogSink.
5671func (k * KubeAwareLogSink ) Error (err error , msg string , keysAndValues ... interface {}) {
5772 if ! k .KubeAwareEnabled () {
5873 k .sink .Error (err , msg , keysAndValues ... )
@@ -61,45 +76,50 @@ func (k *KubeAwareLogSink) Error(err error, msg string, keysAndValues ...interfa
6176 k .sink .Error (err , msg , k .wrapKeyAndValues (keysAndValues )... )
6277}
6378
64- func (k * KubeAwareLogSink ) wrapKeyAndValues (keysAndValues []interface {}) []interface {} {
65- result := make ([]interface {}, len (keysAndValues ))
66- for i , item := range keysAndValues {
67- if i % 2 == 0 {
68- // item is key, no need to resolve
69- result [i ] = item
70- continue
71- }
72-
73- switch val := item .(type ) {
74- case runtime.Object :
75- result [i ] = & kubeObjectWrapper {obj : val }
76- case types.NamespacedName :
77- result [i ] = & namespacedNameWrapper {NamespacedName : val }
78- default :
79- result [i ] = item
80- }
81- }
82- return result
83- }
84-
79+ // WithValues implements logr.LogSink.
8580func (k * KubeAwareLogSink ) WithValues (keysAndValues ... interface {}) logr.LogSink {
8681 return & KubeAwareLogSink {
8782 kubeAwareEnabled : k .kubeAwareEnabled ,
8883 sink : k .sink .WithValues (k .wrapKeyAndValues (keysAndValues )... ),
8984 }
9085}
9186
87+ // WithName implements logr.LogSink.
9288func (k * KubeAwareLogSink ) WithName (name string ) logr.LogSink {
9389 return & KubeAwareLogSink {
9490 kubeAwareEnabled : k .kubeAwareEnabled ,
9591 sink : k .sink .WithName (name ),
9692 }
9793}
9894
95+ // KubeAwareEnabled return kube aware logging is enabled or not.
9996func (k * KubeAwareLogSink ) KubeAwareEnabled () bool {
10097 return k .kubeAwareEnabled .Load ()
10198}
10299
100+ // SetKubeAwareEnabled could update the kube aware logging flag.
103101func (k * KubeAwareLogSink ) SetKubeAwareEnabled (enabled bool ) {
104102 k .kubeAwareEnabled .Store (enabled )
105103}
104+
105+ // wrapKeyAndValues would replace the kubernetes objects with wrappers.
106+ func (k * KubeAwareLogSink ) wrapKeyAndValues (keysAndValues []interface {}) []interface {} {
107+ result := make ([]interface {}, len (keysAndValues ))
108+ for i , item := range keysAndValues {
109+ if i % 2 == 0 {
110+ // item is key, no need to resolve
111+ result [i ] = item
112+ continue
113+ }
114+
115+ switch val := item .(type ) {
116+ case runtime.Object :
117+ result [i ] = & kubeObjectWrapper {obj : val }
118+ case types.NamespacedName :
119+ result [i ] = & namespacedNameWrapper {NamespacedName : val }
120+ default :
121+ result [i ] = item
122+ }
123+ }
124+ return result
125+ }
0 commit comments