mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Merge pull request #91608 from yuzhiquan/feature-implement-json-logformat
Feature implement json logformat
This commit is contained in:
commit
fd61c3149c
@ -31,7 +31,6 @@ require (
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
|
||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f
|
||||
go.uber.org/atomic v1.4.0 // indirect
|
||||
go.uber.org/zap v1.10.0
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e
|
||||
|
3
staging/src/k8s.io/cloud-provider/go.sum
generated
3
staging/src/k8s.io/cloud-provider/go.sum
generated
@ -200,6 +200,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
@ -17,6 +17,9 @@ require (
|
||||
github.com/prometheus/procfs v0.0.11
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.4.0
|
||||
go.uber.org/atomic v1.4.0 // indirect
|
||||
go.uber.org/multierr v1.1.0 // indirect
|
||||
go.uber.org/zap v1.10.0
|
||||
k8s.io/apimachinery v0.0.0
|
||||
k8s.io/client-go v0.0.0
|
||||
k8s.io/klog/v2 v2.1.0
|
||||
|
6
staging/src/k8s.io/component-base/go.sum
generated
6
staging/src/k8s.io/component-base/go.sum
generated
@ -207,6 +207,12 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
@ -16,6 +16,7 @@ go_library(
|
||||
importpath = "k8s.io/component-base/logs",
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/logs/json:go_default_library",
|
||||
"//vendor/github.com/go-logr/logr:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/klog/v2:go_default_library",
|
||||
@ -33,6 +34,7 @@ filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/component-base/logs/json:all-srcs",
|
||||
"//staging/src/k8s.io/component-base/logs/logreduction:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
|
42
staging/src/k8s.io/component-base/logs/json/BUILD
Normal file
42
staging/src/k8s.io/component-base/logs/json/BUILD
Normal file
@ -0,0 +1,42 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["json.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/component-base/logs/json",
|
||||
importpath = "k8s.io/component-base/logs/json",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/go-logr/logr:go_default_library",
|
||||
"//vendor/go.uber.org/zap:go_default_library",
|
||||
"//vendor/go.uber.org/zap/zapcore:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"json_benchmark_test.go",
|
||||
"json_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/go.uber.org/zap:go_default_library",
|
||||
"//vendor/go.uber.org/zap/zapcore:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
212
staging/src/k8s.io/component-base/logs/json/json.go
Normal file
212
staging/src/k8s.io/component-base/logs/json/json.go
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
Copyright 2020 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 logs
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// Inspired from https://github.com/go-logr/zapr, some functions is copy from the repo.
|
||||
|
||||
var (
|
||||
// JSONLogger is global json log format logr
|
||||
JSONLogger logr.Logger
|
||||
|
||||
// timeNow stubbed out for testing
|
||||
timeNow = time.Now
|
||||
)
|
||||
|
||||
type noopInfoLogger struct{}
|
||||
|
||||
// Enabled func in noopInfoLogger always return false
|
||||
func (l *noopInfoLogger) Enabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (l *noopInfoLogger) Info(_ string, _ ...interface{}) {}
|
||||
|
||||
var disabledInfoLogger = &noopInfoLogger{}
|
||||
|
||||
type infoLogger struct {
|
||||
lvl zapcore.Level
|
||||
l *zap.Logger
|
||||
}
|
||||
|
||||
// implement logr.InfoLogger
|
||||
var _ logr.InfoLogger = &infoLogger{}
|
||||
|
||||
// Enabled always return true
|
||||
func (l *infoLogger) Enabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Info write message to error level log
|
||||
func (l *infoLogger) Info(msg string, keysAndVals ...interface{}) {
|
||||
if checkedEntry := l.l.Check(l.lvl, msg); checkedEntry != nil {
|
||||
checkedEntry.Time = timeNow()
|
||||
checkedEntry.Write(l.handleFields(keysAndVals)...)
|
||||
}
|
||||
}
|
||||
|
||||
// dPanic write message to DPanicLevel level log
|
||||
// we need implement this because unit test case need stub time.Now
|
||||
// otherwise the ts field always changed
|
||||
func (l *infoLogger) dPanic(msg string, keysAndVals ...interface{}) {
|
||||
entry := zapcore.Entry{
|
||||
Level: zapcore.DPanicLevel,
|
||||
Time: timeNow(),
|
||||
Message: msg,
|
||||
}
|
||||
checkedEntry := l.l.Core().Check(entry, nil)
|
||||
checkedEntry.Write(l.handleFields(keysAndVals)...)
|
||||
}
|
||||
|
||||
// handleFields converts a bunch of arbitrary key-value pairs into Zap fields. It takes
|
||||
// additional pre-converted Zap fields, for use with automatically attached fields, like
|
||||
// `error`.
|
||||
func (l *infoLogger) handleFields(args []interface{}, additional ...zap.Field) []zap.Field {
|
||||
// a slightly modified version of zap.SugaredLogger.sweetenFields
|
||||
if len(args) == 0 {
|
||||
// fast-return if we have no suggared fields.
|
||||
return additional
|
||||
}
|
||||
|
||||
// unlike Zap, we can be pretty sure users aren't passing structured
|
||||
// fields (since logr has no concept of that), so guess that we need a
|
||||
// little less space.
|
||||
fields := make([]zap.Field, 0, len(args)/2+len(additional))
|
||||
for i := 0; i < len(args)-1; i += 2 {
|
||||
// check just in case for strongly-typed Zap fields, which is illegal (since
|
||||
// it breaks implementation agnosticism), so we can give a better error message.
|
||||
if _, ok := args[i].(zap.Field); ok {
|
||||
l.dPanic("strongly-typed Zap Field passed to logr", zap.Any("zap field", args[i]))
|
||||
break
|
||||
}
|
||||
|
||||
// process a key-value pair,
|
||||
// ensuring that the key is a string
|
||||
key, val := args[i], args[i+1]
|
||||
keyStr, isString := key.(string)
|
||||
if !isString {
|
||||
// if the key isn't a string, DPanic and stop logging
|
||||
l.dPanic("non-string key argument passed to logging, ignoring all later arguments", zap.Any("invalid key", key))
|
||||
break
|
||||
}
|
||||
|
||||
fields = append(fields, zap.Any(keyStr, val))
|
||||
}
|
||||
|
||||
return append(fields, additional...)
|
||||
}
|
||||
|
||||
// zapLogger is a logr.Logger that uses Zap to record log.
|
||||
type zapLogger struct {
|
||||
// NB: this looks very similar to zap.SugaredLogger, but
|
||||
// deals with our desire to have multiple verbosity levels.
|
||||
l *zap.Logger
|
||||
infoLogger
|
||||
}
|
||||
|
||||
// implement logr.Logger
|
||||
var _ logr.Logger = &zapLogger{}
|
||||
|
||||
// Error write log message to error level
|
||||
func (l *zapLogger) Error(err error, msg string, keysAndVals ...interface{}) {
|
||||
entry := zapcore.Entry{
|
||||
Level: zapcore.ErrorLevel,
|
||||
Time: timeNow(),
|
||||
Message: msg,
|
||||
}
|
||||
checkedEntry := l.l.Core().Check(entry, nil)
|
||||
checkedEntry.Write(l.handleFields(keysAndVals, handleError(err))...)
|
||||
}
|
||||
|
||||
// V return info logr.Logger with specified level
|
||||
func (l *zapLogger) V(level int) logr.InfoLogger {
|
||||
lvl := zapcore.Level(-1 * level)
|
||||
if l.l.Core().Enabled(lvl) {
|
||||
return &infoLogger{
|
||||
l: l.l,
|
||||
lvl: lvl,
|
||||
}
|
||||
}
|
||||
return disabledInfoLogger
|
||||
}
|
||||
|
||||
// WithValues return logr.Logger with some keys And Values
|
||||
func (l *zapLogger) WithValues(keysAndValues ...interface{}) logr.Logger {
|
||||
l.l = l.l.With(l.handleFields(keysAndValues)...)
|
||||
return l
|
||||
}
|
||||
|
||||
// WithName return logger Named with specified name
|
||||
func (l *zapLogger) WithName(name string) logr.Logger {
|
||||
l.l = l.l.Named(name)
|
||||
return l
|
||||
}
|
||||
|
||||
// encoderConfig config zap json encoder key format, and encodetime format
|
||||
var encoderConfig = zapcore.EncoderConfig{
|
||||
MessageKey: "msg",
|
||||
|
||||
LevelKey: "v",
|
||||
EncodeLevel: int8LevelEncoder,
|
||||
|
||||
TimeKey: "ts",
|
||||
EncodeTime: zapcore.EpochMillisTimeEncoder,
|
||||
}
|
||||
|
||||
// NewJSONLogger creates a new json logr.Logger using the given Zap Logger to log.
|
||||
func NewJSONLogger(l *zap.Logger, w zapcore.WriteSyncer) logr.Logger {
|
||||
if w == nil {
|
||||
w = os.Stdout
|
||||
}
|
||||
log := l.WithOptions(zap.AddCallerSkip(1),
|
||||
zap.WrapCore(
|
||||
func(zapcore.Core) zapcore.Core {
|
||||
return zapcore.NewCore(zapcore.NewJSONEncoder(encoderConfig), zapcore.AddSync(w), zapcore.DebugLevel)
|
||||
}))
|
||||
return &zapLogger{
|
||||
l: log,
|
||||
infoLogger: infoLogger{
|
||||
l: log,
|
||||
lvl: zap.DebugLevel,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func int8LevelEncoder(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
|
||||
lvl := int8(l)
|
||||
if lvl < 0 {
|
||||
lvl = -lvl
|
||||
}
|
||||
enc.AppendInt8(lvl)
|
||||
}
|
||||
|
||||
func handleError(err error) zap.Field {
|
||||
return zap.NamedError("err", err)
|
||||
}
|
||||
|
||||
func init() {
|
||||
l, _ := zap.NewProduction()
|
||||
JSONLogger = NewJSONLogger(l, nil)
|
||||
}
|
@ -0,0 +1,161 @@
|
||||
/*
|
||||
Copyright 2020 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 logs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var record = struct {
|
||||
Error error `json:"err"`
|
||||
Level int `json:"v"`
|
||||
Message string `json:"msg"`
|
||||
Time time.Time `json:"ts"`
|
||||
Fields map[string]interface{} `json:"fields"`
|
||||
}{
|
||||
Error: fmt.Errorf("test for error:%s", "default"),
|
||||
Level: 2,
|
||||
Message: "test",
|
||||
Time: time.Unix(0, 123),
|
||||
Fields: map[string]interface{}{
|
||||
"str": "foo",
|
||||
"int64-1": int64(1),
|
||||
"int64-2": int64(1),
|
||||
"float64": float64(1.0),
|
||||
"string1": "\n",
|
||||
"string2": "💩",
|
||||
"string3": "🤔",
|
||||
"string4": "🙊",
|
||||
"bool": true,
|
||||
"request": struct {
|
||||
Method string `json:"method"`
|
||||
Timeout int `json:"timeout"`
|
||||
secret string `json:"secret"`
|
||||
}{
|
||||
Method: "GET",
|
||||
Timeout: 10,
|
||||
secret: "pony",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func BenchmarkInfoLoggerInfo(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
jLogger := NewJSONLogger(zap.NewExample(), nil)
|
||||
jLogger.Info("test",
|
||||
"str", "foo",
|
||||
"int64-1", int64(1),
|
||||
"int64-2", int64(1),
|
||||
"float64", float64(1.0),
|
||||
"string1", "\n",
|
||||
"string2", "💩",
|
||||
"string3", "🤔",
|
||||
"string4", "🙊",
|
||||
"bool", true,
|
||||
"request", struct {
|
||||
Method string `json:"method"`
|
||||
Timeout int `json:"timeout"`
|
||||
secret string `json:"secret"`
|
||||
}{
|
||||
Method: "GET",
|
||||
Timeout: 10,
|
||||
secret: "pony",
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkInfoLoggerInfoStandardJSON(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
json.Marshal(record)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkZapLoggerError(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
jLogger := NewJSONLogger(zap.NewExample(), nil)
|
||||
jLogger.Error(fmt.Errorf("test for error:%s", "default"),
|
||||
"test",
|
||||
"str", "foo",
|
||||
"int64-1", int64(1),
|
||||
"int64-2", int64(1),
|
||||
"float64", float64(1.0),
|
||||
"string1", "\n",
|
||||
"string2", "💩",
|
||||
"string3", "🤔",
|
||||
"string4", "🙊",
|
||||
"bool", true,
|
||||
"request", struct {
|
||||
Method string `json:"method"`
|
||||
Timeout int `json:"timeout"`
|
||||
secret string `json:"secret"`
|
||||
}{
|
||||
Method: "GET",
|
||||
Timeout: 10,
|
||||
secret: "pony",
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
func BenchmarkZapLoggerErrorStandardJSON(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
json.Marshal(record)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkZapLoggerV(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
jLogger := NewJSONLogger(zap.NewExample(), nil)
|
||||
jLogger.V(1).Info("test",
|
||||
"str", "foo",
|
||||
"int64-1", int64(1),
|
||||
"int64-2", int64(1),
|
||||
"float64", float64(1.0),
|
||||
"string1", "\n",
|
||||
"string2", "💩",
|
||||
"string3", "🤔",
|
||||
"string4", "🙊",
|
||||
"bool", true,
|
||||
"request", struct {
|
||||
Method string `json:"method"`
|
||||
Timeout int `json:"timeout"`
|
||||
secret string `json:"secret"`
|
||||
}{
|
||||
Method: "GET",
|
||||
Timeout: 10,
|
||||
secret: "pony",
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
130
staging/src/k8s.io/component-base/logs/json/json_test.go
Normal file
130
staging/src/k8s.io/component-base/logs/json/json_test.go
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
Copyright 2020 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 logs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// TestInfoLoggerInfo test infologger json info format
|
||||
func TestInfoLoggerInfo(t *testing.T) {
|
||||
timeNow = func() time.Time {
|
||||
return time.Date(1970, time.January, 1, 0, 0, 0, 123, time.UTC)
|
||||
}
|
||||
var testDataInfo = []struct {
|
||||
msg string
|
||||
format string
|
||||
keysValues []interface{}
|
||||
}{
|
||||
{
|
||||
msg: "test",
|
||||
format: "{\"v\":1,\"ts\":%f,\"msg\":\"test\",\"ns\":\"default\",\"podnum\":2}\n",
|
||||
keysValues: []interface{}{"ns", "default", "podnum", 2},
|
||||
},
|
||||
{
|
||||
msg: "test for strongly typed Zap field",
|
||||
format: "{\"v\":3,\"ts\":%f,\"msg\":\"strongly-typed Zap Field passed to logr\"}\n{\"v\":1,\"ts\":0.000123,\"msg\":\"test for strongly typed Zap field\",\"ns\":\"default\",\"podnum\":2}\n",
|
||||
keysValues: []interface{}{"ns", "default", "podnum", 2, zap.Int("attempt", 3), "attempt", "Running", 10},
|
||||
},
|
||||
{
|
||||
msg: "test for non-string key argument",
|
||||
format: "{\"v\":3,\"ts\":%f,\"msg\":\"non-string key argument passed to logging, ignoring all later arguments\"}\n{\"v\":1,\"ts\":0.000123,\"msg\":\"test for non-string key argument\",\"ns\":\"default\",\"podnum\":2}\n",
|
||||
keysValues: []interface{}{"ns", "default", "podnum", 2, 200, "replica", "Running", 10},
|
||||
},
|
||||
}
|
||||
|
||||
for i, data := range testDataInfo {
|
||||
var buffer bytes.Buffer
|
||||
writer := bufio.NewWriter(&buffer)
|
||||
var sampleInfoLogger = NewJSONLogger(zap.NewExample(), zapcore.AddSync(writer))
|
||||
sampleInfoLogger.Info(data.msg, data.keysValues...)
|
||||
writer.Flush()
|
||||
logStr := buffer.String()
|
||||
var ts float64
|
||||
fmt.Println(i, logStr)
|
||||
n, err := fmt.Sscanf(logStr, data.format, &ts)
|
||||
if n != 1 || err != nil {
|
||||
t.Errorf("log format error: %d elements, error %s:\n%s", n, err, logStr)
|
||||
}
|
||||
expect := fmt.Sprintf(data.format, ts)
|
||||
if !assert.Equal(t, expect, logStr) {
|
||||
t.Errorf("Info has wrong format \n expect:%s\n got:%s", expect, logStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestInfoLoggerEnabled test jsonlogger should always enabled
|
||||
func TestInfoLoggerEnabled(t *testing.T) {
|
||||
var sampleInfoLogger = NewJSONLogger(zap.NewExample(), nil)
|
||||
if !sampleInfoLogger.Enabled() {
|
||||
t.Error("info logger should always enabled")
|
||||
}
|
||||
}
|
||||
|
||||
// TestInfoLoggerInfo test infologger V set log level func
|
||||
func TestZapLoggerV(t *testing.T) {
|
||||
var buffer bytes.Buffer
|
||||
writer := bufio.NewWriter(&buffer)
|
||||
timeNow = func() time.Time {
|
||||
return time.Date(1970, time.January, 1, 0, 0, 0, 123, time.UTC)
|
||||
}
|
||||
var sampleInfoLogger = NewJSONLogger(zap.NewExample(), zapcore.AddSync(writer))
|
||||
sampleInfoLogger.V(2).Info("test", "ns", "default", "podnum", 2)
|
||||
writer.Flush()
|
||||
logStr := buffer.String()
|
||||
var ts float64
|
||||
expectFormat := `{"v":1,"ts":%f,"msg":"test","ns":"default","podnum":2}`
|
||||
n, err := fmt.Sscanf(logStr, expectFormat, &ts)
|
||||
if n != 0 || err == nil {
|
||||
t.Errorf("log format error: %d elements, error %s:\n%s", n, err, logStr)
|
||||
}
|
||||
if !assert.Empty(t, logStr) {
|
||||
t.Errorf("Info log: %s should empty", logStr)
|
||||
}
|
||||
}
|
||||
|
||||
// TestZapLoggerError test infologger json error format
|
||||
func TestZapLoggerError(t *testing.T) {
|
||||
var buffer bytes.Buffer
|
||||
writer := bufio.NewWriter(&buffer)
|
||||
timeNow = func() time.Time {
|
||||
return time.Date(1970, time.January, 1, 0, 0, 0, 123, time.UTC)
|
||||
}
|
||||
var sampleInfoLogger = NewJSONLogger(zap.NewExample(), zapcore.AddSync(writer))
|
||||
sampleInfoLogger.Error(fmt.Errorf("ivailid namespace:%s", "default"), "wrong namespace", "ns", "default", "podnum", 2)
|
||||
writer.Flush()
|
||||
logStr := buffer.String()
|
||||
var ts float64
|
||||
expectFormat := `{"v":2,"ts":%f,"msg":"wrong namespace","ns":"default","podnum":2,"err":"ivailid namespace:default"}`
|
||||
n, err := fmt.Sscanf(logStr, expectFormat, &ts)
|
||||
if n != 1 || err != nil {
|
||||
t.Errorf("log format error: %d elements, error %s:\n%s", n, err, logStr)
|
||||
}
|
||||
expect := fmt.Sprintf(expectFormat, ts)
|
||||
if !assert.JSONEq(t, expect, logStr) {
|
||||
t.Errorf("Info has wrong format \n expect:%s\n got:%s", expect, logStr)
|
||||
}
|
||||
}
|
@ -21,6 +21,11 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
json "k8s.io/component-base/logs/json"
|
||||
)
|
||||
|
||||
const (
|
||||
jsonLogFormat = "json"
|
||||
)
|
||||
|
||||
var logRegistry = NewLogFormatRegistry()
|
||||
@ -77,5 +82,6 @@ func (lfr *LogFormatRegistry) Delete(name string) {
|
||||
|
||||
func init() {
|
||||
// Text format is default klog format
|
||||
logRegistry.Register("text", nil)
|
||||
logRegistry.Register(defaultLogFormat, nil)
|
||||
logRegistry.Register(jsonLogFormat, json.JSONLogger)
|
||||
}
|
||||
|
3
staging/src/k8s.io/csi-translation-lib/go.sum
generated
3
staging/src/k8s.io/csi-translation-lib/go.sum
generated
@ -183,6 +183,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
@ -182,6 +182,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
3
staging/src/k8s.io/kube-proxy/go.sum
generated
3
staging/src/k8s.io/kube-proxy/go.sum
generated
@ -182,6 +182,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
3
staging/src/k8s.io/kube-scheduler/go.sum
generated
3
staging/src/k8s.io/kube-scheduler/go.sum
generated
@ -182,6 +182,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
3
staging/src/k8s.io/kubelet/go.sum
generated
3
staging/src/k8s.io/kubelet/go.sum
generated
@ -185,6 +185,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -1678,6 +1678,7 @@ k8s.io/component-base/configz
|
||||
k8s.io/component-base/featuregate
|
||||
k8s.io/component-base/featuregate/testing
|
||||
k8s.io/component-base/logs
|
||||
k8s.io/component-base/logs/json
|
||||
k8s.io/component-base/logs/logreduction
|
||||
k8s.io/component-base/metrics
|
||||
k8s.io/component-base/metrics/legacyregistry
|
||||
|
Loading…
Reference in New Issue
Block a user