mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-10-22 15:09:39 +00:00
dependencies: klog v2.100.1
This commit is contained in:
65
vendor/k8s.io/klog/v2/format.go
generated
vendored
Normal file
65
vendor/k8s.io/klog/v2/format.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package klog
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
)
|
||||
|
||||
// Format wraps a value of an arbitrary type and implement fmt.Stringer and
|
||||
// logr.Marshaler for them. Stringer returns pretty-printed JSON. MarshalLog
|
||||
// returns the original value with a type that has no special methods, in
|
||||
// particular no MarshalLog or MarshalJSON.
|
||||
//
|
||||
// Wrapping values like that is useful when the value has a broken
|
||||
// implementation of these special functions (for example, a type which
|
||||
// inherits String from TypeMeta, but then doesn't re-implement String) or the
|
||||
// implementation produces output that is less readable or unstructured (for
|
||||
// example, the generated String functions for Kubernetes API types).
|
||||
func Format(obj interface{}) interface{} {
|
||||
return formatAny{Object: obj}
|
||||
}
|
||||
|
||||
type formatAny struct {
|
||||
Object interface{}
|
||||
}
|
||||
|
||||
func (f formatAny) String() string {
|
||||
var buffer strings.Builder
|
||||
encoder := json.NewEncoder(&buffer)
|
||||
encoder.SetIndent("", " ")
|
||||
if err := encoder.Encode(&f.Object); err != nil {
|
||||
return fmt.Sprintf("error marshaling %T to JSON: %v", f, err)
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
func (f formatAny) MarshalLog() interface{} {
|
||||
// Returning a pointer to a pointer ensures that zapr doesn't find a
|
||||
// fmt.Stringer or logr.Marshaler when it checks the type of the
|
||||
// value. It then falls back to reflection, which dumps the value being
|
||||
// pointed to (JSON doesn't have pointers).
|
||||
ptr := &f.Object
|
||||
return &ptr
|
||||
}
|
||||
|
||||
var _ fmt.Stringer = formatAny{}
|
||||
var _ logr.Marshaler = formatAny{}
|
47
vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go
generated
vendored
47
vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go
generated
vendored
@@ -18,6 +18,7 @@ package serialize
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
@@ -196,11 +197,11 @@ func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) {
|
||||
case textWriter:
|
||||
writeTextWriterValue(b, v)
|
||||
case fmt.Stringer:
|
||||
writeStringValue(b, true, StringerToString(v))
|
||||
writeStringValue(b, StringerToString(v))
|
||||
case string:
|
||||
writeStringValue(b, true, v)
|
||||
writeStringValue(b, v)
|
||||
case error:
|
||||
writeStringValue(b, true, ErrorToString(v))
|
||||
writeStringValue(b, ErrorToString(v))
|
||||
case logr.Marshaler:
|
||||
value := MarshalerToValue(v)
|
||||
// A marshaler that returns a string is useful for
|
||||
@@ -215,9 +216,9 @@ func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) {
|
||||
// value directly.
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
writeStringValue(b, true, value)
|
||||
writeStringValue(b, value)
|
||||
default:
|
||||
writeStringValue(b, false, f.AnyToString(value))
|
||||
f.formatAny(b, value)
|
||||
}
|
||||
case []byte:
|
||||
// In https://github.com/kubernetes/klog/pull/237 it was decided
|
||||
@@ -234,7 +235,7 @@ func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) {
|
||||
b.WriteByte('=')
|
||||
b.WriteString(fmt.Sprintf("%+q", v))
|
||||
default:
|
||||
writeStringValue(b, false, f.AnyToString(v))
|
||||
f.formatAny(b, v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,12 +243,25 @@ func KVFormat(b *bytes.Buffer, k, v interface{}) {
|
||||
Formatter{}.KVFormat(b, k, v)
|
||||
}
|
||||
|
||||
// AnyToString is the historic fallback formatter.
|
||||
func (f Formatter) AnyToString(v interface{}) string {
|
||||
// formatAny is the fallback formatter for a value. It supports a hook (for
|
||||
// example, for YAML encoding) and itself uses JSON encoding.
|
||||
func (f Formatter) formatAny(b *bytes.Buffer, v interface{}) {
|
||||
b.WriteRune('=')
|
||||
if f.AnyToStringHook != nil {
|
||||
return f.AnyToStringHook(v)
|
||||
b.WriteString(f.AnyToStringHook(v))
|
||||
return
|
||||
}
|
||||
return fmt.Sprintf("%+v", v)
|
||||
encoder := json.NewEncoder(b)
|
||||
l := b.Len()
|
||||
if err := encoder.Encode(v); err != nil {
|
||||
// This shouldn't happen. We discard whatever the encoder
|
||||
// wrote and instead dump an error string.
|
||||
b.Truncate(l)
|
||||
b.WriteString(fmt.Sprintf(`"<internal error: %v>"`, err))
|
||||
return
|
||||
}
|
||||
// Remove trailing newline.
|
||||
b.Truncate(b.Len() - 1)
|
||||
}
|
||||
|
||||
// StringerToString converts a Stringer to a string,
|
||||
@@ -287,7 +301,7 @@ func ErrorToString(err error) (ret string) {
|
||||
}
|
||||
|
||||
func writeTextWriterValue(b *bytes.Buffer, v textWriter) {
|
||||
b.WriteRune('=')
|
||||
b.WriteByte('=')
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
fmt.Fprintf(b, `"<panic: %s>"`, err)
|
||||
@@ -296,18 +310,13 @@ func writeTextWriterValue(b *bytes.Buffer, v textWriter) {
|
||||
v.WriteText(b)
|
||||
}
|
||||
|
||||
func writeStringValue(b *bytes.Buffer, quote bool, v string) {
|
||||
func writeStringValue(b *bytes.Buffer, v string) {
|
||||
data := []byte(v)
|
||||
index := bytes.IndexByte(data, '\n')
|
||||
if index == -1 {
|
||||
b.WriteByte('=')
|
||||
if quote {
|
||||
// Simple string, quote quotation marks and non-printable characters.
|
||||
b.WriteString(strconv.Quote(v))
|
||||
return
|
||||
}
|
||||
// Non-string with no line breaks.
|
||||
b.WriteString(v)
|
||||
// Simple string, quote quotation marks and non-printable characters.
|
||||
b.WriteString(strconv.Quote(v))
|
||||
return
|
||||
}
|
||||
|
||||
|
12
vendor/k8s.io/klog/v2/k8s_references.go
generated
vendored
12
vendor/k8s.io/klog/v2/k8s_references.go
generated
vendored
@@ -178,14 +178,14 @@ func (ks kobjSlice) process() (objs []interface{}, err string) {
|
||||
return objectRefs, ""
|
||||
}
|
||||
|
||||
var nilToken = []byte("<nil>")
|
||||
var nilToken = []byte("null")
|
||||
|
||||
func (ks kobjSlice) WriteText(out *bytes.Buffer) {
|
||||
s := reflect.ValueOf(ks.arg)
|
||||
switch s.Kind() {
|
||||
case reflect.Invalid:
|
||||
// nil parameter, print as empty slice.
|
||||
out.WriteString("[]")
|
||||
// nil parameter, print as null.
|
||||
out.Write(nilToken)
|
||||
return
|
||||
case reflect.Slice:
|
||||
// Okay, handle below.
|
||||
@@ -197,15 +197,15 @@ func (ks kobjSlice) WriteText(out *bytes.Buffer) {
|
||||
defer out.Write([]byte{']'})
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
if i > 0 {
|
||||
out.Write([]byte{' '})
|
||||
out.Write([]byte{','})
|
||||
}
|
||||
item := s.Index(i).Interface()
|
||||
if item == nil {
|
||||
out.Write(nilToken)
|
||||
} else if v, ok := item.(KMetadata); ok {
|
||||
KObj(v).writeUnquoted(out)
|
||||
KObj(v).WriteText(out)
|
||||
} else {
|
||||
fmt.Fprintf(out, "<KObjSlice needs a slice of values implementing KMetadata, got type %T>", item)
|
||||
fmt.Fprintf(out, `"<KObjSlice needs a slice of values implementing KMetadata, got type %T>"`, item)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
13
vendor/k8s.io/klog/v2/klog.go
generated
vendored
13
vendor/k8s.io/klog/v2/klog.go
generated
vendored
@@ -1228,6 +1228,19 @@ func CopyStandardLogTo(name string) {
|
||||
stdLog.SetOutput(logBridge(sev))
|
||||
}
|
||||
|
||||
// NewStandardLogger returns a Logger that writes to the klog logs for the
|
||||
// named and lower severities.
|
||||
//
|
||||
// Valid names are "INFO", "WARNING", "ERROR", and "FATAL". If the name is not
|
||||
// recognized, NewStandardLogger panics.
|
||||
func NewStandardLogger(name string) *stdLog.Logger {
|
||||
sev, ok := severity.ByName(name)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("klog.NewStandardLogger(%q): unknown severity", name))
|
||||
}
|
||||
return stdLog.New(logBridge(sev), "", stdLog.Lshortfile)
|
||||
}
|
||||
|
||||
// logBridge provides the Write method that enables CopyStandardLogTo to connect
|
||||
// Go's standard logs to the logs provided by this package.
|
||||
type logBridge severity.Severity
|
||||
|
99
vendor/k8s.io/klog/v2/test/output.go
generated
vendored
99
vendor/k8s.io/klog/v2/test/output.go
generated
vendored
@@ -275,30 +275,30 @@ I output.go:<LINE>] "test" firstKey=1 secondKey=3
|
||||
`,
|
||||
},
|
||||
"KObjs": {
|
||||
text: "test",
|
||||
text: "KObjs",
|
||||
values: []interface{}{"pods",
|
||||
klog.KObjs([]interface{}{
|
||||
&kmeta{Name: "pod-1", Namespace: "kube-system"},
|
||||
&kmeta{Name: "pod-2", Namespace: "kube-system"},
|
||||
})},
|
||||
expectedOutput: `I output.go:<LINE>] "test" pods=[kube-system/pod-1 kube-system/pod-2]
|
||||
expectedOutput: `I output.go:<LINE>] "KObjs" pods=[{"name":"pod-1","namespace":"kube-system"},{"name":"pod-2","namespace":"kube-system"}]
|
||||
`,
|
||||
},
|
||||
"KObjSlice okay": {
|
||||
text: "test",
|
||||
text: "KObjSlice",
|
||||
values: []interface{}{"pods",
|
||||
klog.KObjSlice([]interface{}{
|
||||
&kmeta{Name: "pod-1", Namespace: "kube-system"},
|
||||
&kmeta{Name: "pod-2", Namespace: "kube-system"},
|
||||
})},
|
||||
expectedOutput: `I output.go:<LINE>] "test" pods=[kube-system/pod-1 kube-system/pod-2]
|
||||
expectedOutput: `I output.go:<LINE>] "KObjSlice" pods=["kube-system/pod-1","kube-system/pod-2"]
|
||||
`,
|
||||
},
|
||||
"KObjSlice nil arg": {
|
||||
text: "test",
|
||||
values: []interface{}{"pods",
|
||||
klog.KObjSlice(nil)},
|
||||
expectedOutput: `I output.go:<LINE>] "test" pods=[]
|
||||
expectedOutput: `I output.go:<LINE>] "test" pods=null
|
||||
`,
|
||||
},
|
||||
"KObjSlice int arg": {
|
||||
@@ -315,14 +315,14 @@ I output.go:<LINE>] "test" firstKey=1 secondKey=3
|
||||
&kmeta{Name: "pod-1", Namespace: "kube-system"},
|
||||
nil,
|
||||
})},
|
||||
expectedOutput: `I output.go:<LINE>] "test" pods=[kube-system/pod-1 <nil>]
|
||||
expectedOutput: `I output.go:<LINE>] "test" pods=["kube-system/pod-1",null]
|
||||
`,
|
||||
},
|
||||
"KObjSlice ints": {
|
||||
text: "test",
|
||||
values: []interface{}{"ints",
|
||||
klog.KObjSlice([]int{1, 2, 3})},
|
||||
expectedOutput: `I output.go:<LINE>] "test" ints=[<KObjSlice needs a slice of values implementing KMetadata, got type int>]
|
||||
expectedOutput: `I output.go:<LINE>] "test" ints=["<KObjSlice needs a slice of values implementing KMetadata, got type int>"]
|
||||
`,
|
||||
},
|
||||
"regular error types as value": {
|
||||
@@ -404,6 +404,41 @@ I output.go:<LINE>] "test" firstKey=1 secondKey=3
|
||||
text: "map keys",
|
||||
values: []interface{}{map[string]bool{"test": true}, "test"},
|
||||
expectedOutput: `I output.go:<LINE>] "map keys" map[test:%!s(bool=true)]="test"
|
||||
`,
|
||||
},
|
||||
"map values": {
|
||||
text: "maps",
|
||||
values: []interface{}{"s", map[string]string{"hello": "world"}, "i", map[int]int{1: 2, 3: 4}},
|
||||
expectedOutput: `I output.go:<LINE>] "maps" s={"hello":"world"} i={"1":2,"3":4}
|
||||
`,
|
||||
},
|
||||
"slice values": {
|
||||
text: "slices",
|
||||
values: []interface{}{"s", []string{"hello", "world"}, "i", []int{1, 2, 3}},
|
||||
expectedOutput: `I output.go:<LINE>] "slices" s=["hello","world"] i=[1,2,3]
|
||||
`,
|
||||
},
|
||||
"struct values": {
|
||||
text: "structs",
|
||||
values: []interface{}{"s", struct{ Name, Kind, hidden string }{Name: "worker", Kind: "pod", hidden: "ignore"}},
|
||||
expectedOutput: `I output.go:<LINE>] "structs" s={"Name":"worker","Kind":"pod"}
|
||||
`,
|
||||
},
|
||||
"klog.Format": {
|
||||
text: "klog.Format",
|
||||
values: []interface{}{"s", klog.Format(struct{ Name, Kind, hidden string }{Name: "worker", Kind: "pod", hidden: "ignore"})},
|
||||
expectedOutput: `I output.go:<LINE>] "klog.Format" s=<
|
||||
{
|
||||
"Name": "worker",
|
||||
"Kind": "pod"
|
||||
}
|
||||
>
|
||||
`,
|
||||
},
|
||||
"cyclic list": {
|
||||
text: "cycle",
|
||||
values: []interface{}{"list", newCyclicList()},
|
||||
expectedOutput: `I output.go:<LINE>] "cycle" list="<internal error: json: unsupported value: encountered a cycle via *test.myList>"
|
||||
`,
|
||||
},
|
||||
}
|
||||
@@ -595,6 +630,15 @@ func Output(t *testing.T, config OutputConfig) {
|
||||
}
|
||||
|
||||
if config.NewLogger == nil || config.AsBackend {
|
||||
configStruct := klog.Format(myConfig{typeMeta: typeMeta{Kind: "config"}, RealField: 42})
|
||||
configStructOutput := `I output.go:<LINE>] "Format" config=<
|
||||
{
|
||||
"Kind": "config",
|
||||
"RealField": 42
|
||||
}
|
||||
>
|
||||
`
|
||||
|
||||
// Test all klog output functions.
|
||||
//
|
||||
// Each test case must be defined with the same number of
|
||||
@@ -760,6 +804,11 @@ func Output(t *testing.T, config OutputConfig) {
|
||||
logFunc: func() { klog.V(1).ErrorS(errors.New("hello"), "one world") },
|
||||
output: "E output.go:<LINE>] \"one world\" err=\"hello\"\n",
|
||||
},
|
||||
{
|
||||
name: "Format InfoS",
|
||||
logFunc: func() { klog.InfoS("Format", "config", configStruct) },
|
||||
output: configStructOutput,
|
||||
},
|
||||
}
|
||||
_, _, line, _ := runtime.Caller(0)
|
||||
|
||||
@@ -964,3 +1013,39 @@ func (f faultyError) Error() string {
|
||||
}
|
||||
|
||||
var _ error = faultyError{}
|
||||
|
||||
// typeMeta implements fmt.Stringer and logr.Marshaler. config below
|
||||
// inherits those (incomplete!) implementations.
|
||||
type typeMeta struct {
|
||||
Kind string
|
||||
}
|
||||
|
||||
func (t typeMeta) String() string {
|
||||
return "kind is " + t.Kind
|
||||
}
|
||||
|
||||
func (t typeMeta) MarshalLog() interface{} {
|
||||
return t.Kind
|
||||
}
|
||||
|
||||
type myConfig struct {
|
||||
typeMeta
|
||||
|
||||
RealField int
|
||||
}
|
||||
|
||||
var _ logr.Marshaler = myConfig{}
|
||||
var _ fmt.Stringer = myConfig{}
|
||||
|
||||
// This is a linked list. It can contain a cycle, which cannot be expressed in JSON.
|
||||
type myList struct {
|
||||
Value int
|
||||
Next *myList
|
||||
}
|
||||
|
||||
func newCyclicList() *myList {
|
||||
a := &myList{Value: 1}
|
||||
b := &myList{Value: 2, Next: a}
|
||||
a.Next = b
|
||||
return a
|
||||
}
|
||||
|
45
vendor/k8s.io/klog/v2/test/zapr.go
generated
vendored
45
vendor/k8s.io/klog/v2/test/zapr.go
generated
vendored
@@ -69,11 +69,15 @@ func ZaprOutputMappingDirect() map[string]string {
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"test","v":0,"pod":{"name":"pod-1","namespace":"kube-system"}}
|
||||
`,
|
||||
|
||||
`I output.go:<LINE>] "test" pods=[kube-system/pod-1 kube-system/pod-2]
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"test","v":0,"pods":[{"name":"pod-1","namespace":"kube-system"},{"name":"pod-2","namespace":"kube-system"}]}
|
||||
`I output.go:<LINE>] "KObjs" pods=[{"name":"pod-1","namespace":"kube-system"},{"name":"pod-2","namespace":"kube-system"}]
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"KObjs","v":0,"pods":[{"name":"pod-1","namespace":"kube-system"},{"name":"pod-2","namespace":"kube-system"}]}
|
||||
`,
|
||||
|
||||
`I output.go:<LINE>] "test" pods=[]
|
||||
`I output.go:<LINE>] "KObjSlice" pods=["kube-system/pod-1","kube-system/pod-2"]
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"KObjSlice","v":0,"pods":[{"name":"pod-1","namespace":"kube-system"},{"name":"pod-2","namespace":"kube-system"}]}
|
||||
`,
|
||||
|
||||
`I output.go:<LINE>] "test" pods=null
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"test","v":0,"pods":null}
|
||||
`,
|
||||
|
||||
@@ -81,11 +85,11 @@ func ZaprOutputMappingDirect() map[string]string {
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"test","v":0,"pods":"<KObjSlice needs a slice, got type int>"}
|
||||
`,
|
||||
|
||||
`I output.go:<LINE>] "test" ints=[<KObjSlice needs a slice of values implementing KMetadata, got type int>]
|
||||
`I output.go:<LINE>] "test" ints=["<KObjSlice needs a slice of values implementing KMetadata, got type int>"]
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"test","v":0,"ints":"<KObjSlice needs a slice of values implementing KMetadata, got type int>"}
|
||||
`,
|
||||
|
||||
`I output.go:<LINE>] "test" pods=[kube-system/pod-1 <nil>]
|
||||
`I output.go:<LINE>] "test" pods=["kube-system/pod-1",null]
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"test","v":0,"pods":[{"name":"pod-1","namespace":"kube-system"},null]}
|
||||
`,
|
||||
|
||||
@@ -228,6 +232,37 @@ I output.go:<LINE>] "odd WithValues" keyWithoutValue="(MISSING)"
|
||||
`I output.go:<LINE>] "map keys" map[test:%!s(bool=true)]="test"
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"non-string key argument passed to logging, ignoring all later arguments","invalid key":{"test":true}}
|
||||
{"caller":"test/output.go:<LINE>","msg":"map keys","v":0}
|
||||
`,
|
||||
|
||||
`I output.go:<LINE>] "Format" config=<
|
||||
{
|
||||
"Kind": "config",
|
||||
"RealField": 42
|
||||
}
|
||||
>
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"Format","v":0,"config":{"Kind":"config","RealField":42}}
|
||||
`,
|
||||
`I output.go:<LINE>] "maps" s={"hello":"world"} i={"1":2,"3":4}
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"maps","v":0,"s":{"hello":"world"},"i":{"1":2,"3":4}}
|
||||
`,
|
||||
|
||||
`I output.go:<LINE>] "slices" s=["hello","world"] i=[1,2,3]
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"slices","v":0,"s":["hello","world"],"i":[1,2,3]}
|
||||
`,
|
||||
`I output.go:<LINE>] "structs" s={"Name":"worker","Kind":"pod"}
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"structs","v":0,"s":{"Name":"worker","Kind":"pod"}}
|
||||
`,
|
||||
`I output.go:<LINE>] "klog.Format" s=<
|
||||
{
|
||||
"Name": "worker",
|
||||
"Kind": "pod"
|
||||
}
|
||||
>
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"klog.Format","v":0,"s":{"Name":"worker","Kind":"pod"}}
|
||||
`,
|
||||
|
||||
`I output.go:<LINE>] "cycle" list="<internal error: json: unsupported value: encountered a cycle via *test.myList>"
|
||||
`: `{"caller":"test/output.go:<LINE>","msg":"cycle","v":0,"listError":"json: unsupported value: encountered a cycle via *test.myList"}
|
||||
`,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user