Skip to content

Commit 6078881

Browse files
committed
chore: basic implementation
Signed-off-by: STRRL <[email protected]>
1 parent 6a99e51 commit 6078881

File tree

6 files changed

+241
-0
lines changed

6 files changed

+241
-0
lines changed

pkg/log/logr/doc.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package logr introduces an implementation of logr.LogSink, which could
18+
// encode Kubernetes Objects into Type information and Namespace/Name.
19+
package logr
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package logr
18+
19+
import (
20+
"github.com/go-logr/logr"
21+
"go.uber.org/atomic"
22+
"k8s.io/apimachinery/pkg/runtime"
23+
"k8s.io/apimachinery/pkg/types"
24+
)
25+
26+
type KubeAwareLogSink struct {
27+
kubeAwareEnabled *atomic.Bool
28+
logger logr.LogSink
29+
}
30+
31+
func (k *KubeAwareLogSink) Init(info logr.RuntimeInfo) {
32+
k.logger.Init(info)
33+
}
34+
35+
func (k *KubeAwareLogSink) Enabled(level int) bool {
36+
return k.logger.Enabled(level)
37+
}
38+
39+
func (k *KubeAwareLogSink) Info(level int, msg string, keysAndValues ...interface{}) {
40+
if !k.KubeAwareEnabled() {
41+
k.logger.Info(level, msg, keysAndValues...)
42+
return
43+
}
44+
45+
k.logger.Info(level, msg, k.wrapKeyAndValues(keysAndValues)...)
46+
}
47+
48+
func (k *KubeAwareLogSink) Error(err error, msg string, keysAndValues ...interface{}) {
49+
if !k.KubeAwareEnabled() {
50+
k.logger.Error(err, msg, keysAndValues...)
51+
return
52+
}
53+
k.logger.Error(err, msg, k.wrapKeyAndValues(keysAndValues)...)
54+
}
55+
56+
func (k *KubeAwareLogSink) wrapKeyAndValues(keysAndValues []interface{}) []interface{} {
57+
result := make([]interface{}, len(keysAndValues))
58+
for i, item := range keysAndValues {
59+
if i%2 == 1 {
60+
// item is key, no need to resolve
61+
result[i] = item
62+
continue
63+
}
64+
switch val := item.(type) {
65+
case runtime.Object:
66+
result[i] = kubeObjectWrapper{obj: val}
67+
case types.NamespacedName:
68+
result[i] = namespacedNameWrapper{NamespacedName: val}
69+
default:
70+
result[i] = item
71+
}
72+
}
73+
return result
74+
}
75+
76+
func (k *KubeAwareLogSink) WithValues(keysAndValues ...interface{}) logr.LogSink {
77+
return &KubeAwareLogSink{
78+
kubeAwareEnabled: k.kubeAwareEnabled,
79+
logger: k.logger.WithValues(keysAndValues...),
80+
}
81+
}
82+
83+
func (k *KubeAwareLogSink) WithName(name string) logr.LogSink {
84+
return &KubeAwareLogSink{
85+
kubeAwareEnabled: k.kubeAwareEnabled,
86+
logger: k.logger.WithName(name),
87+
}
88+
}
89+
90+
func (k *KubeAwareLogSink) KubeAwareEnabled() bool {
91+
return k.kubeAwareEnabled.Load()
92+
}
93+
94+
func (k *KubeAwareLogSink) SetKubeAwareEnabled(enabled bool) {
95+
k.kubeAwareEnabled.Store(enabled)
96+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package logr

pkg/log/logr/kube_object_wrapper.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package logr
18+
19+
import (
20+
"k8s.io/apimachinery/pkg/api/meta"
21+
"k8s.io/apimachinery/pkg/runtime"
22+
)
23+
24+
type kubeObjectWrapper struct {
25+
obj runtime.Object
26+
}
27+
28+
func (w *kubeObjectWrapper) MarshalLog() interface{} {
29+
result := make(map[string]string)
30+
if gvk := w.obj.GetObjectKind().GroupVersionKind(); gvk.Version != "" {
31+
result["apiVersion"] = gvk.GroupVersion().String()
32+
result["kind"] = gvk.Kind
33+
}
34+
35+
objMeta, err := meta.Accessor(w.obj)
36+
if err != nil {
37+
// best effort, noop
38+
return result
39+
}
40+
41+
if ns := objMeta.GetNamespace(); ns != "" {
42+
result["namespace"] = ns
43+
}
44+
result["name"] = objMeta.GetName()
45+
return result
46+
}

pkg/log/logr/logr_suite_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package logr
18+
19+
import (
20+
"testing"
21+
22+
. "github.com/onsi/ginkgo"
23+
. "github.com/onsi/gomega"
24+
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
25+
)
26+
27+
func TestSource(t *testing.T) {
28+
RegisterFailHandler(Fail)
29+
suiteName := "Logr Log Suite"
30+
RunSpecsWithDefaultAndCustomReporters(t, suiteName, []Reporter{printer.NewlineReporter{}, printer.NewProwReporter(suiteName)})
31+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package logr
18+
19+
import "k8s.io/apimachinery/pkg/types"
20+
21+
type namespacedNameWrapper struct {
22+
types.NamespacedName
23+
}
24+
25+
func (w *namespacedNameWrapper) MarshalLog() interface{} {
26+
result := make(map[string]string)
27+
if w.Namespace != "" {
28+
result["namespace"] = w.Namespace
29+
}
30+
result["name"] = w.Name
31+
return result
32+
}

0 commit comments

Comments
 (0)