8
vendor/k8s.io/component-base/logs/OWNERS
generated
vendored
Normal file
8
vendor/k8s.io/component-base/logs/OWNERS
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
approvers:
|
||||
- sig-instrumentation-approvers
|
||||
reviewers:
|
||||
- sig-instrumentation-reviewers
|
||||
labels:
|
||||
- sig/instrumentation
|
||||
99
vendor/k8s.io/component-base/logs/datapol/datapol.go
generated
vendored
Normal file
99
vendor/k8s.io/component-base/logs/datapol/datapol.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
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 datapol contains functions to determine if objects contain sensitive
|
||||
// data to e.g. make decisions on whether to log them or not.
|
||||
package datapol
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// Verify returns a list of the datatypes contained in the argument that can be
|
||||
// considered sensitive w.r.t. to logging
|
||||
func Verify(value interface{}) []string {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
//TODO maybe export a metric
|
||||
klog.Warningf("Error while inspecting arguments for sensitive data: %v", r)
|
||||
}
|
||||
}()
|
||||
t := reflect.ValueOf(value)
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
return datatypes(t)
|
||||
}
|
||||
|
||||
func datatypes(v reflect.Value) []string {
|
||||
if types := byType(v.Type()); len(types) > 0 {
|
||||
// Slices, and maps can be nil or empty, only the nil case is zero
|
||||
switch v.Kind() {
|
||||
case reflect.Slice, reflect.Map:
|
||||
if !v.IsZero() && v.Len() > 0 {
|
||||
return types
|
||||
}
|
||||
default:
|
||||
if !v.IsZero() {
|
||||
return types
|
||||
}
|
||||
}
|
||||
}
|
||||
switch v.Kind() {
|
||||
case reflect.Interface:
|
||||
return datatypes(v.Elem())
|
||||
case reflect.Slice, reflect.Array:
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if types := datatypes(v.Index(i)); len(types) > 0 {
|
||||
return types
|
||||
}
|
||||
}
|
||||
case reflect.Map:
|
||||
mapIter := v.MapRange()
|
||||
for mapIter.Next() {
|
||||
k := mapIter.Key()
|
||||
v := mapIter.Value()
|
||||
if types := datatypes(k); len(types) > 0 {
|
||||
return types
|
||||
}
|
||||
if types := datatypes(v); len(types) > 0 {
|
||||
return types
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
t := v.Type()
|
||||
numField := t.NumField()
|
||||
|
||||
for i := 0; i < numField; i++ {
|
||||
f := t.Field(i)
|
||||
if f.Type.Kind() == reflect.Ptr {
|
||||
continue
|
||||
}
|
||||
if reason, ok := f.Tag.Lookup("datapolicy"); ok {
|
||||
if !v.Field(i).IsZero() {
|
||||
return strings.Split(reason, ",")
|
||||
}
|
||||
}
|
||||
if types := datatypes(v.Field(i)); len(types) > 0 {
|
||||
return types
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
49
vendor/k8s.io/component-base/logs/datapol/externaltypes.go
generated
vendored
Normal file
49
vendor/k8s.io/component-base/logs/datapol/externaltypes.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
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 datapol
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
const (
|
||||
httpHeader = "net/http.Header"
|
||||
httpCookie = "net/http.Cookie"
|
||||
x509Certificate = "crypto/x509.Certificate"
|
||||
)
|
||||
|
||||
// GlobalDatapolicyMapping returns the list of sensitive datatypes are embedded
|
||||
// in types not native to Kubernetes.
|
||||
func GlobalDatapolicyMapping(v interface{}) []string {
|
||||
return byType(reflect.TypeOf(v))
|
||||
}
|
||||
|
||||
func byType(t reflect.Type) []string {
|
||||
// Use string representation of the type to prevent taking a depency on the actual type.
|
||||
switch fmt.Sprintf("%s.%s", t.PkgPath(), t.Name()) {
|
||||
case httpHeader:
|
||||
return []string{"password", "token"}
|
||||
case httpCookie:
|
||||
return []string{"token"}
|
||||
case x509Certificate:
|
||||
return []string{"security-key"}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
178
vendor/k8s.io/component-base/logs/json/json.go
generated
vendored
Normal file
178
vendor/k8s.io/component-base/logs/json/json.go
generated
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
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
|
||||
)
|
||||
|
||||
// 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
|
||||
lvl int
|
||||
}
|
||||
|
||||
// implement logr.Logger
|
||||
var _ logr.Logger = &zapLogger{}
|
||||
|
||||
// Enabled should always return true
|
||||
func (l *zapLogger) Enabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Info write message to error level log
|
||||
func (l *zapLogger) Info(msg string, keysAndVals ...interface{}) {
|
||||
entry := zapcore.Entry{
|
||||
Time: timeNow(),
|
||||
Message: msg,
|
||||
}
|
||||
checkedEntry := l.l.Core().Check(entry, nil)
|
||||
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 *zapLogger) dPanic(msg string) {
|
||||
entry := zapcore.Entry{
|
||||
Level: zapcore.DPanicLevel,
|
||||
Time: timeNow(),
|
||||
Message: msg,
|
||||
}
|
||||
checkedEntry := l.l.Core().Check(entry, nil)
|
||||
checkedEntry.Write(zap.Int("v", l.lvl))
|
||||
}
|
||||
|
||||
// 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 *zapLogger) 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 append(additional, zap.Int("v", l.lvl))
|
||||
}
|
||||
|
||||
// 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)+1)
|
||||
fields = append(fields, zap.Int("v", l.lvl))
|
||||
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")
|
||||
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, stop logging
|
||||
l.dPanic("non-string key argument passed to logging, ignoring all later arguments")
|
||||
break
|
||||
}
|
||||
|
||||
fields = append(fields, zap.Any(keyStr, val))
|
||||
}
|
||||
|
||||
return append(fields, additional...)
|
||||
}
|
||||
|
||||
// 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.Logger {
|
||||
return &zapLogger{
|
||||
lvl: l.lvl + level,
|
||||
l: l.l,
|
||||
}
|
||||
}
|
||||
|
||||
// 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 encodetime format
|
||||
var encoderConfig = zapcore.EncoderConfig{
|
||||
MessageKey: "msg",
|
||||
|
||||
TimeKey: "ts",
|
||||
EncodeTime: zapcore.EpochMillisTimeEncoder,
|
||||
EncodeDuration: zapcore.StringDurationEncoder,
|
||||
}
|
||||
|
||||
// NewJSONLogger creates a new json logr.Logger using the given Zap Logger to log.
|
||||
func NewJSONLogger(w zapcore.WriteSyncer) logr.Logger {
|
||||
l, _ := zap.NewProduction()
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
func handleError(err error) zap.Field {
|
||||
return zap.NamedError("err", err)
|
||||
}
|
||||
|
||||
func init() {
|
||||
JSONLogger = NewJSONLogger(nil)
|
||||
}
|
||||
2
vendor/k8s.io/component-base/logs/logs.go
generated
vendored
2
vendor/k8s.io/component-base/logs/logs.go
generated
vendored
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
const logFlushFreqFlagName = "log-flush-frequency"
|
||||
|
||||
154
vendor/k8s.io/component-base/logs/options.go
generated
vendored
Normal file
154
vendor/k8s.io/component-base/logs/options.go
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
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 (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/component-base/logs/sanitization"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
logFormatFlagName = "logging-format"
|
||||
defaultLogFormat = "text"
|
||||
)
|
||||
|
||||
// List of logs (k8s.io/klog + k8s.io/component-base/logs) flags supported by all logging formats
|
||||
var supportedLogsFlags = map[string]struct{}{
|
||||
"v": {},
|
||||
// TODO: support vmodule after 1.19 Alpha
|
||||
}
|
||||
|
||||
// Options has klog format parameters
|
||||
type Options struct {
|
||||
LogFormat string
|
||||
LogSanitization bool
|
||||
}
|
||||
|
||||
// NewOptions return new klog options
|
||||
func NewOptions() *Options {
|
||||
return &Options{
|
||||
LogFormat: defaultLogFormat,
|
||||
}
|
||||
}
|
||||
|
||||
// Validate verifies if any unsupported flag is set
|
||||
// for non-default logging format
|
||||
func (o *Options) Validate() []error {
|
||||
errs := []error{}
|
||||
if o.LogFormat != defaultLogFormat {
|
||||
allFlags := unsupportedLoggingFlags(hyphensToUnderscores)
|
||||
for _, fname := range allFlags {
|
||||
if flagIsSet(fname, hyphensToUnderscores) {
|
||||
errs = append(errs, fmt.Errorf("non-default logging format doesn't honor flag: %s", fname))
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, err := o.Get(); err != nil {
|
||||
errs = append(errs, fmt.Errorf("unsupported log format: %s", o.LogFormat))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// hyphensToUnderscores replaces hyphens with underscores
|
||||
// we should always use underscores instead of hyphens when validate flags
|
||||
func hyphensToUnderscores(s string) string {
|
||||
return strings.Replace(s, "-", "_", -1)
|
||||
}
|
||||
|
||||
func flagIsSet(name string, normalizeFunc func(name string) string) bool {
|
||||
f := flag.Lookup(name)
|
||||
if f != nil {
|
||||
return f.DefValue != f.Value.String()
|
||||
}
|
||||
if normalizeFunc != nil {
|
||||
f = flag.Lookup(normalizeFunc(name))
|
||||
if f != nil {
|
||||
return f.DefValue != f.Value.String()
|
||||
}
|
||||
}
|
||||
pf := pflag.Lookup(name)
|
||||
if pf != nil {
|
||||
return pf.DefValue != pf.Value.String()
|
||||
}
|
||||
panic("failed to lookup unsupported log flag")
|
||||
}
|
||||
|
||||
// AddFlags add logging-format flag
|
||||
func (o *Options) AddFlags(fs *pflag.FlagSet) {
|
||||
normalizeFunc := func(name string) string {
|
||||
f := fs.GetNormalizeFunc()
|
||||
return string(f(fs, name))
|
||||
}
|
||||
|
||||
unsupportedFlags := fmt.Sprintf("--%s", strings.Join(unsupportedLoggingFlags(normalizeFunc), ", --"))
|
||||
formats := fmt.Sprintf(`"%s"`, strings.Join(logRegistry.List(), `", "`))
|
||||
fs.StringVar(&o.LogFormat, logFormatFlagName, defaultLogFormat, fmt.Sprintf("Sets the log format. Permitted formats: %s.\nNon-default formats don't honor these flags: %s.\nNon-default choices are currently alpha and subject to change without warning.", formats, unsupportedFlags))
|
||||
|
||||
// No new log formats should be added after generation is of flag options
|
||||
logRegistry.Freeze()
|
||||
fs.BoolVar(&o.LogSanitization, "experimental-logging-sanitization", o.LogSanitization, `[Experimental] When enabled prevents logging of fields tagged as sensitive (passwords, keys, tokens).
|
||||
Runtime log sanitization may introduce significant computation overhead and therefore should not be enabled in production.`)
|
||||
}
|
||||
|
||||
// Apply set klog logger from LogFormat type
|
||||
func (o *Options) Apply() {
|
||||
// if log format not exists, use nil loggr
|
||||
loggr, _ := o.Get()
|
||||
klog.SetLogger(loggr)
|
||||
if o.LogSanitization {
|
||||
klog.SetLogFilter(&sanitization.SanitizingFilter{})
|
||||
}
|
||||
}
|
||||
|
||||
// Get logger with LogFormat field
|
||||
func (o *Options) Get() (logr.Logger, error) {
|
||||
return logRegistry.Get(o.LogFormat)
|
||||
}
|
||||
|
||||
func unsupportedLoggingFlags(normalizeFunc func(name string) string) []string {
|
||||
allFlags := []string{}
|
||||
|
||||
// k8s.io/klog flags
|
||||
fs := &flag.FlagSet{}
|
||||
klog.InitFlags(fs)
|
||||
fs.VisitAll(func(flag *flag.Flag) {
|
||||
if _, found := supportedLogsFlags[flag.Name]; !found {
|
||||
name := flag.Name
|
||||
if normalizeFunc != nil {
|
||||
name = normalizeFunc(name)
|
||||
}
|
||||
allFlags = append(allFlags, name)
|
||||
}
|
||||
})
|
||||
|
||||
// k8s.io/component-base/logs flags
|
||||
pfs := &pflag.FlagSet{}
|
||||
AddFlags(pfs)
|
||||
pfs.VisitAll(func(flag *pflag.Flag) {
|
||||
if _, found := supportedLogsFlags[flag.Name]; !found {
|
||||
allFlags = append(allFlags, flag.Name)
|
||||
}
|
||||
})
|
||||
return allFlags
|
||||
}
|
||||
106
vendor/k8s.io/component-base/logs/registry.go
generated
vendored
Normal file
106
vendor/k8s.io/component-base/logs/registry.go
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
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 (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
json "k8s.io/component-base/logs/json"
|
||||
)
|
||||
|
||||
const (
|
||||
jsonLogFormat = "json"
|
||||
)
|
||||
|
||||
var logRegistry = NewLogFormatRegistry()
|
||||
|
||||
// LogFormatRegistry store klog format registry
|
||||
type LogFormatRegistry struct {
|
||||
registry map[string]logr.Logger
|
||||
frozen bool
|
||||
}
|
||||
|
||||
// NewLogFormatRegistry return new init LogFormatRegistry struct
|
||||
func NewLogFormatRegistry() *LogFormatRegistry {
|
||||
return &LogFormatRegistry{
|
||||
registry: make(map[string]logr.Logger),
|
||||
frozen: false,
|
||||
}
|
||||
}
|
||||
|
||||
// Register new log format registry to global logRegistry
|
||||
func (lfr *LogFormatRegistry) Register(name string, logger logr.Logger) error {
|
||||
if lfr.frozen {
|
||||
return fmt.Errorf("log format is frozen, unable to register log format")
|
||||
}
|
||||
if _, ok := lfr.registry[name]; ok {
|
||||
return fmt.Errorf("log format: %s already exists", name)
|
||||
}
|
||||
lfr.registry[name] = logger
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get specified log format logger
|
||||
func (lfr *LogFormatRegistry) Get(name string) (logr.Logger, error) {
|
||||
re, ok := lfr.registry[name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("log format: %s does not exists", name)
|
||||
}
|
||||
return re, nil
|
||||
}
|
||||
|
||||
// Set specified log format logger
|
||||
func (lfr *LogFormatRegistry) Set(name string, logger logr.Logger) error {
|
||||
if lfr.frozen {
|
||||
return fmt.Errorf("log format is frozen, unable to set log format")
|
||||
}
|
||||
|
||||
lfr.registry[name] = logger
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete specified log format logger
|
||||
func (lfr *LogFormatRegistry) Delete(name string) error {
|
||||
if lfr.frozen {
|
||||
return fmt.Errorf("log format is frozen, unable to delete log format")
|
||||
}
|
||||
|
||||
delete(lfr.registry, name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// List names of registered log formats (sorted)
|
||||
func (lfr *LogFormatRegistry) List() []string {
|
||||
formats := make([]string, 0, len(lfr.registry))
|
||||
for f := range lfr.registry {
|
||||
formats = append(formats, f)
|
||||
}
|
||||
sort.Strings(formats)
|
||||
return formats
|
||||
}
|
||||
|
||||
// Freeze freezes the log format registry
|
||||
func (lfr *LogFormatRegistry) Freeze() {
|
||||
lfr.frozen = true
|
||||
}
|
||||
func init() {
|
||||
// Text format is default klog format
|
||||
logRegistry.Register(defaultLogFormat, nil)
|
||||
logRegistry.Register(jsonLogFormat, json.JSONLogger)
|
||||
}
|
||||
69
vendor/k8s.io/component-base/logs/sanitization/sanitization.go
generated
vendored
Normal file
69
vendor/k8s.io/component-base/logs/sanitization/sanitization.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
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 sanitization
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/component-base/logs/datapol"
|
||||
)
|
||||
|
||||
const (
|
||||
datapolMsgFmt = "Log message has been redacted. Log argument #%d contains: %v"
|
||||
datapolMsg = "Log message has been redacted."
|
||||
)
|
||||
|
||||
// SanitizingFilter implements the LogFilter interface from klog with a set of functions that inspects the arguments with the datapol library
|
||||
type SanitizingFilter struct{}
|
||||
|
||||
// Filter is the filter function for the non-formatting logging functions of klog.
|
||||
func (sf *SanitizingFilter) Filter(args []interface{}) []interface{} {
|
||||
for i, v := range args {
|
||||
types := datapol.Verify(v)
|
||||
if len(types) > 0 {
|
||||
return []interface{}{fmt.Sprintf(datapolMsgFmt, i, types)}
|
||||
}
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
// FilterF is the filter function for the formatting logging functions of klog
|
||||
func (sf *SanitizingFilter) FilterF(fmt string, args []interface{}) (string, []interface{}) {
|
||||
for i, v := range args {
|
||||
types := datapol.Verify(v)
|
||||
if len(types) > 0 {
|
||||
return datapolMsgFmt, []interface{}{i, types}
|
||||
}
|
||||
}
|
||||
return fmt, args
|
||||
|
||||
}
|
||||
|
||||
// FilterS is the filter for the structured logging functions of klog.
|
||||
func (sf *SanitizingFilter) FilterS(msg string, keysAndValues []interface{}) (string, []interface{}) {
|
||||
for i, v := range keysAndValues {
|
||||
types := datapol.Verify(v)
|
||||
if len(types) > 0 {
|
||||
if i%2 == 0 {
|
||||
return datapolMsg, []interface{}{"key_index", i, "types", types}
|
||||
}
|
||||
// since we scanned linearly we can safely log the key.
|
||||
return datapolMsg, []interface{}{"key", keysAndValues[i-1], "types", types}
|
||||
}
|
||||
}
|
||||
return msg, keysAndValues
|
||||
}
|
||||
Reference in New Issue
Block a user