mirror of https://github.com/knative/caching.git
upgrade to latest dependencies (#664)
bumping k8s.io/api e08b72c...f89a761: > f89a761 Update dependencies to v0.23.9 tag bumping k8s.io/client-go 14fa49e...11f68c5: > 11f68c5 Update dependencies to v0.23.9 tag bumping knative.dev/pkg 6c9c1c6...a01dfed: > a01dfed bump to k8s 0.23.9 (# 2565) > 449f7e6 Update community files (# 2564) > ed7ab1d upgrade to latest dependencies (# 2559) bumping k8s.io/apimachinery 276a8a7...276a8a7: bumping k8s.io/code-generator 31c00a6...31c00a6: bumping knative.dev/hack 782bbaa...9dabf7c: > 9dabf7c Update community files (# 206) Signed-off-by: Knative Automation <automation@knative.team>
This commit is contained in:
parent
a0fb648e0c
commit
c920610465
12
go.mod
12
go.mod
|
@ -5,11 +5,11 @@ go 1.15
|
|||
require (
|
||||
github.com/google/go-cmp v0.5.6
|
||||
go.uber.org/zap v1.19.1
|
||||
k8s.io/api v0.23.8
|
||||
k8s.io/apimachinery v0.23.8
|
||||
k8s.io/client-go v0.23.8
|
||||
k8s.io/code-generator v0.23.8
|
||||
k8s.io/api v0.23.9
|
||||
k8s.io/apimachinery v0.23.9
|
||||
k8s.io/client-go v0.23.9
|
||||
k8s.io/code-generator v0.23.9
|
||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65
|
||||
knative.dev/hack v0.0.0-20220725145124-782bbaabb8a1
|
||||
knative.dev/pkg v0.0.0-20220722175921-6c9c1c6098d5
|
||||
knative.dev/hack v0.0.0-20220728013938-9dabf7cf62e3
|
||||
knative.dev/pkg v0.0.0-20220802185824-a01dfedb0486
|
||||
)
|
||||
|
|
38
go.sum
38
go.sum
|
@ -1119,36 +1119,36 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.23.8 h1:tBMQ7z7s1NUUii649OaGe962xPacUzHwnGEj6Ahneu0=
|
||||
k8s.io/api v0.23.8/go.mod h1:26VNldp5fRyiZ/tEO/3V8RJW+In1Aay3YkxsDzkvuWU=
|
||||
k8s.io/apiextensions-apiserver v0.23.8/go.mod h1:pcYtXkSRncXGgCCQSbTqppO3XMaLWdqlDisD4dUKQ/U=
|
||||
k8s.io/apimachinery v0.23.8 h1:6Z+0LLvvPnAF6GXbUcBmzB1+b/AnDZpVd2N0MxUJcl0=
|
||||
k8s.io/apimachinery v0.23.8/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=
|
||||
k8s.io/apiserver v0.23.8/go.mod h1:/WVQG619hfUCgp3pazpqVspyC83NJemH5B0qxlZjNpw=
|
||||
k8s.io/client-go v0.23.8 h1:0POvFP1/bN0DQYO41ks1tdzIBf9I+afqpUUNedyZ3T4=
|
||||
k8s.io/client-go v0.23.8/go.mod h1:m9GosuTn6NlShCjb5XvrRlNDuHeIbGrsDLxjDoS6gec=
|
||||
k8s.io/code-generator v0.23.8 h1:YHHiSaUd2uzLhUpzh1Wlsz20ah0BG6V3gYjkYSte8Gs=
|
||||
k8s.io/code-generator v0.23.8/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk=
|
||||
k8s.io/component-base v0.23.8/go.mod h1:rCj6EeaYLsNneVoFuSPL/AlEWmomc39j9M9i4NpR8r0=
|
||||
k8s.io/api v0.23.9 h1:v7Ee2CZuyb6rVm1q4bUe7ZonWleLsrvgcOTxPGjQVa4=
|
||||
k8s.io/api v0.23.9/go.mod h1:r4g0GrGdLgwSYB90qgO4tBrbKtALBhUfut+oFt4ikCc=
|
||||
k8s.io/apiextensions-apiserver v0.23.9/go.mod h1:uu79PjF1T6YbfFqL5kVTmEdxb40Z0eHM7MfHDHz9dho=
|
||||
k8s.io/apimachinery v0.23.9 h1:u9Pu7Ffe+9+QJUemtNjuCwvHSnOUeYEwgSHV+88Ne0g=
|
||||
k8s.io/apimachinery v0.23.9/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=
|
||||
k8s.io/apiserver v0.23.9/go.mod h1:vIXpgCnHep34bP/y+wGhYdn1NgxAvWtntxfEjst0e74=
|
||||
k8s.io/client-go v0.23.9 h1:OKxNCL+nhw7UBB5b01OVuAV4Db/AdBdaV6/GYpucuOw=
|
||||
k8s.io/client-go v0.23.9/go.mod h1:sNo0X0MZqo4Uu0qDY5Fl5Y60cJFinBDWWUBOAM5JUCM=
|
||||
k8s.io/code-generator v0.23.9 h1:nCvstXOrfWAbxcmrUzJ+TpRsbPHh2XVDNKxqzkH/nH4=
|
||||
k8s.io/code-generator v0.23.9/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk=
|
||||
k8s.io/component-base v0.23.9/go.mod h1:WUNtIRIMd9WBS2r5LCSNZoh6f/Uh+8O+aGuZUG5t428=
|
||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/gengo v0.0.0-20220307231824-4627b89bbf1b h1:vEhKDJESYfeRiaBNmRvO+/12RAo1cFeu6vGm1fBFY34=
|
||||
k8s.io/gengo v0.0.0-20220307231824-4627b89bbf1b/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/gengo v0.0.0-20220613173612-397b4ae3bce7 h1:RGb68G3yotdQggcyenx9y0+lnVJCXXcLa6geXOMlf5o=
|
||||
k8s.io/gengo v0.0.0-20220613173612-397b4ae3bce7/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/klog/v2 v2.60.1-0.20220317184644-43cc75f9ae89 h1:bUNlsw5yb353zbKMj8srOr6V2Ajhz1VkTKonP1L8r2o=
|
||||
k8s.io/klog/v2 v2.60.1-0.20220317184644-43cc75f9ae89/go.mod h1:N3kgBtsFxMb4nQ0eBDgbHEt/dtxBuTkSFQ+7K5OUoz4=
|
||||
k8s.io/klog/v2 v2.70.2-0.20220707122935-0990e81f1a8f h1:dltw7bAn8bCrQ2CmzzhgoieUZEbWqrvIGVdHGioP5nY=
|
||||
k8s.io/klog/v2 v2.70.2-0.20220707122935-0990e81f1a8f/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4=
|
||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
|
||||
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
knative.dev/hack v0.0.0-20220721014222-a6450400b5f1/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||
knative.dev/hack v0.0.0-20220725145124-782bbaabb8a1 h1:90z6q68YSEUuPR5P5j8W6viTO8Pi/MhNnHEIhX3Uvnk=
|
||||
knative.dev/hack v0.0.0-20220725145124-782bbaabb8a1/go.mod h1:t/azP8I/Cygaw+87O7rkAPrNRjCelmtfSzWzu/9TM7I=
|
||||
knative.dev/pkg v0.0.0-20220722175921-6c9c1c6098d5 h1:wfxvM/LiVcnHxZCOeBQwFcjJxIGIhhNglK0uj3dwmms=
|
||||
knative.dev/pkg v0.0.0-20220722175921-6c9c1c6098d5/go.mod h1:zaGmg6so9RiTx8Fu6vCSUClfVtOBtCrsD/j3c2y+no8=
|
||||
knative.dev/hack v0.0.0-20220728013938-9dabf7cf62e3 h1:1JsQ8ylMK+9yQfuxXvGBux+NOzvNLQyoyTXlupBrfHE=
|
||||
knative.dev/hack v0.0.0-20220728013938-9dabf7cf62e3/go.mod h1:t/azP8I/Cygaw+87O7rkAPrNRjCelmtfSzWzu/9TM7I=
|
||||
knative.dev/pkg v0.0.0-20220802185824-a01dfedb0486 h1:eWw7LtEIq2GjR9Z5Uw86BlVYyLh50ueJfcXV0SQiMWc=
|
||||
knative.dev/pkg v0.0.0-20220802185824-a01dfedb0486/go.mod h1:nBMKMJvyoaJdkpUrjwLVs/DwaP6d73R3UkXK6lblJyE=
|
||||
pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
|
|
|
@ -28,12 +28,14 @@ Historical context is available here:
|
|||
Semantic versioning is used in this repository. It contains several Go modules
|
||||
with different levels of stability:
|
||||
- `k8s.io/klog/v2` - stable API, `vX.Y.Z` tags
|
||||
- `k8s.io/tools` - no stable API yet (may change eventually), `tools/v0.Y.Z` tags
|
||||
- `examples` - no stable API, no tags, no intention to ever stabilize
|
||||
|
||||
Exempt from the API stability guarantee are items (packages, functions, etc.)
|
||||
which are marked explicitly as `EXPERIMENTAL` in their docs comment. Those
|
||||
may still change in incompatible ways or get removed entirely.
|
||||
may still change in incompatible ways or get removed entirely. This can only
|
||||
be used for code that is used in tests to avoid situations where non-test
|
||||
code from two different Kubernetes dependencies depends on incompatible
|
||||
releases of klog because an experimental API was changed.
|
||||
|
||||
----
|
||||
|
||||
|
|
|
@ -34,18 +34,6 @@ import (
|
|||
// mutex locking.
|
||||
|
||||
var (
|
||||
// contextualLoggingEnabled controls whether contextual logging is
|
||||
// active. Disabling it may have some small performance benefit.
|
||||
contextualLoggingEnabled = true
|
||||
|
||||
// globalLogger is the global Logger chosen by users of klog, nil if
|
||||
// none is available.
|
||||
globalLogger *Logger
|
||||
|
||||
// globalLoggerOptions contains the options that were supplied for
|
||||
// globalLogger.
|
||||
globalLoggerOptions loggerOptions
|
||||
|
||||
// klogLogger is used as fallback for logging through the normal klog code
|
||||
// when no Logger is set.
|
||||
klogLogger logr.Logger = logr.New(&klogger{})
|
||||
|
@ -80,27 +68,17 @@ func SetLogger(logger logr.Logger) {
|
|||
// Supporting direct calls is recommended because it avoids the overhead of
|
||||
// routing log entries through klogr into klog and then into the actual Logger
|
||||
// backend.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func SetLoggerWithOptions(logger logr.Logger, opts ...LoggerOption) {
|
||||
globalLogger = &logger
|
||||
globalLoggerOptions = loggerOptions{}
|
||||
logging.logger = &logger
|
||||
logging.loggerOptions = loggerOptions{}
|
||||
for _, opt := range opts {
|
||||
opt(&globalLoggerOptions)
|
||||
opt(&logging.loggerOptions)
|
||||
}
|
||||
}
|
||||
|
||||
// ContextualLogger determines whether the logger passed to
|
||||
// SetLoggerWithOptions may also get called directly. Such a logger cannot rely
|
||||
// on verbosity checking in klog.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func ContextualLogger(enabled bool) LoggerOption {
|
||||
return func(o *loggerOptions) {
|
||||
o.contextualLogger = enabled
|
||||
|
@ -108,11 +86,6 @@ func ContextualLogger(enabled bool) LoggerOption {
|
|||
}
|
||||
|
||||
// FlushLogger provides a callback for flushing data buffered by the logger.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func FlushLogger(flush func()) LoggerOption {
|
||||
return func(o *loggerOptions) {
|
||||
o.flush = flush
|
||||
|
@ -121,11 +94,6 @@ func FlushLogger(flush func()) LoggerOption {
|
|||
|
||||
// LoggerOption implements the functional parameter paradigm for
|
||||
// SetLoggerWithOptions.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type LoggerOption func(o *loggerOptions)
|
||||
|
||||
type loggerOptions struct {
|
||||
|
@ -139,8 +107,8 @@ type loggerOptions struct {
|
|||
// Modifying the logger is not thread-safe and should be done while no other
|
||||
// goroutines invoke log calls, usually during program initialization.
|
||||
func ClearLogger() {
|
||||
globalLogger = nil
|
||||
globalLoggerOptions = loggerOptions{}
|
||||
logging.logger = nil
|
||||
logging.loggerOptions = loggerOptions{}
|
||||
}
|
||||
|
||||
// EnableContextualLogging controls whether contextual logging is enabled.
|
||||
|
@ -151,25 +119,15 @@ func ClearLogger() {
|
|||
// to avoid the additional overhead for contextual logging.
|
||||
//
|
||||
// This must be called during initialization before goroutines are started.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func EnableContextualLogging(enabled bool) {
|
||||
contextualLoggingEnabled = enabled
|
||||
logging.contextualLoggingEnabled = enabled
|
||||
}
|
||||
|
||||
// FromContext retrieves a logger set by the caller or, if not set,
|
||||
// falls back to the program's global logger (a Logger instance or klog
|
||||
// itself).
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func FromContext(ctx context.Context) Logger {
|
||||
if contextualLoggingEnabled {
|
||||
if logging.contextualLoggingEnabled {
|
||||
if logger, err := logr.FromContext(ctx); err == nil {
|
||||
return logger
|
||||
}
|
||||
|
@ -181,11 +139,6 @@ func FromContext(ctx context.Context) Logger {
|
|||
// TODO can be used as a last resort by code that has no means of
|
||||
// receiving a logger from its caller. FromContext or an explicit logger
|
||||
// parameter should be used instead.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func TODO() Logger {
|
||||
return Background()
|
||||
}
|
||||
|
@ -194,16 +147,11 @@ func TODO() Logger {
|
|||
// that logger was initialized by the program and not by code that should
|
||||
// better receive a logger via its parameters. TODO can be used as a temporary
|
||||
// solution for such code.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func Background() Logger {
|
||||
if globalLoggerOptions.contextualLogger {
|
||||
// Is non-nil because globalLoggerOptions.contextualLogger is
|
||||
if logging.loggerOptions.contextualLogger {
|
||||
// Is non-nil because logging.loggerOptions.contextualLogger is
|
||||
// only true if a logger was set.
|
||||
return *globalLogger
|
||||
return *logging.logger
|
||||
}
|
||||
|
||||
return klogLogger
|
||||
|
@ -211,13 +159,8 @@ func Background() Logger {
|
|||
|
||||
// LoggerWithValues returns logger.WithValues(...kv) when
|
||||
// contextual logging is enabled, otherwise the logger.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func LoggerWithValues(logger Logger, kv ...interface{}) Logger {
|
||||
if contextualLoggingEnabled {
|
||||
if logging.contextualLoggingEnabled {
|
||||
return logger.WithValues(kv...)
|
||||
}
|
||||
return logger
|
||||
|
@ -225,13 +168,8 @@ func LoggerWithValues(logger Logger, kv ...interface{}) Logger {
|
|||
|
||||
// LoggerWithName returns logger.WithName(name) when contextual logging is
|
||||
// enabled, otherwise the logger.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func LoggerWithName(logger Logger, name string) Logger {
|
||||
if contextualLoggingEnabled {
|
||||
if logging.contextualLoggingEnabled {
|
||||
return logger.WithName(name)
|
||||
}
|
||||
return logger
|
||||
|
@ -239,13 +177,8 @@ func LoggerWithName(logger Logger, name string) Logger {
|
|||
|
||||
// NewContext returns logr.NewContext(ctx, logger) when
|
||||
// contextual logging is enabled, otherwise ctx.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func NewContext(ctx context.Context, logger Logger) context.Context {
|
||||
if contextualLoggingEnabled {
|
||||
if logging.contextualLoggingEnabled {
|
||||
return logr.NewContext(ctx, logger)
|
||||
}
|
||||
return ctx
|
||||
|
|
|
@ -2,7 +2,4 @@ module k8s.io/klog/v2
|
|||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/go-logr/logr v1.2.0
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
|
||||
)
|
||||
require github.com/go-logr/logr v1.2.0
|
||||
|
|
|
@ -1,13 +1,2 @@
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE=
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
|
|
|
@ -24,35 +24,15 @@ import (
|
|||
// without directly importing it.
|
||||
|
||||
// Logger in this package is exactly the same as logr.Logger.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type Logger = logr.Logger
|
||||
|
||||
// LogSink in this package is exactly the same as logr.LogSink.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type LogSink = logr.LogSink
|
||||
|
||||
// Runtimeinfo in this package is exactly the same as logr.RuntimeInfo.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This type is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
type RuntimeInfo = logr.RuntimeInfo
|
||||
|
||||
var (
|
||||
// New is an alias for logr.New.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This variable is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
New = logr.New
|
||||
)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# Clock
|
||||
|
||||
This package provides an interface for time-based operations. It allows
|
||||
mocking time for testing.
|
||||
|
||||
This is a copy of k8s.io/utils/clock. We have to copy it to avoid a circular
|
||||
dependency (k8s.io/klog -> k8s.io/utils -> k8s.io/klog).
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
Copyright 2014 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 clock
|
||||
|
||||
import "time"
|
||||
|
||||
// PassiveClock allows for injecting fake or real clocks into code
|
||||
// that needs to read the current time but does not support scheduling
|
||||
// activity in the future.
|
||||
type PassiveClock interface {
|
||||
Now() time.Time
|
||||
Since(time.Time) time.Duration
|
||||
}
|
||||
|
||||
// Clock allows for injecting fake or real clocks into code that
|
||||
// needs to do arbitrary things based on time.
|
||||
type Clock interface {
|
||||
PassiveClock
|
||||
// After returns the channel of a new Timer.
|
||||
// This method does not allow to free/GC the backing timer before it fires. Use
|
||||
// NewTimer instead.
|
||||
After(d time.Duration) <-chan time.Time
|
||||
// NewTimer returns a new Timer.
|
||||
NewTimer(d time.Duration) Timer
|
||||
// Sleep sleeps for the provided duration d.
|
||||
// Consider making the sleep interruptible by using 'select' on a context channel and a timer channel.
|
||||
Sleep(d time.Duration)
|
||||
// Tick returns the channel of a new Ticker.
|
||||
// This method does not allow to free/GC the backing ticker. Use
|
||||
// NewTicker from WithTicker instead.
|
||||
Tick(d time.Duration) <-chan time.Time
|
||||
}
|
||||
|
||||
// WithTicker allows for injecting fake or real clocks into code that
|
||||
// needs to do arbitrary things based on time.
|
||||
type WithTicker interface {
|
||||
Clock
|
||||
// NewTicker returns a new Ticker.
|
||||
NewTicker(time.Duration) Ticker
|
||||
}
|
||||
|
||||
// WithDelayedExecution allows for injecting fake or real clocks into
|
||||
// code that needs to make use of AfterFunc functionality.
|
||||
type WithDelayedExecution interface {
|
||||
Clock
|
||||
// AfterFunc executes f in its own goroutine after waiting
|
||||
// for d duration and returns a Timer whose channel can be
|
||||
// closed by calling Stop() on the Timer.
|
||||
AfterFunc(d time.Duration, f func()) Timer
|
||||
}
|
||||
|
||||
// WithTickerAndDelayedExecution allows for injecting fake or real clocks
|
||||
// into code that needs Ticker and AfterFunc functionality
|
||||
type WithTickerAndDelayedExecution interface {
|
||||
WithTicker
|
||||
// AfterFunc executes f in its own goroutine after waiting
|
||||
// for d duration and returns a Timer whose channel can be
|
||||
// closed by calling Stop() on the Timer.
|
||||
AfterFunc(d time.Duration, f func()) Timer
|
||||
}
|
||||
|
||||
// Ticker defines the Ticker interface.
|
||||
type Ticker interface {
|
||||
C() <-chan time.Time
|
||||
Stop()
|
||||
}
|
||||
|
||||
var _ = WithTicker(RealClock{})
|
||||
|
||||
// RealClock really calls time.Now()
|
||||
type RealClock struct{}
|
||||
|
||||
// Now returns the current time.
|
||||
func (RealClock) Now() time.Time {
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
// Since returns time since the specified timestamp.
|
||||
func (RealClock) Since(ts time.Time) time.Duration {
|
||||
return time.Since(ts)
|
||||
}
|
||||
|
||||
// After is the same as time.After(d).
|
||||
// This method does not allow to free/GC the backing timer before it fires. Use
|
||||
// NewTimer instead.
|
||||
func (RealClock) After(d time.Duration) <-chan time.Time {
|
||||
return time.After(d)
|
||||
}
|
||||
|
||||
// NewTimer is the same as time.NewTimer(d)
|
||||
func (RealClock) NewTimer(d time.Duration) Timer {
|
||||
return &realTimer{
|
||||
timer: time.NewTimer(d),
|
||||
}
|
||||
}
|
||||
|
||||
// AfterFunc is the same as time.AfterFunc(d, f).
|
||||
func (RealClock) AfterFunc(d time.Duration, f func()) Timer {
|
||||
return &realTimer{
|
||||
timer: time.AfterFunc(d, f),
|
||||
}
|
||||
}
|
||||
|
||||
// Tick is the same as time.Tick(d)
|
||||
// This method does not allow to free/GC the backing ticker. Use
|
||||
// NewTicker instead.
|
||||
func (RealClock) Tick(d time.Duration) <-chan time.Time {
|
||||
return time.Tick(d)
|
||||
}
|
||||
|
||||
// NewTicker returns a new Ticker.
|
||||
func (RealClock) NewTicker(d time.Duration) Ticker {
|
||||
return &realTicker{
|
||||
ticker: time.NewTicker(d),
|
||||
}
|
||||
}
|
||||
|
||||
// Sleep is the same as time.Sleep(d)
|
||||
// Consider making the sleep interruptible by using 'select' on a context channel and a timer channel.
|
||||
func (RealClock) Sleep(d time.Duration) {
|
||||
time.Sleep(d)
|
||||
}
|
||||
|
||||
// Timer allows for injecting fake or real timers into code that
|
||||
// needs to do arbitrary things based on time.
|
||||
type Timer interface {
|
||||
C() <-chan time.Time
|
||||
Stop() bool
|
||||
Reset(d time.Duration) bool
|
||||
}
|
||||
|
||||
var _ = Timer(&realTimer{})
|
||||
|
||||
// realTimer is backed by an actual time.Timer.
|
||||
type realTimer struct {
|
||||
timer *time.Timer
|
||||
}
|
||||
|
||||
// C returns the underlying timer's channel.
|
||||
func (r *realTimer) C() <-chan time.Time {
|
||||
return r.timer.C
|
||||
}
|
||||
|
||||
// Stop calls Stop() on the underlying timer.
|
||||
func (r *realTimer) Stop() bool {
|
||||
return r.timer.Stop()
|
||||
}
|
||||
|
||||
// Reset calls Reset() on the underlying timer.
|
||||
func (r *realTimer) Reset(d time.Duration) bool {
|
||||
return r.timer.Reset(d)
|
||||
}
|
||||
|
||||
type realTicker struct {
|
||||
ticker *time.Ticker
|
||||
}
|
||||
|
||||
func (r *realTicker) C() <-chan time.Time {
|
||||
return r.ticker.C
|
||||
}
|
||||
|
||||
func (r *realTicker) Stop() {
|
||||
r.ticker.Stop()
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
|
||||
//
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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 dbg provides some helper code for call traces.
|
||||
package dbg
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Stacks is a wrapper for runtime.Stack that attempts to recover the data for
|
||||
// all goroutines or the calling one.
|
||||
func Stacks(all bool) []byte {
|
||||
// We don't know how big the traces are, so grow a few times if they don't fit. Start large, though.
|
||||
n := 10000
|
||||
if all {
|
||||
n = 100000
|
||||
}
|
||||
var trace []byte
|
||||
for i := 0; i < 5; i++ {
|
||||
trace = make([]byte, n)
|
||||
nbytes := runtime.Stack(trace, all)
|
||||
if nbytes < len(trace) {
|
||||
return trace[:nbytes]
|
||||
}
|
||||
n *= 2
|
||||
}
|
||||
return trace
|
||||
}
|
|
@ -20,6 +20,8 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
)
|
||||
|
||||
// WithValues implements LogSink.WithValues. The old key/value pairs are
|
||||
|
@ -44,53 +46,49 @@ func WithValues(oldKV, newKV []interface{}) []interface{} {
|
|||
return kv
|
||||
}
|
||||
|
||||
// TrimDuplicates deduplicates elements provided in multiple key/value tuple
|
||||
// slices, whilst maintaining the distinction between where the items are
|
||||
// contained.
|
||||
func TrimDuplicates(kvLists ...[]interface{}) [][]interface{} {
|
||||
// maintain a map of all seen keys
|
||||
seenKeys := map[interface{}]struct{}{}
|
||||
// build the same number of output slices as inputs
|
||||
outs := make([][]interface{}, len(kvLists))
|
||||
// iterate over the input slices backwards, as 'later' kv specifications
|
||||
// of the same key will take precedence over earlier ones
|
||||
for i := len(kvLists) - 1; i >= 0; i-- {
|
||||
// initialise this output slice
|
||||
outs[i] = []interface{}{}
|
||||
// obtain a reference to the kvList we are processing
|
||||
// and make sure it has an even number of entries
|
||||
kvList := kvLists[i]
|
||||
if len(kvList)%2 != 0 {
|
||||
kvList = append(kvList, missingValue)
|
||||
// MergeKVs deduplicates elements provided in two key/value slices.
|
||||
//
|
||||
// Keys in each slice are expected to be unique, so duplicates can only occur
|
||||
// when the first and second slice contain the same key. When that happens, the
|
||||
// key/value pair from the second slice is used. The first slice must be well-formed
|
||||
// (= even key/value pairs). The second one may have a missing value, in which
|
||||
// case the special "missing value" is added to the result.
|
||||
func MergeKVs(first, second []interface{}) []interface{} {
|
||||
maxLength := len(first) + (len(second)+1)/2*2
|
||||
if maxLength == 0 {
|
||||
// Nothing to do at all.
|
||||
return nil
|
||||
}
|
||||
|
||||
// start iterating at len(kvList) - 2 (i.e. the 2nd last item) for
|
||||
// slices that have an even number of elements.
|
||||
// We add (len(kvList) % 2) here to handle the case where there is an
|
||||
// odd number of elements in a kvList.
|
||||
// If there is an odd number, then the last element in the slice will
|
||||
// have the value 'null'.
|
||||
for i2 := len(kvList) - 2 + (len(kvList) % 2); i2 >= 0; i2 -= 2 {
|
||||
k := kvList[i2]
|
||||
// if we have already seen this key, do not include it again
|
||||
if _, ok := seenKeys[k]; ok {
|
||||
if len(first) == 0 && len(second)%2 == 0 {
|
||||
// Nothing to be overridden, second slice is well-formed
|
||||
// and can be used directly.
|
||||
return second
|
||||
}
|
||||
|
||||
// Determine which keys are in the second slice so that we can skip
|
||||
// them when iterating over the first one. The code intentionally
|
||||
// favors performance over completeness: we assume that keys are string
|
||||
// constants and thus compare equal when the string values are equal. A
|
||||
// string constant being overridden by, for example, a fmt.Stringer is
|
||||
// not handled.
|
||||
overrides := map[interface{}]bool{}
|
||||
for i := 0; i < len(second); i += 2 {
|
||||
overrides[second[i]] = true
|
||||
}
|
||||
merged := make([]interface{}, 0, maxLength)
|
||||
for i := 0; i+1 < len(first); i += 2 {
|
||||
key := first[i]
|
||||
if overrides[key] {
|
||||
continue
|
||||
}
|
||||
// make a note that we've observed a new key
|
||||
seenKeys[k] = struct{}{}
|
||||
// attempt to obtain the value of the key
|
||||
var v interface{}
|
||||
// i2+1 should only ever be out of bounds if we handling the first
|
||||
// iteration over a slice with an odd number of elements
|
||||
if i2+1 < len(kvList) {
|
||||
v = kvList[i2+1]
|
||||
merged = append(merged, key, first[i+1])
|
||||
}
|
||||
// add this KV tuple to the *start* of the output list to maintain
|
||||
// the original order as we are iterating over the slice backwards
|
||||
outs[i] = append([]interface{}{k, v}, outs[i]...)
|
||||
merged = append(merged, second...)
|
||||
if len(merged)%2 != 0 {
|
||||
merged = append(merged, missingValue)
|
||||
}
|
||||
}
|
||||
return outs
|
||||
return merged
|
||||
}
|
||||
|
||||
const missingValue = "(MISSING)"
|
||||
|
@ -111,10 +109,10 @@ func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) {
|
|||
// https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments
|
||||
// for the sake of performance. Keys with spaces,
|
||||
// special characters, etc. will break parsing.
|
||||
if k, ok := k.(string); ok {
|
||||
if sK, ok := k.(string); ok {
|
||||
// Avoid one allocation when the key is a string, which
|
||||
// normally it should be.
|
||||
b.WriteString(k)
|
||||
b.WriteString(sK)
|
||||
} else {
|
||||
b.WriteString(fmt.Sprintf("%s", k))
|
||||
}
|
||||
|
@ -131,6 +129,24 @@ func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) {
|
|||
writeStringValue(b, true, v)
|
||||
case error:
|
||||
writeStringValue(b, true, ErrorToString(v))
|
||||
case logr.Marshaler:
|
||||
value := MarshalerToValue(v)
|
||||
// A marshaler that returns a string is useful for
|
||||
// delayed formatting of complex values. We treat this
|
||||
// case like a normal string. This is useful for
|
||||
// multi-line support.
|
||||
//
|
||||
// We could do this by recursively formatting a value,
|
||||
// but that comes with the risk of infinite recursion
|
||||
// if a marshaler returns itself. Instead we call it
|
||||
// only once and rely on it returning the intended
|
||||
// value directly.
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
writeStringValue(b, true, value)
|
||||
default:
|
||||
writeStringValue(b, false, fmt.Sprintf("%+v", v))
|
||||
}
|
||||
case []byte:
|
||||
// In https://github.com/kubernetes/klog/pull/237 it was decided
|
||||
// to format byte slices with "%+q". The advantages of that are:
|
||||
|
@ -163,6 +179,18 @@ func StringerToString(s fmt.Stringer) (ret string) {
|
|||
return
|
||||
}
|
||||
|
||||
// MarshalerToValue invokes a marshaler and catches
|
||||
// panics.
|
||||
func MarshalerToValue(m logr.Marshaler) (ret interface{}) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
ret = fmt.Sprintf("<panic: %s>", err)
|
||||
}
|
||||
}()
|
||||
ret = m.MarshalLog()
|
||||
return
|
||||
}
|
||||
|
||||
// ErrorToString converts an error to a string,
|
||||
// handling panics if they occur.
|
||||
func ErrorToString(err error) (ret string) {
|
||||
|
|
|
@ -77,6 +77,8 @@ func KRef(namespace, name string) ObjectRef {
|
|||
}
|
||||
|
||||
// KObjs returns slice of ObjectRef from an slice of ObjectMeta
|
||||
//
|
||||
// DEPRECATED: Use KObjSlice instead, it has better performance.
|
||||
func KObjs(arg interface{}) []ObjectRef {
|
||||
s := reflect.ValueOf(arg)
|
||||
if s.Kind() != reflect.Slice {
|
||||
|
@ -92,3 +94,65 @@ func KObjs(arg interface{}) []ObjectRef {
|
|||
}
|
||||
return objectRefs
|
||||
}
|
||||
|
||||
// KObjSlice takes a slice of objects that implement the KMetadata interface
|
||||
// and returns an object that gets logged as a slice of ObjectRef values or a
|
||||
// string containing those values, depending on whether the logger prefers text
|
||||
// output or structured output.
|
||||
//
|
||||
// An error string is logged when KObjSlice is not passed a suitable slice.
|
||||
//
|
||||
// Processing of the argument is delayed until the value actually gets logged,
|
||||
// in contrast to KObjs where that overhead is incurred regardless of whether
|
||||
// the result is needed.
|
||||
func KObjSlice(arg interface{}) interface{} {
|
||||
return kobjSlice{arg: arg}
|
||||
}
|
||||
|
||||
type kobjSlice struct {
|
||||
arg interface{}
|
||||
}
|
||||
|
||||
var _ fmt.Stringer = kobjSlice{}
|
||||
var _ logr.Marshaler = kobjSlice{}
|
||||
|
||||
func (ks kobjSlice) String() string {
|
||||
objectRefs, err := ks.process()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return fmt.Sprintf("%v", objectRefs)
|
||||
}
|
||||
|
||||
func (ks kobjSlice) MarshalLog() interface{} {
|
||||
objectRefs, err := ks.process()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return objectRefs
|
||||
}
|
||||
|
||||
func (ks kobjSlice) process() ([]interface{}, error) {
|
||||
s := reflect.ValueOf(ks.arg)
|
||||
switch s.Kind() {
|
||||
case reflect.Invalid:
|
||||
// nil parameter, print as nil.
|
||||
return nil, nil
|
||||
case reflect.Slice:
|
||||
// Okay, handle below.
|
||||
default:
|
||||
return nil, fmt.Errorf("<KObjSlice needs a slice, got type %T>", ks.arg)
|
||||
}
|
||||
objectRefs := make([]interface{}, 0, s.Len())
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
item := s.Index(i).Interface()
|
||||
if item == nil {
|
||||
objectRefs = append(objectRefs, nil)
|
||||
} else if v, ok := item.(KMetadata); ok {
|
||||
objectRefs = append(objectRefs, KObj(v))
|
||||
} else {
|
||||
return nil, fmt.Errorf("<KObjSlice needs a slice of values implementing KMetadata, got type %T>", item)
|
||||
}
|
||||
}
|
||||
return objectRefs, nil
|
||||
}
|
||||
|
|
|
@ -41,6 +41,10 @@
|
|||
//
|
||||
// -logtostderr=true
|
||||
// Logs are written to standard error instead of to files.
|
||||
// This shortcuts most of the usual output routing:
|
||||
// -alsologtostderr, -stderrthreshold and -log_dir have no
|
||||
// effect and output redirection at runtime with SetOutput is
|
||||
// ignored.
|
||||
// -alsologtostderr=false
|
||||
// Logs are written to standard error as well as to files.
|
||||
// -stderrthreshold=ERROR
|
||||
|
@ -91,9 +95,10 @@ import (
|
|||
"github.com/go-logr/logr"
|
||||
|
||||
"k8s.io/klog/v2/internal/buffer"
|
||||
"k8s.io/klog/v2/internal/clock"
|
||||
"k8s.io/klog/v2/internal/dbg"
|
||||
"k8s.io/klog/v2/internal/serialize"
|
||||
"k8s.io/klog/v2/internal/severity"
|
||||
"k8s.io/utils/clock"
|
||||
)
|
||||
|
||||
// severityValue identifies the sort of log: info, warning etc. It also implements
|
||||
|
@ -242,6 +247,10 @@ func (m *moduleSpec) String() string {
|
|||
// Lock because the type is not atomic. TODO: clean this up.
|
||||
logging.mu.Lock()
|
||||
defer logging.mu.Unlock()
|
||||
return m.serialize()
|
||||
}
|
||||
|
||||
func (m *moduleSpec) serialize() string {
|
||||
var b bytes.Buffer
|
||||
for i, f := range m.filter {
|
||||
if i > 0 {
|
||||
|
@ -263,6 +272,17 @@ var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of
|
|||
// Set will sets module value
|
||||
// Syntax: -vmodule=recordio=2,file=1,gfs*=3
|
||||
func (m *moduleSpec) Set(value string) error {
|
||||
filter, err := parseModuleSpec(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logging.mu.Lock()
|
||||
defer logging.mu.Unlock()
|
||||
logging.setVState(logging.verbosity, filter, true)
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseModuleSpec(value string) ([]modulePat, error) {
|
||||
var filter []modulePat
|
||||
for _, pat := range strings.Split(value, ",") {
|
||||
if len(pat) == 0 {
|
||||
|
@ -271,15 +291,15 @@ func (m *moduleSpec) Set(value string) error {
|
|||
}
|
||||
patLev := strings.Split(pat, "=")
|
||||
if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
|
||||
return errVmoduleSyntax
|
||||
return nil, errVmoduleSyntax
|
||||
}
|
||||
pattern := patLev[0]
|
||||
v, err := strconv.ParseInt(patLev[1], 10, 32)
|
||||
if err != nil {
|
||||
return errors.New("syntax error: expect comma-separated list of filename=N")
|
||||
return nil, errors.New("syntax error: expect comma-separated list of filename=N")
|
||||
}
|
||||
if v < 0 {
|
||||
return errors.New("negative value for vmodule level")
|
||||
return nil, errors.New("negative value for vmodule level")
|
||||
}
|
||||
if v == 0 {
|
||||
continue // Ignore. It's harmless but no point in paying the overhead.
|
||||
|
@ -287,10 +307,7 @@ func (m *moduleSpec) Set(value string) error {
|
|||
// TODO: check syntax of filter?
|
||||
filter = append(filter, modulePat{pattern, isLiteral(pattern), Level(v)})
|
||||
}
|
||||
logging.mu.Lock()
|
||||
defer logging.mu.Unlock()
|
||||
logging.setVState(logging.verbosity, filter, true)
|
||||
return nil
|
||||
return filter, nil
|
||||
}
|
||||
|
||||
// isLiteral reports whether the pattern is a literal string, that is, has no metacharacters
|
||||
|
@ -404,19 +421,19 @@ func InitFlags(flagset *flag.FlagSet) {
|
|||
flagset = flag.CommandLine
|
||||
}
|
||||
|
||||
flagset.StringVar(&logging.logDir, "log_dir", logging.logDir, "If non-empty, write log files in this directory")
|
||||
flagset.StringVar(&logging.logFile, "log_file", logging.logFile, "If non-empty, use this log file")
|
||||
flagset.StringVar(&logging.logDir, "log_dir", logging.logDir, "If non-empty, write log files in this directory (no effect when -logtostderr=true)")
|
||||
flagset.StringVar(&logging.logFile, "log_file", logging.logFile, "If non-empty, use this log file (no effect when -logtostderr=true)")
|
||||
flagset.Uint64Var(&logging.logFileMaxSizeMB, "log_file_max_size", logging.logFileMaxSizeMB,
|
||||
"Defines the maximum size a log file can grow to. Unit is megabytes. "+
|
||||
"Defines the maximum size a log file can grow to (no effect when -logtostderr=true). Unit is megabytes. "+
|
||||
"If the value is 0, the maximum file size is unlimited.")
|
||||
flagset.BoolVar(&logging.toStderr, "logtostderr", logging.toStderr, "log to standard error instead of files")
|
||||
flagset.BoolVar(&logging.alsoToStderr, "alsologtostderr", logging.alsoToStderr, "log to standard error as well as files")
|
||||
flagset.BoolVar(&logging.alsoToStderr, "alsologtostderr", logging.alsoToStderr, "log to standard error as well as files (no effect when -logtostderr=true)")
|
||||
flagset.Var(&logging.verbosity, "v", "number for the log level verbosity")
|
||||
flagset.BoolVar(&logging.addDirHeader, "add_dir_header", logging.addDirHeader, "If true, adds the file directory to the header of the log messages")
|
||||
flagset.BoolVar(&logging.skipHeaders, "skip_headers", logging.skipHeaders, "If true, avoid header prefixes in the log messages")
|
||||
flagset.BoolVar(&logging.oneOutput, "one_output", logging.oneOutput, "If true, only write logs to their native severity level (vs also writing to each lower severity level)")
|
||||
flagset.BoolVar(&logging.skipLogHeaders, "skip_log_headers", logging.skipLogHeaders, "If true, avoid headers when opening log files")
|
||||
flagset.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr")
|
||||
flagset.BoolVar(&logging.oneOutput, "one_output", logging.oneOutput, "If true, only write logs to their native severity level (vs also writing to each lower severity level; no effect when -logtostderr=true)")
|
||||
flagset.BoolVar(&logging.skipLogHeaders, "skip_log_headers", logging.skipLogHeaders, "If true, avoid headers when opening log files (no effect when -logtostderr=true)")
|
||||
flagset.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=false)")
|
||||
flagset.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging")
|
||||
flagset.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace")
|
||||
}
|
||||
|
@ -426,8 +443,20 @@ func Flush() {
|
|||
logging.lockAndFlushAll()
|
||||
}
|
||||
|
||||
// loggingT collects all the global state of the logging setup.
|
||||
type loggingT struct {
|
||||
// settings collects global settings.
|
||||
type settings struct {
|
||||
// contextualLoggingEnabled controls whether contextual logging is
|
||||
// active. Disabling it may have some small performance benefit.
|
||||
contextualLoggingEnabled bool
|
||||
|
||||
// logger is the global Logger chosen by users of klog, nil if
|
||||
// none is available.
|
||||
logger *Logger
|
||||
|
||||
// loggerOptions contains the options that were supplied for
|
||||
// globalLogger.
|
||||
loggerOptions loggerOptions
|
||||
|
||||
// Boolean flags. Not handled atomically because the flag.Value interface
|
||||
// does not let us avoid the =true, and that shorthand is necessary for
|
||||
// compatibility. TODO: does this matter enough to fix? Seems unlikely.
|
||||
|
@ -437,26 +466,14 @@ type loggingT struct {
|
|||
// Level flag. Handled atomically.
|
||||
stderrThreshold severityValue // The -stderrthreshold flag.
|
||||
|
||||
// bufferCache maintains the free list. It uses its own mutex
|
||||
// so buffers can be grabbed and printed to without holding the main lock,
|
||||
// for better parallelization.
|
||||
bufferCache buffer.Buffers
|
||||
// Access to all of the following fields must be protected via a mutex.
|
||||
|
||||
// mu protects the remaining elements of this structure and is
|
||||
// used to synchronize logging.
|
||||
mu sync.Mutex
|
||||
// file holds writer for each of the log types.
|
||||
file [severity.NumSeverity]flushSyncWriter
|
||||
// flushD holds a flushDaemon that frequently flushes log file buffers.
|
||||
flushD *flushDaemon
|
||||
// flushInterval is the interval for periodic flushing. If zero,
|
||||
// the global default will be used.
|
||||
flushInterval time.Duration
|
||||
// pcs is used in V to avoid an allocation when computing the caller's PC.
|
||||
pcs [1]uintptr
|
||||
// vmap is a cache of the V Level for each V() call site, identified by PC.
|
||||
// It is wiped whenever the vmodule flag changes state.
|
||||
vmap map[uintptr]Level
|
||||
|
||||
// filterLength stores the length of the vmodule filter chain. If greater
|
||||
// than zero, it means vmodule is enabled. It may be read safely
|
||||
// using sync.LoadInt32, but is only modified under mu.
|
||||
|
@ -496,7 +513,48 @@ type loggingT struct {
|
|||
filter LogFilter
|
||||
}
|
||||
|
||||
var logging loggingT
|
||||
// deepCopy creates a copy that doesn't share anything with the original
|
||||
// instance.
|
||||
func (s settings) deepCopy() settings {
|
||||
// vmodule is a slice and would be shared, so we have copy it.
|
||||
filter := make([]modulePat, len(s.vmodule.filter))
|
||||
for i := range s.vmodule.filter {
|
||||
filter[i] = s.vmodule.filter[i]
|
||||
}
|
||||
s.vmodule.filter = filter
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// loggingT collects all the global state of the logging setup.
|
||||
type loggingT struct {
|
||||
settings
|
||||
|
||||
// bufferCache maintains the free list. It uses its own mutex
|
||||
// so buffers can be grabbed and printed to without holding the main lock,
|
||||
// for better parallelization.
|
||||
bufferCache buffer.Buffers
|
||||
|
||||
// flushD holds a flushDaemon that frequently flushes log file buffers.
|
||||
// Uses its own mutex.
|
||||
flushD *flushDaemon
|
||||
|
||||
// mu protects the remaining elements of this structure and the fields
|
||||
// in settingsT which need a mutex lock.
|
||||
mu sync.Mutex
|
||||
|
||||
// pcs is used in V to avoid an allocation when computing the caller's PC.
|
||||
pcs [1]uintptr
|
||||
// vmap is a cache of the V Level for each V() call site, identified by PC.
|
||||
// It is wiped whenever the vmodule flag changes state.
|
||||
vmap map[uintptr]Level
|
||||
}
|
||||
|
||||
var logging = loggingT{
|
||||
settings: settings{
|
||||
contextualLoggingEnabled: true,
|
||||
},
|
||||
}
|
||||
|
||||
// setVState sets a consistent state for V logging.
|
||||
// l.mu is held.
|
||||
|
@ -520,6 +578,55 @@ func (l *loggingT) setVState(verbosity Level, filter []modulePat, setFilter bool
|
|||
|
||||
var timeNow = time.Now // Stubbed out for testing.
|
||||
|
||||
// CaptureState gathers information about all current klog settings.
|
||||
// The result can be used to restore those settings.
|
||||
func CaptureState() State {
|
||||
logging.mu.Lock()
|
||||
defer logging.mu.Unlock()
|
||||
return &state{
|
||||
settings: logging.settings.deepCopy(),
|
||||
flushDRunning: logging.flushD.isRunning(),
|
||||
maxSize: MaxSize,
|
||||
}
|
||||
}
|
||||
|
||||
// State stores a snapshot of klog settings. It gets created with CaptureState
|
||||
// and can be used to restore the entire state. Modifying individual settings
|
||||
// is supported via the command line flags.
|
||||
type State interface {
|
||||
// Restore restore the entire state. It may get called more than once.
|
||||
Restore()
|
||||
}
|
||||
|
||||
type state struct {
|
||||
settings
|
||||
|
||||
flushDRunning bool
|
||||
maxSize uint64
|
||||
}
|
||||
|
||||
func (s *state) Restore() {
|
||||
// This needs to be done before mutex locking.
|
||||
if s.flushDRunning && !logging.flushD.isRunning() {
|
||||
// This is not quite accurate: StartFlushDaemon might
|
||||
// have been called with some different interval.
|
||||
interval := s.flushInterval
|
||||
if interval == 0 {
|
||||
interval = flushInterval
|
||||
}
|
||||
logging.flushD.run(interval)
|
||||
} else if !s.flushDRunning && logging.flushD.isRunning() {
|
||||
logging.flushD.stop()
|
||||
}
|
||||
|
||||
logging.mu.Lock()
|
||||
defer logging.mu.Unlock()
|
||||
|
||||
logging.settings = s.settings
|
||||
logging.setVState(s.verbosity, s.vmodule.filter, true)
|
||||
MaxSize = s.maxSize
|
||||
}
|
||||
|
||||
/*
|
||||
header formats a log header as defined by the C++ implementation.
|
||||
It returns a buffer containing the formatted header and the user's file and line number.
|
||||
|
@ -688,7 +795,7 @@ func (l *loggingT) printS(err error, s severity.Severity, depth int, msg string,
|
|||
serialize.KVListFormat(&b.Buffer, "err", err)
|
||||
}
|
||||
serialize.KVListFormat(&b.Buffer, keysAndValues...)
|
||||
l.printDepth(s, globalLogger, nil, depth+1, &b.Buffer)
|
||||
l.printDepth(s, logging.logger, nil, depth+1, &b.Buffer)
|
||||
// Make the buffer available for reuse.
|
||||
l.bufferCache.PutBuffer(b)
|
||||
}
|
||||
|
@ -757,7 +864,7 @@ func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buf
|
|||
|
||||
if l.traceLocation.isSet() {
|
||||
if l.traceLocation.match(file, line) {
|
||||
buf.Write(stacks(false))
|
||||
buf.Write(dbg.Stacks(false))
|
||||
}
|
||||
}
|
||||
data := buf.Bytes()
|
||||
|
@ -765,7 +872,7 @@ func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buf
|
|||
// TODO: set 'severity' and caller information as structured log info
|
||||
// keysAndValues := []interface{}{"severity", severityName[s], "file", file, "line", line}
|
||||
if s == severity.ErrorLog {
|
||||
globalLogger.WithCallDepth(depth+3).Error(nil, string(data))
|
||||
logging.logger.WithCallDepth(depth+3).Error(nil, string(data))
|
||||
} else {
|
||||
log.WithCallDepth(depth + 3).Info(string(data))
|
||||
}
|
||||
|
@ -822,12 +929,15 @@ func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buf
|
|||
OsExit(1)
|
||||
}
|
||||
// Dump all goroutine stacks before exiting.
|
||||
trace := stacks(true)
|
||||
// Write the stack trace for all goroutines to the stderr.
|
||||
if l.toStderr || l.alsoToStderr || s >= l.stderrThreshold.get() || alsoToStderr {
|
||||
os.Stderr.Write(trace)
|
||||
// First, make sure we see the trace for the current goroutine on standard error.
|
||||
// If -logtostderr has been specified, the loop below will do that anyway
|
||||
// as the first stack in the full dump.
|
||||
if !l.toStderr {
|
||||
os.Stderr.Write(dbg.Stacks(false))
|
||||
}
|
||||
|
||||
// Write the stack trace for all goroutines to the files.
|
||||
trace := dbg.Stacks(true)
|
||||
logExitFunc = func(error) {} // If we get a write error, we'll still exit below.
|
||||
for log := severity.FatalLog; log >= severity.InfoLog; log-- {
|
||||
if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set.
|
||||
|
@ -847,25 +957,6 @@ func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buf
|
|||
}
|
||||
}
|
||||
|
||||
// stacks is a wrapper for runtime.Stack that attempts to recover the data for all goroutines.
|
||||
func stacks(all bool) []byte {
|
||||
// We don't know how big the traces are, so grow a few times if they don't fit. Start large, though.
|
||||
n := 10000
|
||||
if all {
|
||||
n = 100000
|
||||
}
|
||||
var trace []byte
|
||||
for i := 0; i < 5; i++ {
|
||||
trace = make([]byte, n)
|
||||
nbytes := runtime.Stack(trace, all)
|
||||
if nbytes < len(trace) {
|
||||
return trace[:nbytes]
|
||||
}
|
||||
n *= 2
|
||||
}
|
||||
return trace
|
||||
}
|
||||
|
||||
// logExitFunc provides a simple mechanism to override the default behavior
|
||||
// of exiting on error. Used in testing and to guarantee we reach a required exit
|
||||
// for fatal logs. Instead, exit could be a function rather than a method but that
|
||||
|
@ -1077,9 +1168,9 @@ func (f *flushDaemon) isRunning() bool {
|
|||
return f.stopC != nil
|
||||
}
|
||||
|
||||
// StopFlushDaemon stops the flush daemon, if running.
|
||||
// StopFlushDaemon stops the flush daemon, if running, and flushes once.
|
||||
// This prevents klog from leaking goroutines on shutdown. After stopping
|
||||
// the daemon, you can still manually flush buffers by calling Flush().
|
||||
// the daemon, you can still manually flush buffers again by calling Flush().
|
||||
func StopFlushDaemon() {
|
||||
logging.flushD.stop()
|
||||
}
|
||||
|
@ -1109,8 +1200,8 @@ func (l *loggingT) flushAll() {
|
|||
file.Sync() // ignore error
|
||||
}
|
||||
}
|
||||
if globalLoggerOptions.flush != nil {
|
||||
globalLoggerOptions.flush()
|
||||
if logging.loggerOptions.flush != nil {
|
||||
logging.loggerOptions.flush()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1158,7 +1249,7 @@ func (lb logBridge) Write(b []byte) (n int, err error) {
|
|||
}
|
||||
// printWithFileLine with alsoToStderr=true, so standard log messages
|
||||
// always appear on standard error.
|
||||
logging.printWithFileLine(severity.Severity(lb), globalLogger, logging.filter, file, line, true, text)
|
||||
logging.printWithFileLine(severity.Severity(lb), logging.logger, logging.filter, file, line, true, text)
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
|
@ -1196,10 +1287,10 @@ type Verbose struct {
|
|||
}
|
||||
|
||||
func newVerbose(level Level, b bool) Verbose {
|
||||
if globalLogger == nil {
|
||||
if logging.logger == nil {
|
||||
return Verbose{b, nil}
|
||||
}
|
||||
v := globalLogger.V(int(level))
|
||||
v := logging.logger.V(int(level))
|
||||
return Verbose{b, &v}
|
||||
}
|
||||
|
||||
|
@ -1318,7 +1409,7 @@ func (v Verbose) InfoS(msg string, keysAndValues ...interface{}) {
|
|||
// InfoSDepth acts as InfoS but uses depth to determine which call frame to log.
|
||||
// InfoSDepth(0, "msg") is the same as InfoS("msg").
|
||||
func InfoSDepth(depth int, msg string, keysAndValues ...interface{}) {
|
||||
logging.infoS(globalLogger, logging.filter, depth, msg, keysAndValues...)
|
||||
logging.infoS(logging.logger, logging.filter, depth, msg, keysAndValues...)
|
||||
}
|
||||
|
||||
// InfoSDepth is equivalent to the global InfoSDepth function, guarded by the value of v.
|
||||
|
@ -1347,37 +1438,37 @@ func (v Verbose) ErrorS(err error, msg string, keysAndValues ...interface{}) {
|
|||
// Info logs to the INFO log.
|
||||
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
|
||||
func Info(args ...interface{}) {
|
||||
logging.print(severity.InfoLog, globalLogger, logging.filter, args...)
|
||||
logging.print(severity.InfoLog, logging.logger, logging.filter, args...)
|
||||
}
|
||||
|
||||
// InfoDepth acts as Info but uses depth to determine which call frame to log.
|
||||
// InfoDepth(0, "msg") is the same as Info("msg").
|
||||
func InfoDepth(depth int, args ...interface{}) {
|
||||
logging.printDepth(severity.InfoLog, globalLogger, logging.filter, depth, args...)
|
||||
logging.printDepth(severity.InfoLog, logging.logger, logging.filter, depth, args...)
|
||||
}
|
||||
|
||||
// Infoln logs to the INFO log.
|
||||
// Arguments are handled in the manner of fmt.Println; a newline is always appended.
|
||||
func Infoln(args ...interface{}) {
|
||||
logging.println(severity.InfoLog, globalLogger, logging.filter, args...)
|
||||
logging.println(severity.InfoLog, logging.logger, logging.filter, args...)
|
||||
}
|
||||
|
||||
// InfolnDepth acts as Infoln but uses depth to determine which call frame to log.
|
||||
// InfolnDepth(0, "msg") is the same as Infoln("msg").
|
||||
func InfolnDepth(depth int, args ...interface{}) {
|
||||
logging.printlnDepth(severity.InfoLog, globalLogger, logging.filter, depth, args...)
|
||||
logging.printlnDepth(severity.InfoLog, logging.logger, logging.filter, depth, args...)
|
||||
}
|
||||
|
||||
// Infof logs to the INFO log.
|
||||
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
|
||||
func Infof(format string, args ...interface{}) {
|
||||
logging.printf(severity.InfoLog, globalLogger, logging.filter, format, args...)
|
||||
logging.printf(severity.InfoLog, logging.logger, logging.filter, format, args...)
|
||||
}
|
||||
|
||||
// InfofDepth acts as Infof but uses depth to determine which call frame to log.
|
||||
// InfofDepth(0, "msg", args...) is the same as Infof("msg", args...).
|
||||
func InfofDepth(depth int, format string, args ...interface{}) {
|
||||
logging.printfDepth(severity.InfoLog, globalLogger, logging.filter, depth, format, args...)
|
||||
logging.printfDepth(severity.InfoLog, logging.logger, logging.filter, depth, format, args...)
|
||||
}
|
||||
|
||||
// InfoS structured logs to the INFO log.
|
||||
|
@ -1389,79 +1480,79 @@ func InfofDepth(depth int, format string, args ...interface{}) {
|
|||
// output:
|
||||
// >> I1025 00:15:15.525108 1 controller_utils.go:116] "Pod status updated" pod="kubedns" status="ready"
|
||||
func InfoS(msg string, keysAndValues ...interface{}) {
|
||||
logging.infoS(globalLogger, logging.filter, 0, msg, keysAndValues...)
|
||||
logging.infoS(logging.logger, logging.filter, 0, msg, keysAndValues...)
|
||||
}
|
||||
|
||||
// Warning logs to the WARNING and INFO logs.
|
||||
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
|
||||
func Warning(args ...interface{}) {
|
||||
logging.print(severity.WarningLog, globalLogger, logging.filter, args...)
|
||||
logging.print(severity.WarningLog, logging.logger, logging.filter, args...)
|
||||
}
|
||||
|
||||
// WarningDepth acts as Warning but uses depth to determine which call frame to log.
|
||||
// WarningDepth(0, "msg") is the same as Warning("msg").
|
||||
func WarningDepth(depth int, args ...interface{}) {
|
||||
logging.printDepth(severity.WarningLog, globalLogger, logging.filter, depth, args...)
|
||||
logging.printDepth(severity.WarningLog, logging.logger, logging.filter, depth, args...)
|
||||
}
|
||||
|
||||
// Warningln logs to the WARNING and INFO logs.
|
||||
// Arguments are handled in the manner of fmt.Println; a newline is always appended.
|
||||
func Warningln(args ...interface{}) {
|
||||
logging.println(severity.WarningLog, globalLogger, logging.filter, args...)
|
||||
logging.println(severity.WarningLog, logging.logger, logging.filter, args...)
|
||||
}
|
||||
|
||||
// WarninglnDepth acts as Warningln but uses depth to determine which call frame to log.
|
||||
// WarninglnDepth(0, "msg") is the same as Warningln("msg").
|
||||
func WarninglnDepth(depth int, args ...interface{}) {
|
||||
logging.printlnDepth(severity.WarningLog, globalLogger, logging.filter, depth, args...)
|
||||
logging.printlnDepth(severity.WarningLog, logging.logger, logging.filter, depth, args...)
|
||||
}
|
||||
|
||||
// Warningf logs to the WARNING and INFO logs.
|
||||
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
|
||||
func Warningf(format string, args ...interface{}) {
|
||||
logging.printf(severity.WarningLog, globalLogger, logging.filter, format, args...)
|
||||
logging.printf(severity.WarningLog, logging.logger, logging.filter, format, args...)
|
||||
}
|
||||
|
||||
// WarningfDepth acts as Warningf but uses depth to determine which call frame to log.
|
||||
// WarningfDepth(0, "msg", args...) is the same as Warningf("msg", args...).
|
||||
func WarningfDepth(depth int, format string, args ...interface{}) {
|
||||
logging.printfDepth(severity.WarningLog, globalLogger, logging.filter, depth, format, args...)
|
||||
logging.printfDepth(severity.WarningLog, logging.logger, logging.filter, depth, format, args...)
|
||||
}
|
||||
|
||||
// Error logs to the ERROR, WARNING, and INFO logs.
|
||||
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
|
||||
func Error(args ...interface{}) {
|
||||
logging.print(severity.ErrorLog, globalLogger, logging.filter, args...)
|
||||
logging.print(severity.ErrorLog, logging.logger, logging.filter, args...)
|
||||
}
|
||||
|
||||
// ErrorDepth acts as Error but uses depth to determine which call frame to log.
|
||||
// ErrorDepth(0, "msg") is the same as Error("msg").
|
||||
func ErrorDepth(depth int, args ...interface{}) {
|
||||
logging.printDepth(severity.ErrorLog, globalLogger, logging.filter, depth, args...)
|
||||
logging.printDepth(severity.ErrorLog, logging.logger, logging.filter, depth, args...)
|
||||
}
|
||||
|
||||
// Errorln logs to the ERROR, WARNING, and INFO logs.
|
||||
// Arguments are handled in the manner of fmt.Println; a newline is always appended.
|
||||
func Errorln(args ...interface{}) {
|
||||
logging.println(severity.ErrorLog, globalLogger, logging.filter, args...)
|
||||
logging.println(severity.ErrorLog, logging.logger, logging.filter, args...)
|
||||
}
|
||||
|
||||
// ErrorlnDepth acts as Errorln but uses depth to determine which call frame to log.
|
||||
// ErrorlnDepth(0, "msg") is the same as Errorln("msg").
|
||||
func ErrorlnDepth(depth int, args ...interface{}) {
|
||||
logging.printlnDepth(severity.ErrorLog, globalLogger, logging.filter, depth, args...)
|
||||
logging.printlnDepth(severity.ErrorLog, logging.logger, logging.filter, depth, args...)
|
||||
}
|
||||
|
||||
// Errorf logs to the ERROR, WARNING, and INFO logs.
|
||||
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
|
||||
func Errorf(format string, args ...interface{}) {
|
||||
logging.printf(severity.ErrorLog, globalLogger, logging.filter, format, args...)
|
||||
logging.printf(severity.ErrorLog, logging.logger, logging.filter, format, args...)
|
||||
}
|
||||
|
||||
// ErrorfDepth acts as Errorf but uses depth to determine which call frame to log.
|
||||
// ErrorfDepth(0, "msg", args...) is the same as Errorf("msg", args...).
|
||||
func ErrorfDepth(depth int, format string, args ...interface{}) {
|
||||
logging.printfDepth(severity.ErrorLog, globalLogger, logging.filter, depth, format, args...)
|
||||
logging.printfDepth(severity.ErrorLog, logging.logger, logging.filter, depth, format, args...)
|
||||
}
|
||||
|
||||
// ErrorS structured logs to the ERROR, WARNING, and INFO logs.
|
||||
|
@ -1474,52 +1565,63 @@ func ErrorfDepth(depth int, format string, args ...interface{}) {
|
|||
// output:
|
||||
// >> E1025 00:15:15.525108 1 controller_utils.go:114] "Failed to update pod status" err="timeout"
|
||||
func ErrorS(err error, msg string, keysAndValues ...interface{}) {
|
||||
logging.errorS(err, globalLogger, logging.filter, 0, msg, keysAndValues...)
|
||||
logging.errorS(err, logging.logger, logging.filter, 0, msg, keysAndValues...)
|
||||
}
|
||||
|
||||
// ErrorSDepth acts as ErrorS but uses depth to determine which call frame to log.
|
||||
// ErrorSDepth(0, "msg") is the same as ErrorS("msg").
|
||||
func ErrorSDepth(depth int, err error, msg string, keysAndValues ...interface{}) {
|
||||
logging.errorS(err, globalLogger, logging.filter, depth, msg, keysAndValues...)
|
||||
logging.errorS(err, logging.logger, logging.filter, depth, msg, keysAndValues...)
|
||||
}
|
||||
|
||||
// Fatal logs to the FATAL, ERROR, WARNING, and INFO logs,
|
||||
// including a stack trace of all running goroutines, then calls OsExit(255).
|
||||
// prints stack trace(s), then calls OsExit(255).
|
||||
//
|
||||
// Stderr only receives a dump of the current goroutine's stack trace. Log files,
|
||||
// if there are any, receive a dump of the stack traces in all goroutines.
|
||||
//
|
||||
// Callers who want more control over handling of fatal events may instead use a
|
||||
// combination of different functions:
|
||||
// - some info or error logging function, optionally with a stack trace
|
||||
// value generated by github.com/go-logr/lib/dbg.Backtrace
|
||||
// - Flush to flush pending log data
|
||||
// - panic, os.Exit or returning to the caller with an error
|
||||
//
|
||||
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
|
||||
func Fatal(args ...interface{}) {
|
||||
logging.print(severity.FatalLog, globalLogger, logging.filter, args...)
|
||||
logging.print(severity.FatalLog, logging.logger, logging.filter, args...)
|
||||
}
|
||||
|
||||
// FatalDepth acts as Fatal but uses depth to determine which call frame to log.
|
||||
// FatalDepth(0, "msg") is the same as Fatal("msg").
|
||||
func FatalDepth(depth int, args ...interface{}) {
|
||||
logging.printDepth(severity.FatalLog, globalLogger, logging.filter, depth, args...)
|
||||
logging.printDepth(severity.FatalLog, logging.logger, logging.filter, depth, args...)
|
||||
}
|
||||
|
||||
// Fatalln logs to the FATAL, ERROR, WARNING, and INFO logs,
|
||||
// including a stack trace of all running goroutines, then calls OsExit(255).
|
||||
// Arguments are handled in the manner of fmt.Println; a newline is always appended.
|
||||
func Fatalln(args ...interface{}) {
|
||||
logging.println(severity.FatalLog, globalLogger, logging.filter, args...)
|
||||
logging.println(severity.FatalLog, logging.logger, logging.filter, args...)
|
||||
}
|
||||
|
||||
// FatallnDepth acts as Fatalln but uses depth to determine which call frame to log.
|
||||
// FatallnDepth(0, "msg") is the same as Fatalln("msg").
|
||||
func FatallnDepth(depth int, args ...interface{}) {
|
||||
logging.printlnDepth(severity.FatalLog, globalLogger, logging.filter, depth, args...)
|
||||
logging.printlnDepth(severity.FatalLog, logging.logger, logging.filter, depth, args...)
|
||||
}
|
||||
|
||||
// Fatalf logs to the FATAL, ERROR, WARNING, and INFO logs,
|
||||
// including a stack trace of all running goroutines, then calls OsExit(255).
|
||||
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
|
||||
func Fatalf(format string, args ...interface{}) {
|
||||
logging.printf(severity.FatalLog, globalLogger, logging.filter, format, args...)
|
||||
logging.printf(severity.FatalLog, logging.logger, logging.filter, format, args...)
|
||||
}
|
||||
|
||||
// FatalfDepth acts as Fatalf but uses depth to determine which call frame to log.
|
||||
// FatalfDepth(0, "msg", args...) is the same as Fatalf("msg", args...).
|
||||
func FatalfDepth(depth int, format string, args ...interface{}) {
|
||||
logging.printfDepth(severity.FatalLog, globalLogger, logging.filter, depth, format, args...)
|
||||
logging.printfDepth(severity.FatalLog, logging.logger, logging.filter, depth, format, args...)
|
||||
}
|
||||
|
||||
// fatalNoStacks is non-zero if we are to exit without dumping goroutine stacks.
|
||||
|
@ -1530,41 +1632,41 @@ var fatalNoStacks uint32
|
|||
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
|
||||
func Exit(args ...interface{}) {
|
||||
atomic.StoreUint32(&fatalNoStacks, 1)
|
||||
logging.print(severity.FatalLog, globalLogger, logging.filter, args...)
|
||||
logging.print(severity.FatalLog, logging.logger, logging.filter, args...)
|
||||
}
|
||||
|
||||
// ExitDepth acts as Exit but uses depth to determine which call frame to log.
|
||||
// ExitDepth(0, "msg") is the same as Exit("msg").
|
||||
func ExitDepth(depth int, args ...interface{}) {
|
||||
atomic.StoreUint32(&fatalNoStacks, 1)
|
||||
logging.printDepth(severity.FatalLog, globalLogger, logging.filter, depth, args...)
|
||||
logging.printDepth(severity.FatalLog, logging.logger, logging.filter, depth, args...)
|
||||
}
|
||||
|
||||
// Exitln logs to the FATAL, ERROR, WARNING, and INFO logs, then calls OsExit(1).
|
||||
func Exitln(args ...interface{}) {
|
||||
atomic.StoreUint32(&fatalNoStacks, 1)
|
||||
logging.println(severity.FatalLog, globalLogger, logging.filter, args...)
|
||||
logging.println(severity.FatalLog, logging.logger, logging.filter, args...)
|
||||
}
|
||||
|
||||
// ExitlnDepth acts as Exitln but uses depth to determine which call frame to log.
|
||||
// ExitlnDepth(0, "msg") is the same as Exitln("msg").
|
||||
func ExitlnDepth(depth int, args ...interface{}) {
|
||||
atomic.StoreUint32(&fatalNoStacks, 1)
|
||||
logging.printlnDepth(severity.FatalLog, globalLogger, logging.filter, depth, args...)
|
||||
logging.printlnDepth(severity.FatalLog, logging.logger, logging.filter, depth, args...)
|
||||
}
|
||||
|
||||
// Exitf logs to the FATAL, ERROR, WARNING, and INFO logs, then calls OsExit(1).
|
||||
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
|
||||
func Exitf(format string, args ...interface{}) {
|
||||
atomic.StoreUint32(&fatalNoStacks, 1)
|
||||
logging.printf(severity.FatalLog, globalLogger, logging.filter, format, args...)
|
||||
logging.printf(severity.FatalLog, logging.logger, logging.filter, format, args...)
|
||||
}
|
||||
|
||||
// ExitfDepth acts as Exitf but uses depth to determine which call frame to log.
|
||||
// ExitfDepth(0, "msg", args...) is the same as Exitf("msg", args...).
|
||||
func ExitfDepth(depth int, format string, args ...interface{}) {
|
||||
atomic.StoreUint32(&fatalNoStacks, 1)
|
||||
logging.printfDepth(severity.FatalLog, globalLogger, logging.filter, depth, format, args...)
|
||||
logging.printfDepth(severity.FatalLog, logging.logger, logging.filter, depth, format, args...)
|
||||
}
|
||||
|
||||
// LogFilter is a collection of functions that can filter all logging calls,
|
||||
|
|
|
@ -25,11 +25,6 @@ import (
|
|||
// NewKlogr returns a logger that is functionally identical to
|
||||
// klogr.NewWithOptions(klogr.FormatKlog), i.e. it passes through to klog. The
|
||||
// difference is that it uses a simpler implementation.
|
||||
//
|
||||
// Experimental
|
||||
//
|
||||
// Notice: This function is EXPERIMENTAL and may be changed or removed in a
|
||||
// later release.
|
||||
func NewKlogr() Logger {
|
||||
return New(&klogger{})
|
||||
}
|
||||
|
@ -48,11 +43,11 @@ func (l *klogger) Init(info logr.RuntimeInfo) {
|
|||
}
|
||||
|
||||
func (l klogger) Info(level int, msg string, kvList ...interface{}) {
|
||||
trimmed := serialize.TrimDuplicates(l.values, kvList)
|
||||
merged := serialize.MergeKVs(l.values, kvList)
|
||||
if l.prefix != "" {
|
||||
msg = l.prefix + ": " + msg
|
||||
}
|
||||
V(Level(level)).InfoSDepth(l.callDepth+1, msg, append(trimmed[0], trimmed[1]...)...)
|
||||
V(Level(level)).InfoSDepth(l.callDepth+1, msg, merged...)
|
||||
}
|
||||
|
||||
func (l klogger) Enabled(level int) bool {
|
||||
|
@ -60,11 +55,11 @@ func (l klogger) Enabled(level int) bool {
|
|||
}
|
||||
|
||||
func (l klogger) Error(err error, msg string, kvList ...interface{}) {
|
||||
trimmed := serialize.TrimDuplicates(l.values, kvList)
|
||||
merged := serialize.MergeKVs(l.values, kvList)
|
||||
if l.prefix != "" {
|
||||
msg = l.prefix + ": " + msg
|
||||
}
|
||||
ErrorSDepth(l.callDepth+1, err, msg, append(trimmed[0], trimmed[1]...)...)
|
||||
ErrorSDepth(l.callDepth+1, err, msg, merged...)
|
||||
}
|
||||
|
||||
// WithName returns a new logr.Logger with the specified name appended. klogr
|
||||
|
|
|
@ -314,7 +314,7 @@ gopkg.in/inf.v0
|
|||
gopkg.in/yaml.v2
|
||||
# gopkg.in/yaml.v3 v3.0.1
|
||||
gopkg.in/yaml.v3
|
||||
# k8s.io/api v0.23.8
|
||||
# k8s.io/api v0.23.9
|
||||
## explicit
|
||||
k8s.io/api/admissionregistration/v1
|
||||
k8s.io/api/admissionregistration/v1beta1
|
||||
|
@ -361,7 +361,7 @@ k8s.io/api/scheduling/v1beta1
|
|||
k8s.io/api/storage/v1
|
||||
k8s.io/api/storage/v1alpha1
|
||||
k8s.io/api/storage/v1beta1
|
||||
# k8s.io/apimachinery v0.23.8
|
||||
# k8s.io/apimachinery v0.23.9
|
||||
## explicit
|
||||
k8s.io/apimachinery/pkg/api/equality
|
||||
k8s.io/apimachinery/pkg/api/errors
|
||||
|
@ -410,7 +410,7 @@ k8s.io/apimachinery/pkg/version
|
|||
k8s.io/apimachinery/pkg/watch
|
||||
k8s.io/apimachinery/third_party/forked/golang/json
|
||||
k8s.io/apimachinery/third_party/forked/golang/reflect
|
||||
# k8s.io/client-go v0.23.8
|
||||
# k8s.io/client-go v0.23.9
|
||||
## explicit
|
||||
k8s.io/client-go/applyconfigurations/admissionregistration/v1
|
||||
k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1
|
||||
|
@ -536,7 +536,7 @@ k8s.io/client-go/util/homedir
|
|||
k8s.io/client-go/util/keyutil
|
||||
k8s.io/client-go/util/retry
|
||||
k8s.io/client-go/util/workqueue
|
||||
# k8s.io/code-generator v0.23.8
|
||||
# k8s.io/code-generator v0.23.9
|
||||
## explicit
|
||||
k8s.io/code-generator
|
||||
k8s.io/code-generator/cmd/client-gen
|
||||
|
@ -571,7 +571,7 @@ k8s.io/code-generator/cmd/set-gen
|
|||
k8s.io/code-generator/pkg/namer
|
||||
k8s.io/code-generator/pkg/util
|
||||
k8s.io/code-generator/third_party/forked/golang/reflect
|
||||
# k8s.io/gengo v0.0.0-20220307231824-4627b89bbf1b
|
||||
# k8s.io/gengo v0.0.0-20220613173612-397b4ae3bce7
|
||||
k8s.io/gengo/args
|
||||
k8s.io/gengo/examples/deepcopy-gen/generators
|
||||
k8s.io/gengo/examples/defaulter-gen/generators
|
||||
|
@ -582,9 +582,11 @@ k8s.io/gengo/generator
|
|||
k8s.io/gengo/namer
|
||||
k8s.io/gengo/parser
|
||||
k8s.io/gengo/types
|
||||
# k8s.io/klog/v2 v2.60.1-0.20220317184644-43cc75f9ae89
|
||||
# k8s.io/klog/v2 v2.70.2-0.20220707122935-0990e81f1a8f
|
||||
k8s.io/klog/v2
|
||||
k8s.io/klog/v2/internal/buffer
|
||||
k8s.io/klog/v2/internal/clock
|
||||
k8s.io/klog/v2/internal/dbg
|
||||
k8s.io/klog/v2/internal/serialize
|
||||
k8s.io/klog/v2/internal/severity
|
||||
# k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65
|
||||
|
@ -606,10 +608,10 @@ k8s.io/utils/integer
|
|||
k8s.io/utils/internal/third_party/forked/golang/net
|
||||
k8s.io/utils/net
|
||||
k8s.io/utils/trace
|
||||
# knative.dev/hack v0.0.0-20220725145124-782bbaabb8a1
|
||||
# knative.dev/hack v0.0.0-20220728013938-9dabf7cf62e3
|
||||
## explicit
|
||||
knative.dev/hack
|
||||
# knative.dev/pkg v0.0.0-20220722175921-6c9c1c6098d5
|
||||
# knative.dev/pkg v0.0.0-20220802185824-a01dfedb0486
|
||||
## explicit
|
||||
knative.dev/pkg/apis
|
||||
knative.dev/pkg/apis/duck
|
||||
|
|
Loading…
Reference in New Issue