1
0
mirror of https://github.com/kubernetes-sigs/descheduler.git synced 2026-01-28 14:41:10 +01:00

bump to k8s 1.24-rc.0

This commit is contained in:
JaneLiuL
2022-04-21 08:45:59 +08:00
parent e5ed0540f2
commit ecbd10afe2
942 changed files with 31997 additions and 28908 deletions

View File

@@ -5,8 +5,8 @@
# (b) flags are the bread-and-butter of cli tools.
approvers:
- sig-cli-maintainers
- sig-cli-maintainers
reviewers:
- sig-cli
- sig-cli-reviewers
labels:
- sig/cli
- sig/cli

View File

@@ -34,7 +34,58 @@ import (
// flags get added to the command line if not added already. Flags get normalized
// so that help texts show them with hyphens. Underscores are accepted
// as alternative for the command parameters.
//
// Run tries to be smart about how to print errors that are returned by the
// command: before logging is known to be set up, it prints them as plain text
// to stderr. This covers command line flag parse errors and unknown commands.
// Afterwards it logs them. This covers runtime errors.
//
// Commands like kubectl where logging is not normally part of the runtime output
// should use RunNoErrOutput instead and deal with the returned error themselves.
func Run(cmd *cobra.Command) int {
if logsInitialized, err := run(cmd); err != nil {
// If the error is about flag parsing, then printing that error
// with the decoration that klog would add ("E0923
// 23:02:03.219216 4168816 run.go:61] unknown shorthand flag")
// is less readable. Using klog.Fatal is even worse because it
// dumps a stack trace that isn't about the error.
//
// But if it is some other error encountered at runtime, then
// we want to log it as error, at least in most commands because
// their output is a log event stream.
//
// We can distinguish these two cases depending on whether
// we got to logs.InitLogs() above.
//
// This heuristic might be problematic for command line
// tools like kubectl where the output is carefully controlled
// and not a log by default. They should use RunNoErrOutput
// instead.
//
// The usage of klog is problematic also because we don't know
// whether the command has managed to configure it. This cannot
// be checked right now, but may become possible when the early
// logging proposal from
// https://github.com/kubernetes/enhancements/pull/3078
// ("contextual logging") is implemented.
if !logsInitialized {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
} else {
klog.ErrorS(err, "command failed")
}
return 1
}
return 0
}
// RunNoErrOutput is a version of Run which returns the cobra command error
// instead of printing it.
func RunNoErrOutput(cmd *cobra.Command) error {
_, err := run(cmd)
return err
}
func run(cmd *cobra.Command) (logsInitialized bool, err error) {
rand.Seed(time.Now().UnixNano())
defer logs.FlushLogs()
@@ -51,24 +102,11 @@ func Run(cmd *cobra.Command) int {
// execution fails for other reasons than parsing. We detect this via
// the FlagParseError callback.
//
// A variable is used instead of wrapping the error with a special
// error type because the variable is simpler and less fragile: the
// original FlagErrorFunc might replace the wrapped error.
parsingFailed := false
if cmd.SilenceUsage {
// Some commands, like kubectl, already deal with this themselves.
// We don't change the behavior for those and just track whether
// parsing failed for the error output below.
flagErrorFunc := cmd.FlagErrorFunc()
cmd.SetFlagErrorFunc(func(c *cobra.Command, err error) error {
parsingFailed = true
return flagErrorFunc(c, err)
})
} else {
// Some commands, like kubectl, already deal with this themselves.
// We don't change the behavior for those.
if !cmd.SilenceUsage {
cmd.SilenceUsage = true
cmd.SetFlagErrorFunc(func(c *cobra.Command, err error) error {
parsingFailed = true
// Re-enable usage printing.
c.SilenceUsage = false
return err
@@ -88,38 +126,23 @@ func Run(cmd *cobra.Command) int {
pre := cmd.PersistentPreRun
cmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
logs.InitLogs()
logsInitialized = true
pre(cmd, args)
}
case cmd.PersistentPreRunE != nil:
pre := cmd.PersistentPreRunE
cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
logs.InitLogs()
logsInitialized = true
return pre(cmd, args)
}
default:
cmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
logs.InitLogs()
logsInitialized = true
}
}
if err := cmd.Execute(); err != nil {
// If the error is about flag parsing, then printing that error
// with the decoration that klog would add ("E0923
// 23:02:03.219216 4168816 run.go:61] unknown shorthand flag")
// is less readable. Using klog.Fatal is even worse because it
// dumps a stack trace that isn't about the error.
//
// But if it is some other error encountered at runtime, then
// we want to log it as error.
//
// We can distinguish these two cases depending on whether
// our FlagErrorFunc above was called.
if parsingFailed {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
} else {
klog.ErrorS(err, "command failed")
}
return 1
}
return 0
err = cmd.Execute()
return
}

View File

@@ -4,14 +4,10 @@
options:
no_parent_owners: true
approvers:
- api-approvers
- api-approvers
reviewers:
- api-reviewers
emeritus_reviewers:
- luxas
- mtaufen
- sttts
- api-reviewers
labels:
- kind/api-change
- sig/api-machinery
- sig/scheduling
- kind/api-change
- sig/api-machinery
- sig/scheduling

View File

@@ -42,8 +42,8 @@ func BindLeaderElectionFlags(l *config.LeaderElectionConfiguration, fs *pflag.Fl
"of a leadership. This is only applicable if leader election is enabled.")
fs.StringVar(&l.ResourceLock, "leader-elect-resource-lock", l.ResourceLock, ""+
"The type of resource object that is used for locking during "+
"leader election. Supported options are 'endpoints', 'configmaps', "+
"'leases', 'endpointsleases' and 'configmapsleases'.")
"leader election. Supported options are 'leases', 'endpointsleases' "+
"and 'configmapsleases'.")
fs.StringVar(&l.ResourceName, "leader-elect-resource-name", l.ResourceName, ""+
"The name of resource object that is used for locking during "+
"leader election.")

View File

@@ -93,8 +93,9 @@ type LoggingConfiguration struct {
// Format Flag specifies the structure of log messages.
// default value of format is `text`
Format string
// Maximum number of seconds between log flushes. Ignored if the
// selected logging backend writes log messages without buffering.
// Maximum number of nanoseconds (i.e. 1s = 1000000000) between log
// flushes. Ignored if the selected logging backend writes log
// messages without buffering.
FlushFrequency time.Duration
// Verbosity is the threshold that determines which log messages are
// logged. Default is zero which logs only the most important
@@ -104,9 +105,6 @@ type LoggingConfiguration struct {
// VModule overrides the verbosity threshold for individual files.
// Only supported for "text" log format.
VModule VModuleConfiguration
// [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.`)
Sanitization bool
// [Experimental] Options holds additional parameters that are specific
// to the different logging formats. Only the options for the selected
// format get used, but all of them get validated.

View File

@@ -90,8 +90,9 @@ type LoggingConfiguration struct {
// Format Flag specifies the structure of log messages.
// default value of format is `text`
Format string `json:"format,omitempty"`
// Maximum number of seconds between log flushes. Ignored if the
// selected logging backend writes log messages without buffering.
// Maximum number of nanoseconds (i.e. 1s = 1000000000) between log
// flushes. Ignored if the selected logging backend writes log
// messages without buffering.
FlushFrequency time.Duration `json:"flushFrequency"`
// Verbosity is the threshold that determines which log messages are
// logged. Default is zero which logs only the most important
@@ -101,9 +102,6 @@ type LoggingConfiguration struct {
// VModule overrides the verbosity threshold for individual files.
// Only supported for "text" log format.
VModule VModuleConfiguration `json:"vmodule,omitempty"`
// [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.`)
Sanitization bool `json:"sanitization,omitempty"`
// [Experimental] Options holds additional parameters that are specific
// to the different logging formats. Only the options for the selected
// format get used, but all of them get validated.

View File

@@ -226,7 +226,6 @@ func autoConvert_v1alpha1_LoggingConfiguration_To_config_LoggingConfiguration(in
out.FlushFrequency = time.Duration(in.FlushFrequency)
out.Verbosity = config.VerbosityLevel(in.Verbosity)
out.VModule = *(*config.VModuleConfiguration)(unsafe.Pointer(&in.VModule))
out.Sanitization = in.Sanitization
if err := Convert_v1alpha1_FormatOptions_To_config_FormatOptions(&in.Options, &out.Options, s); err != nil {
return err
}
@@ -238,7 +237,6 @@ func autoConvert_config_LoggingConfiguration_To_v1alpha1_LoggingConfiguration(in
out.FlushFrequency = time.Duration(in.FlushFrequency)
out.Verbosity = uint32(in.Verbosity)
out.VModule = *(*VModuleConfiguration)(unsafe.Pointer(&in.VModule))
out.Sanitization = in.Sanitization
if err := Convert_config_FormatOptions_To_v1alpha1_FormatOptions(&in.Options, &out.Options, s); err != nil {
return err
}

View File

@@ -7,11 +7,10 @@
options:
no_parent_owners: true
approvers:
- api-approvers
- api-approvers
reviewers:
- api-reviewers
- api-reviewers
labels:
- kind/api-change
- sig/api-machinery
- sig/cluster-lifecycle
- kind/api-change
- sig/api-machinery
- sig/cluster-lifecycle

View File

@@ -1,11 +1,12 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- sig-instrumentation-approvers
- serathius
- sig-instrumentation-approvers
- serathius
- pohly
reviewers:
- sig-instrumentation-reviewers
- serathius
- sig-instrumentation-reviewers
- serathius
labels:
- sig/instrumentation
- wg/structured-logging
- sig/instrumentation
- wg/structured-logging

View File

@@ -71,8 +71,6 @@ func BindLoggingFlags(c *config.LoggingConfiguration, fs *pflag.FlagSet) {
fs.DurationVar(&c.FlushFrequency, logFlushFreqFlagName, logFlushFreq, "Maximum number of seconds between log flushes")
fs.VarP(&c.Verbosity, "v", "v", "number for the log level verbosity")
fs.Var(&c.VModule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging (only works for text log format)")
fs.BoolVar(&c.Sanitization, "experimental-logging-sanitization", c.Sanitization, `[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.`)
// JSON options. We only register them if "json" is a valid format. The
// config file API however always has them.

View File

@@ -1,99 +0,0 @@
/*
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
}

View File

@@ -1,49 +0,0 @@
/*
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
}
}

View File

@@ -17,6 +17,7 @@ limitations under the License.
package logs
import (
"io"
"os"
"time"
@@ -36,32 +37,36 @@ var (
// NewJSONLogger creates a new json logr.Logger and its associated
// flush function. The separate error stream is optional and may be nil.
func NewJSONLogger(infoStream, errorStream zapcore.WriteSyncer) (logr.Logger, func()) {
encoder := zapcore.NewJSONEncoder(encoderConfig)
// The encoder config is also optional.
func NewJSONLogger(v config.VerbosityLevel, infoStream, errorStream zapcore.WriteSyncer, encoderConfig *zapcore.EncoderConfig) (logr.Logger, func()) {
// zap levels are inverted: everything with a verbosity >= threshold gets logged.
zapV := -zapcore.Level(v)
if encoderConfig == nil {
encoderConfig = &zapcore.EncoderConfig{
MessageKey: "msg",
CallerKey: "caller",
NameKey: "logger",
TimeKey: "ts",
EncodeTime: epochMillisTimeEncoder,
EncodeDuration: zapcore.StringDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
}
}
encoder := zapcore.NewJSONEncoder(*encoderConfig)
var core zapcore.Core
if errorStream == nil {
core = zapcore.NewCore(encoder, zapcore.AddSync(infoStream), zapcore.Level(-127))
core = zapcore.NewCore(encoder, infoStream, zapV)
} else {
// Set up writing of error messages to stderr and info messages
// to stdout. Info messages get optionally buffered and flushed
// - through klog.FlushLogs -> zapr Flush -> zap Sync
// - when an error gets logged
//
// The later is important when both streams get merged into a single
// stream by the consumer (same console for a command line tool, pod
// log for a container) because without it, messages get reordered.
flushError := writeWithFlushing{
WriteSyncer: errorStream,
other: infoStream,
}
highPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl >= zapcore.ErrorLevel
return lvl >= zapcore.ErrorLevel && lvl >= zapV
})
lowPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl < zapcore.ErrorLevel
return lvl < zapcore.ErrorLevel && lvl >= zapV
})
core = zapcore.NewTee(
zapcore.NewCore(encoder, flushError, highPriority),
zapcore.NewCore(encoder, errorStream, highPriority),
zapcore.NewCore(encoder, infoStream, lowPriority),
)
}
@@ -71,15 +76,6 @@ func NewJSONLogger(infoStream, errorStream zapcore.WriteSyncer) (logr.Logger, fu
}
}
var encoderConfig = zapcore.EncoderConfig{
MessageKey: "msg",
CallerKey: "caller",
TimeKey: "ts",
EncodeTime: epochMillisTimeEncoder,
EncodeDuration: zapcore.StringDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
}
func epochMillisTimeEncoder(_ time.Time, enc zapcore.PrimitiveArrayEncoder) {
nanos := timeNow().UnixNano()
millis := float64(nanos) / float64(time.Millisecond)
@@ -91,37 +87,45 @@ type Factory struct{}
var _ registry.LogFormatFactory = Factory{}
func (f Factory) Create(options config.FormatOptions) (logr.Logger, func()) {
if options.JSON.SplitStream {
// stdout for info messages, stderr for errors.
infoStream := zapcore.Lock(os.Stdout)
size := options.JSON.InfoBufferSize.Value()
func (f Factory) Create(c config.LoggingConfiguration) (logr.Logger, func()) {
// We intentionally avoid all os.File.Sync calls. Output is unbuffered,
// therefore we don't need to flush, and calling the underlying fsync
// would just slow down writing.
//
// The assumption is that logging only needs to ensure that data gets
// written to the output stream before the process terminates, but
// doesn't need to worry about data not being written because of a
// system crash or powerloss.
stderr := zapcore.Lock(AddNopSync(os.Stderr))
if c.Options.JSON.SplitStream {
stdout := zapcore.Lock(AddNopSync(os.Stdout))
size := c.Options.JSON.InfoBufferSize.Value()
if size > 0 {
// Prevent integer overflow.
if size > 2*1024*1024*1024 {
size = 2 * 1024 * 1024 * 1024
}
infoStream = &zapcore.BufferedWriteSyncer{
WS: infoStream,
stdout = &zapcore.BufferedWriteSyncer{
WS: stdout,
Size: int(size),
}
}
return NewJSONLogger(infoStream, zapcore.Lock(os.Stderr))
// stdout for info messages, stderr for errors.
return NewJSONLogger(c.Verbosity, stdout, stderr, nil)
}
// The default is to write to stderr (same as in klog's text output,
// doesn't get mixed with normal program output).
out := zapcore.Lock(os.Stderr)
return NewJSONLogger(out, out)
// Write info messages and errors to stderr to prevent mixing with normal program output.
return NewJSONLogger(c.Verbosity, stderr, nil, nil)
}
// writeWithFlushing is a wrapper around an output stream which flushes another
// output stream before each write.
type writeWithFlushing struct {
zapcore.WriteSyncer
other zapcore.WriteSyncer
// AddNoSync adds a NOP Sync implementation.
func AddNopSync(writer io.Writer) zapcore.WriteSyncer {
return nopSync{Writer: writer}
}
func (f writeWithFlushing) Write(bs []byte) (int, error) {
f.other.Sync()
return f.WriteSyncer.Write(bs)
type nopSync struct {
io.Writer
}
func (f nopSync) Sync() error {
return nil
}

47
vendor/k8s.io/component-base/logs/kube_features.go generated vendored Normal file
View File

@@ -0,0 +1,47 @@
/*
Copyright 2021 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 (
"k8s.io/component-base/featuregate"
)
const (
// owner: @pohly
// kep: http://kep.k8s.io/3077
// alpha: v1.24
//
// Enables looking up a logger from a context.Context instead of using
// the global fallback logger and manipulating the logger that is
// used by a call chain.
ContextualLogging featuregate.Feature = "ContextualLogging"
// contextualLoggingDefault must remain false while in alpha. It can
// become true in beta.
contextualLoggingDefault = false
)
func featureGates() map[featuregate.Feature]featuregate.FeatureSpec {
return map[featuregate.Feature]featuregate.FeatureSpec{
ContextualLogging: {Default: contextualLoggingDefault, PreRelease: featuregate.Alpha},
}
}
// AddFeatureGates adds all feature gates used by this package.
func AddFeatureGates(mutableFeatureGate featuregate.MutableFeatureGate) error {
return mutableFeatureGate.Add(featureGates())
}

View File

@@ -26,7 +26,6 @@ import (
"time"
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/klog/v2"
)
@@ -41,7 +40,6 @@ const deprecated = "will be removed in a future release, see https://github.com/
var (
packageFlags = flag.NewFlagSet("logging", flag.ContinueOnError)
logrFlush func()
// Periodic flushing gets configured either via the global flag
// in this file or via LoggingConfiguration.
@@ -170,14 +168,28 @@ func (writer KlogWriter) Write(data []byte) (n int, err error) {
// InitLogs initializes logs the way we want for Kubernetes.
// It should be called after parsing flags. If called before that,
// it will use the default log settings.
//
// InitLogs disables support for contextual logging in klog while
// that Kubernetes feature is not considered stable yet. Commands
// which want to support contextual logging can:
// - call klog.EnableContextualLogging after calling InitLogs,
// with a fixed `true` or depending on some command line flag or
// a feature gate check
// - set up a FeatureGate instance, the advanced logging configuration
// with Options and call Options.ValidateAndApply with the FeatureGate;
// k8s.io/component-base/logs/example/cmd demonstrates how to do that
func InitLogs() {
log.SetOutput(KlogWriter{})
log.SetFlags(0)
if logFlushFreqAdded {
// The flag from this file was activated, so use it now.
// Otherwise LoggingConfiguration.Apply will do this.
go wait.Forever(FlushLogs, logFlushFreq)
klog.StartFlushDaemon(logFlushFreq)
}
// This is the default in Kubernetes. Options.ValidateAndApply
// will override this with the result of a feature gate check.
klog.EnableContextualLogging(false)
}
// FlushLogs flushes logs immediately. This should be called at the end of
@@ -185,9 +197,6 @@ func InitLogs() {
// are printed before exiting the program.
func FlushLogs() {
klog.Flush()
if logrFlush != nil {
logrFlush()
}
}
// NewLogger creates a new log.Logger which sends logs to klog.Info.

View File

@@ -22,11 +22,10 @@ import (
"github.com/spf13/pflag"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/component-base/config"
"k8s.io/component-base/config/v1alpha1"
"k8s.io/component-base/featuregate"
"k8s.io/component-base/logs/registry"
"k8s.io/component-base/logs/sanitization"
"k8s.io/klog/v2"
)
@@ -48,12 +47,15 @@ func NewOptions() *Options {
// This should be invoked as early as possible because then the rest of the program
// startup (including validation of other options) will already run with the final
// logging configuration.
func (o *Options) ValidateAndApply() error {
//
// The optional FeatureGate controls logging features. If nil, the default for
// these features is used.
func (o *Options) ValidateAndApply(featureGate featuregate.FeatureGate) error {
errs := o.validate()
if len(errs) > 0 {
return utilerrors.NewAggregate(errs)
}
o.apply()
o.apply(featureGate)
return nil
}
@@ -76,18 +78,23 @@ func (o *Options) AddFlags(fs *pflag.FlagSet) {
}
// apply set klog logger from LogFormat type
func (o *Options) apply() {
func (o *Options) apply(featureGate featuregate.FeatureGate) {
contextualLoggingEnabled := contextualLoggingDefault
if featureGate != nil {
contextualLoggingEnabled = featureGate.Enabled(ContextualLogging)
}
// if log format not exists, use nil loggr
factory, _ := registry.LogRegistry.Get(o.Config.Format)
if factory == nil {
klog.ClearLogger()
} else {
log, flush := factory.Create(o.Config.Options)
klog.SetLogger(log)
logrFlush = flush
}
if o.Config.Sanitization {
klog.SetLogFilter(&sanitization.SanitizingFilter{})
// This logger will do its own verbosity checking, using the exact same
// configuration as klog itself.
log, flush := factory.Create(o.Config)
// Therefore it can get called directly. However, we only allow that
// when the feature is enabled.
klog.SetLoggerWithOptions(log, klog.ContextualLogger(contextualLoggingEnabled), klog.FlushLogger(flush))
}
if err := loggingFlags.Lookup("v").Value.Set(o.Config.Verbosity.String()); err != nil {
panic(fmt.Errorf("internal error while setting klog verbosity: %v", err))
@@ -95,5 +102,6 @@ func (o *Options) apply() {
if err := loggingFlags.Lookup("vmodule").Value.Set(o.Config.VModule.String()); err != nil {
panic(fmt.Errorf("internal error while setting klog vmodule: %v", err))
}
go wait.Forever(FlushLogs, o.Config.FlushFrequency)
klog.StartFlushDaemon(o.Config.FlushFrequency)
klog.EnableContextualLogging(contextualLoggingEnabled)
}

View File

@@ -41,7 +41,7 @@ type LogFormatFactory interface {
// Returning a flush function for the logger is optional.
// If provided, the caller must ensure that it is called
// periodically (if desired) and at program exit.
Create(options config.FormatOptions) (log logr.Logger, flush func())
Create(c config.LoggingConfiguration) (log logr.Logger, flush func())
}
// NewLogFormatRegistry return new init LogFormatRegistry struct

View File

@@ -1,69 +0,0 @@
/*
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
}

View File

@@ -1,11 +1,11 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- sig-instrumentation-approvers
- logicalhan
- RainbowMango
- sig-instrumentation-approvers
- logicalhan
- RainbowMango
reviewers:
- sig-instrumentation-reviewers
- YoyinZyc
- sig-instrumentation-reviewers
- YoyinZyc
labels:
- sig/instrumentation
- sig/instrumentation

View File

@@ -19,7 +19,7 @@ package metrics
import (
"fmt"
"github.com/blang/semver"
"github.com/blang/semver/v4"
"github.com/prometheus/client_golang/prometheus"
)

View File

@@ -18,7 +18,7 @@ package metrics
import (
"context"
"github.com/blang/semver"
"github.com/blang/semver/v4"
"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
)
@@ -212,13 +212,13 @@ func (v *CounterVec) Reset() {
func (v *CounterVec) WithContext(ctx context.Context) *CounterVecWithContext {
return &CounterVecWithContext{
ctx: ctx,
CounterVec: *v,
CounterVec: v,
}
}
// CounterVecWithContext is the wrapper of CounterVec with context.
type CounterVecWithContext struct {
CounterVec
*CounterVec
ctx context.Context
}

View File

@@ -20,7 +20,7 @@ import (
"fmt"
"sync"
"github.com/blang/semver"
"github.com/blang/semver/v4"
"github.com/prometheus/client_golang/prometheus"
"k8s.io/klog/v2"

View File

@@ -18,7 +18,7 @@ package metrics
import (
"context"
"github.com/blang/semver"
"github.com/blang/semver/v4"
"github.com/prometheus/client_golang/prometheus"
"k8s.io/component-base/version"
@@ -189,8 +189,8 @@ func (v *GaugeVec) Reset() {
v.GaugeVec.Reset()
}
func newGaugeFunc(opts GaugeOpts, function func() float64, v semver.Version) GaugeFunc {
g := NewGauge(&opts)
func newGaugeFunc(opts *GaugeOpts, function func() float64, v semver.Version) GaugeFunc {
g := NewGauge(opts)
if !g.Create(&v) {
return nil
@@ -205,7 +205,7 @@ func newGaugeFunc(opts GaugeOpts, function func() float64, v semver.Version) Gau
// concurrently. If that results in concurrent calls to Write, like in the case
// where a GaugeFunc is directly registered with Prometheus, the provided
// function must be concurrency-safe.
func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc {
func NewGaugeFunc(opts *GaugeOpts, function func() float64) GaugeFunc {
v := parseVersion(version.Get())
return newGaugeFunc(opts, function, v)
@@ -215,13 +215,13 @@ func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc {
func (v *GaugeVec) WithContext(ctx context.Context) *GaugeVecWithContext {
return &GaugeVecWithContext{
ctx: ctx,
GaugeVec: *v,
GaugeVec: v,
}
}
// GaugeVecWithContext is the wrapper of GaugeVec with context.
type GaugeVecWithContext struct {
GaugeVec
*GaugeVec
ctx context.Context
}

View File

@@ -18,7 +18,7 @@ package metrics
import (
"context"
"github.com/blang/semver"
"github.com/blang/semver/v4"
"github.com/prometheus/client_golang/prometheus"
)
@@ -199,13 +199,13 @@ func (v *HistogramVec) Reset() {
func (v *HistogramVec) WithContext(ctx context.Context) *HistogramVecWithContext {
return &HistogramVecWithContext{
ctx: ctx,
HistogramVec: *v,
HistogramVec: v,
}
}
// HistogramVecWithContext is the wrapper of HistogramVec with context.
type HistogramVecWithContext struct {
HistogramVec
*HistogramVec
ctx context.Context
}

View File

@@ -53,9 +53,6 @@ func init() {
// Handler returns an HTTP handler for the DefaultGatherer. It is
// already instrumented with InstrumentHandler (using "prometheus" as handler
// name).
//
// Deprecated: Please note the issues described in the doc comment of
// InstrumentHandler. You might want to consider using promhttp.Handler instead.
func Handler() http.Handler {
return promhttp.InstrumentMetricHandler(prometheus.DefaultRegisterer, promhttp.HandlerFor(defaultRegistry, promhttp.HandlerOpts{}))
}

View File

@@ -19,7 +19,7 @@ package metrics
import (
"sync"
"github.com/blang/semver"
"github.com/blang/semver/v4"
"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
@@ -169,8 +169,8 @@ func (r *lazyMetric) ClearState() {
r.isDeprecated = false
r.isHidden = false
r.isCreated = false
r.markDeprecationOnce = *(new(sync.Once))
r.createOnce = *(new(sync.Once))
r.markDeprecationOnce = sync.Once{}
r.createOnce = sync.Once{}
}
// FQName returns the fully-qualified metric name of the collector.

View File

@@ -20,7 +20,7 @@ import (
"fmt"
"regexp"
"github.com/blang/semver"
"github.com/blang/semver/v4"
"github.com/spf13/pflag"
"k8s.io/component-base/version"

View File

@@ -21,7 +21,7 @@ import (
"sync"
"sync/atomic"
"github.com/blang/semver"
"github.com/blang/semver/v4"
"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"

View File

@@ -18,7 +18,7 @@ package metrics
import (
"context"
"github.com/blang/semver"
"github.com/blang/semver/v4"
"github.com/prometheus/client_golang/prometheus"
)
@@ -193,13 +193,13 @@ func (v *SummaryVec) Reset() {
func (v *SummaryVec) WithContext(ctx context.Context) *SummaryVecWithContext {
return &SummaryVecWithContext{
ctx: ctx,
SummaryVec: *v,
SummaryVec: v,
}
}
// SummaryVecWithContext is the wrapper of SummaryVec with context.
type SummaryVecWithContext struct {
SummaryVec
*SummaryVec
ctx context.Context
}

View File

@@ -20,7 +20,7 @@ import (
"fmt"
"regexp"
"github.com/blang/semver"
"github.com/blang/semver/v4"
apimachineryversion "k8s.io/apimachinery/pkg/version"
)

View File

@@ -1,8 +1,8 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- sig-instrumentation-approvers
- sig-instrumentation-approvers
reviewers:
- sig-instrumentation-reviewers
- sig-instrumentation-reviewers
labels:
- sig/instrumentation
- sig/instrumentation

View File

@@ -1 +0,0 @@
base.go export-subst

View File

@@ -6,12 +6,11 @@
# each release.
approvers:
- sig-api-machinery-api-approvers
- release-engineering-approvers
- sig-api-machinery-api-approvers
- release-engineering-approvers
reviewers:
- sig-api-machinery-api-reviewers
- release-managers
- sig-api-machinery-api-reviewers
- release-managers
labels:
- sig/api-machinery
- sig/release
- sig/api-machinery
- sig/release