mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
rebase: update kubernetes to v1.25.0
update kubernetes to latest v1.25.0 release. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
committed by
mergify[bot]
parent
f47839d73d
commit
e3bf375035
132
vendor/k8s.io/component-base/config/types.go
generated
vendored
132
vendor/k8s.io/component-base/config/types.go
generated
vendored
@ -17,14 +17,6 @@ limitations under the License.
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
@ -86,127 +78,3 @@ type DebuggingConfiguration struct {
|
||||
// enableProfiling is true.
|
||||
EnableContentionProfiling bool
|
||||
}
|
||||
|
||||
// LoggingConfiguration contains logging options
|
||||
// Refer [Logs Options](https://github.com/kubernetes/component-base/blob/master/logs/options.go) for more information.
|
||||
type LoggingConfiguration struct {
|
||||
// Format Flag specifies the structure of log messages.
|
||||
// default value of format is `text`
|
||||
Format string
|
||||
// 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
|
||||
// messages. Higher values enable additional messages. Error messages
|
||||
// are always logged.
|
||||
Verbosity VerbosityLevel
|
||||
// VModule overrides the verbosity threshold for individual files.
|
||||
// Only supported for "text" log format.
|
||||
VModule VModuleConfiguration
|
||||
// [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.
|
||||
Options FormatOptions
|
||||
}
|
||||
|
||||
// FormatOptions contains options for the different logging formats.
|
||||
type FormatOptions struct {
|
||||
// [Experimental] JSON contains options for logging format "json".
|
||||
JSON JSONOptions
|
||||
}
|
||||
|
||||
// JSONOptions contains options for logging format "json".
|
||||
type JSONOptions struct {
|
||||
// [Experimental] SplitStream redirects error messages to stderr while
|
||||
// info messages go to stdout, with buffering. The default is to write
|
||||
// both to stdout, without buffering.
|
||||
SplitStream bool
|
||||
// [Experimental] InfoBufferSize sets the size of the info stream when
|
||||
// using split streams. The default is zero, which disables buffering.
|
||||
InfoBufferSize resource.QuantityValue
|
||||
}
|
||||
|
||||
// VModuleConfiguration is a collection of individual file names or patterns
|
||||
// and the corresponding verbosity threshold.
|
||||
type VModuleConfiguration []VModuleItem
|
||||
|
||||
var _ pflag.Value = &VModuleConfiguration{}
|
||||
|
||||
// VModuleItem defines verbosity for one or more files which match a certain
|
||||
// glob pattern.
|
||||
type VModuleItem struct {
|
||||
// FilePattern is a base file name (i.e. minus the ".go" suffix and
|
||||
// directory) or a "glob" pattern for such a name. It must not contain
|
||||
// comma and equal signs because those are separators for the
|
||||
// corresponding klog command line argument.
|
||||
FilePattern string
|
||||
// Verbosity is the threshold for log messages emitted inside files
|
||||
// that match the pattern.
|
||||
Verbosity VerbosityLevel
|
||||
}
|
||||
|
||||
// String returns the -vmodule parameter (comma-separated list of pattern=N).
|
||||
func (vmodule *VModuleConfiguration) String() string {
|
||||
var patterns []string
|
||||
for _, item := range *vmodule {
|
||||
patterns = append(patterns, fmt.Sprintf("%s=%d", item.FilePattern, item.Verbosity))
|
||||
}
|
||||
return strings.Join(patterns, ",")
|
||||
}
|
||||
|
||||
// Set parses the -vmodule parameter (comma-separated list of pattern=N).
|
||||
func (vmodule *VModuleConfiguration) Set(value string) error {
|
||||
// This code mirrors https://github.com/kubernetes/klog/blob/9ad246211af1ed84621ee94a26fcce0038b69cd1/klog.go#L287-L313
|
||||
|
||||
for _, pat := range strings.Split(value, ",") {
|
||||
if len(pat) == 0 {
|
||||
// Empty strings such as from a trailing comma can be ignored.
|
||||
continue
|
||||
}
|
||||
patLev := strings.Split(pat, "=")
|
||||
if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
|
||||
return fmt.Errorf("%q does not have the pattern=N format", pat)
|
||||
}
|
||||
pattern := patLev[0]
|
||||
// 31 instead of 32 to ensure that it also fits into int32.
|
||||
v, err := strconv.ParseUint(patLev[1], 10, 31)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing verbosity in %q: %v", pat, err)
|
||||
}
|
||||
*vmodule = append(*vmodule, VModuleItem{FilePattern: pattern, Verbosity: VerbosityLevel(v)})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vmodule *VModuleConfiguration) Type() string {
|
||||
return "pattern=N,..."
|
||||
}
|
||||
|
||||
// VerbosityLevel represents a klog or logr verbosity threshold.
|
||||
type VerbosityLevel uint32
|
||||
|
||||
var _ pflag.Value = new(VerbosityLevel)
|
||||
|
||||
func (l *VerbosityLevel) String() string {
|
||||
return strconv.FormatInt(int64(*l), 10)
|
||||
}
|
||||
|
||||
func (l *VerbosityLevel) Get() interface{} {
|
||||
return *l
|
||||
}
|
||||
|
||||
func (l *VerbosityLevel) Set(value string) error {
|
||||
// Limited to int32 for compatibility with klog.
|
||||
v, err := strconv.ParseUint(value, 10, 31)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*l = VerbosityLevel(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *VerbosityLevel) Type() string {
|
||||
return "Level"
|
||||
}
|
||||
|
8
vendor/k8s.io/component-base/config/v1alpha1/conversion.go
generated
vendored
8
vendor/k8s.io/component-base/config/v1alpha1/conversion.go
generated
vendored
@ -51,11 +51,3 @@ func Convert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfig
|
||||
func Convert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(in *config.LeaderElectionConfiguration, out *LeaderElectionConfiguration, s conversion.Scope) error {
|
||||
return autoConvert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(in, out, s)
|
||||
}
|
||||
|
||||
func Convert_v1alpha1_LoggingConfiguration_To_config_LoggingConfiguration(in *LoggingConfiguration, out *config.LoggingConfiguration, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_LoggingConfiguration_To_config_LoggingConfiguration(in, out, s)
|
||||
}
|
||||
|
||||
func Convert_config_LoggingConfiguration_To_v1alpha1_LoggingConfiguration(in *config.LoggingConfiguration, out *LoggingConfiguration, s conversion.Scope) error {
|
||||
return autoConvert_config_LoggingConfiguration_To_v1alpha1_LoggingConfiguration(in, out, s)
|
||||
}
|
||||
|
30
vendor/k8s.io/component-base/config/v1alpha1/defaults.go
generated
vendored
30
vendor/k8s.io/component-base/config/v1alpha1/defaults.go
generated
vendored
@ -19,7 +19,6 @@ package v1alpha1
|
||||
import (
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
)
|
||||
@ -97,32 +96,3 @@ func NewRecommendedDebuggingConfiguration() *DebuggingConfiguration {
|
||||
RecommendedDebuggingConfiguration(ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
// RecommendedLoggingConfiguration defaults logging configuration.
|
||||
// This will set the recommended default
|
||||
// values, but they may be subject to change between API versions. This function
|
||||
// is intentionally not registered in the scheme as a "normal" `SetDefaults_Foo`
|
||||
// function to allow consumers of this type to set whatever defaults for their
|
||||
// embedded configs. Forcing consumers to use these defaults would be problematic
|
||||
// as defaulting in the scheme is done as part of the conversion, and there would
|
||||
// be no easy way to opt-out. Instead, if you want to use this defaulting method
|
||||
// run it in your wrapper struct of this type in its `SetDefaults_` method.
|
||||
func RecommendedLoggingConfiguration(obj *LoggingConfiguration) {
|
||||
if obj.Format == "" {
|
||||
obj.Format = "text"
|
||||
}
|
||||
var empty resource.QuantityValue
|
||||
if obj.Options.JSON.InfoBufferSize == empty {
|
||||
obj.Options.JSON.InfoBufferSize = resource.QuantityValue{
|
||||
// This is similar, but not quite the same as a default
|
||||
// constructed instance.
|
||||
Quantity: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
}
|
||||
// This sets the unexported Quantity.s which will be compared
|
||||
// by reflect.DeepEqual in some tests.
|
||||
_ = obj.Options.JSON.InfoBufferSize.String()
|
||||
}
|
||||
if obj.FlushFrequency == 0 {
|
||||
obj.FlushFrequency = 5 * time.Second
|
||||
}
|
||||
}
|
||||
|
61
vendor/k8s.io/component-base/config/v1alpha1/types.go
generated
vendored
61
vendor/k8s.io/component-base/config/v1alpha1/types.go
generated
vendored
@ -17,9 +17,6 @@ limitations under the License.
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
@ -83,61 +80,3 @@ type ClientConnectionConfiguration struct {
|
||||
// burst allows extra queries to accumulate when a client is exceeding its rate.
|
||||
Burst int32 `json:"burst"`
|
||||
}
|
||||
|
||||
// LoggingConfiguration contains logging options
|
||||
// Refer [Logs Options](https://github.com/kubernetes/component-base/blob/master/logs/options.go) for more information.
|
||||
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 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
|
||||
// messages. Higher values enable additional messages. Error messages
|
||||
// are always logged.
|
||||
Verbosity uint32 `json:"verbosity"`
|
||||
// VModule overrides the verbosity threshold for individual files.
|
||||
// Only supported for "text" log format.
|
||||
VModule VModuleConfiguration `json:"vmodule,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.
|
||||
Options FormatOptions `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
// FormatOptions contains options for the different logging formats.
|
||||
type FormatOptions struct {
|
||||
// [Experimental] JSON contains options for logging format "json".
|
||||
JSON JSONOptions `json:"json,omitempty"`
|
||||
}
|
||||
|
||||
// JSONOptions contains options for logging format "json".
|
||||
type JSONOptions struct {
|
||||
// [Experimental] SplitStream redirects error messages to stderr while
|
||||
// info messages go to stdout, with buffering. The default is to write
|
||||
// both to stdout, without buffering.
|
||||
SplitStream bool `json:"splitStream,omitempty"`
|
||||
// [Experimental] InfoBufferSize sets the size of the info stream when
|
||||
// using split streams. The default is zero, which disables buffering.
|
||||
InfoBufferSize resource.QuantityValue `json:"infoBufferSize,omitempty"`
|
||||
}
|
||||
|
||||
// VModuleConfiguration is a collection of individual file names or patterns
|
||||
// and the corresponding verbosity threshold.
|
||||
type VModuleConfiguration []VModuleItem
|
||||
|
||||
// VModuleItem defines verbosity for one or more files which match a certain
|
||||
// glob pattern.
|
||||
type VModuleItem struct {
|
||||
// FilePattern is a base file name (i.e. minus the ".go" suffix and
|
||||
// directory) or a "glob" pattern for such a name. It must not contain
|
||||
// comma and equal signs because those are separators for the
|
||||
// corresponding klog command line argument.
|
||||
FilePattern string `json:"filePattern"`
|
||||
// Verbosity is the threshold for log messages emitted inside files
|
||||
// that match the pattern.
|
||||
Verbosity uint32 `json:"verbosity"`
|
||||
}
|
||||
|
133
vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go
generated
vendored
133
vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go
generated
vendored
@ -22,9 +22,6 @@ limitations under the License.
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
unsafe "unsafe"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
@ -38,36 +35,6 @@ func init() {
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(s *runtime.Scheme) error {
|
||||
if err := s.AddGeneratedConversionFunc((*FormatOptions)(nil), (*config.FormatOptions)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_FormatOptions_To_config_FormatOptions(a.(*FormatOptions), b.(*config.FormatOptions), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*config.FormatOptions)(nil), (*FormatOptions)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_config_FormatOptions_To_v1alpha1_FormatOptions(a.(*config.FormatOptions), b.(*FormatOptions), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*JSONOptions)(nil), (*config.JSONOptions)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_JSONOptions_To_config_JSONOptions(a.(*JSONOptions), b.(*config.JSONOptions), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*config.JSONOptions)(nil), (*JSONOptions)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_config_JSONOptions_To_v1alpha1_JSONOptions(a.(*config.JSONOptions), b.(*JSONOptions), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*VModuleItem)(nil), (*config.VModuleItem)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_VModuleItem_To_config_VModuleItem(a.(*VModuleItem), b.(*config.VModuleItem), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*config.VModuleItem)(nil), (*VModuleItem)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_config_VModuleItem_To_v1alpha1_VModuleItem(a.(*config.VModuleItem), b.(*VModuleItem), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*config.ClientConnectionConfiguration)(nil), (*ClientConnectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(a.(*config.ClientConnectionConfiguration), b.(*ClientConnectionConfiguration), scope)
|
||||
}); err != nil {
|
||||
@ -83,11 +50,6 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*config.LoggingConfiguration)(nil), (*LoggingConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_config_LoggingConfiguration_To_v1alpha1_LoggingConfiguration(a.(*config.LoggingConfiguration), b.(*LoggingConfiguration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*ClientConnectionConfiguration)(nil), (*config.ClientConnectionConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(a.(*ClientConnectionConfiguration), b.(*config.ClientConnectionConfiguration), scope)
|
||||
}); err != nil {
|
||||
@ -103,11 +65,6 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*LoggingConfiguration)(nil), (*config.LoggingConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_LoggingConfiguration_To_config_LoggingConfiguration(a.(*LoggingConfiguration), b.(*config.LoggingConfiguration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -149,52 +106,6 @@ func autoConvert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguratio
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_FormatOptions_To_config_FormatOptions(in *FormatOptions, out *config.FormatOptions, s conversion.Scope) error {
|
||||
if err := Convert_v1alpha1_JSONOptions_To_config_JSONOptions(&in.JSON, &out.JSON, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_FormatOptions_To_config_FormatOptions is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_FormatOptions_To_config_FormatOptions(in *FormatOptions, out *config.FormatOptions, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_FormatOptions_To_config_FormatOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_config_FormatOptions_To_v1alpha1_FormatOptions(in *config.FormatOptions, out *FormatOptions, s conversion.Scope) error {
|
||||
if err := Convert_config_JSONOptions_To_v1alpha1_JSONOptions(&in.JSON, &out.JSON, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_config_FormatOptions_To_v1alpha1_FormatOptions is an autogenerated conversion function.
|
||||
func Convert_config_FormatOptions_To_v1alpha1_FormatOptions(in *config.FormatOptions, out *FormatOptions, s conversion.Scope) error {
|
||||
return autoConvert_config_FormatOptions_To_v1alpha1_FormatOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_JSONOptions_To_config_JSONOptions(in *JSONOptions, out *config.JSONOptions, s conversion.Scope) error {
|
||||
out.SplitStream = in.SplitStream
|
||||
out.InfoBufferSize = in.InfoBufferSize
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_JSONOptions_To_config_JSONOptions is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_JSONOptions_To_config_JSONOptions(in *JSONOptions, out *config.JSONOptions, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_JSONOptions_To_config_JSONOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_config_JSONOptions_To_v1alpha1_JSONOptions(in *config.JSONOptions, out *JSONOptions, s conversion.Scope) error {
|
||||
out.SplitStream = in.SplitStream
|
||||
out.InfoBufferSize = in.InfoBufferSize
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_config_JSONOptions_To_v1alpha1_JSONOptions is an autogenerated conversion function.
|
||||
func Convert_config_JSONOptions_To_v1alpha1_JSONOptions(in *config.JSONOptions, out *JSONOptions, s conversion.Scope) error {
|
||||
return autoConvert_config_JSONOptions_To_v1alpha1_JSONOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(in *LeaderElectionConfiguration, out *config.LeaderElectionConfiguration, s conversion.Scope) error {
|
||||
if err := v1.Convert_Pointer_bool_To_bool(&in.LeaderElect, &out.LeaderElect, s); err != nil {
|
||||
return err
|
||||
@ -220,47 +131,3 @@ func autoConvert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionCo
|
||||
out.ResourceNamespace = in.ResourceNamespace
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_LoggingConfiguration_To_config_LoggingConfiguration(in *LoggingConfiguration, out *config.LoggingConfiguration, s conversion.Scope) error {
|
||||
out.Format = in.Format
|
||||
out.FlushFrequency = time.Duration(in.FlushFrequency)
|
||||
out.Verbosity = config.VerbosityLevel(in.Verbosity)
|
||||
out.VModule = *(*config.VModuleConfiguration)(unsafe.Pointer(&in.VModule))
|
||||
if err := Convert_v1alpha1_FormatOptions_To_config_FormatOptions(&in.Options, &out.Options, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_config_LoggingConfiguration_To_v1alpha1_LoggingConfiguration(in *config.LoggingConfiguration, out *LoggingConfiguration, s conversion.Scope) error {
|
||||
out.Format = in.Format
|
||||
out.FlushFrequency = time.Duration(in.FlushFrequency)
|
||||
out.Verbosity = uint32(in.Verbosity)
|
||||
out.VModule = *(*VModuleConfiguration)(unsafe.Pointer(&in.VModule))
|
||||
if err := Convert_config_FormatOptions_To_v1alpha1_FormatOptions(&in.Options, &out.Options, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_VModuleItem_To_config_VModuleItem(in *VModuleItem, out *config.VModuleItem, s conversion.Scope) error {
|
||||
out.FilePattern = in.FilePattern
|
||||
out.Verbosity = config.VerbosityLevel(in.Verbosity)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_VModuleItem_To_config_VModuleItem is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_VModuleItem_To_config_VModuleItem(in *VModuleItem, out *config.VModuleItem, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_VModuleItem_To_config_VModuleItem(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_config_VModuleItem_To_v1alpha1_VModuleItem(in *config.VModuleItem, out *VModuleItem, s conversion.Scope) error {
|
||||
out.FilePattern = in.FilePattern
|
||||
out.Verbosity = uint32(in.Verbosity)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_config_VModuleItem_To_v1alpha1_VModuleItem is an autogenerated conversion function.
|
||||
func Convert_config_VModuleItem_To_v1alpha1_VModuleItem(in *config.VModuleItem, out *VModuleItem, s conversion.Scope) error {
|
||||
return autoConvert_config_VModuleItem_To_v1alpha1_VModuleItem(in, out, s)
|
||||
}
|
||||
|
92
vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go
generated
vendored
92
vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go
generated
vendored
@ -63,40 +63,6 @@ func (in *DebuggingConfiguration) DeepCopy() *DebuggingConfiguration {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FormatOptions) DeepCopyInto(out *FormatOptions) {
|
||||
*out = *in
|
||||
in.JSON.DeepCopyInto(&out.JSON)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FormatOptions.
|
||||
func (in *FormatOptions) DeepCopy() *FormatOptions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FormatOptions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *JSONOptions) DeepCopyInto(out *JSONOptions) {
|
||||
*out = *in
|
||||
in.InfoBufferSize.DeepCopyInto(&out.InfoBufferSize)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONOptions.
|
||||
func (in *JSONOptions) DeepCopy() *JSONOptions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(JSONOptions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LeaderElectionConfiguration) DeepCopyInto(out *LeaderElectionConfiguration) {
|
||||
*out = *in
|
||||
@ -120,61 +86,3 @@ func (in *LeaderElectionConfiguration) DeepCopy() *LeaderElectionConfiguration {
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LoggingConfiguration) DeepCopyInto(out *LoggingConfiguration) {
|
||||
*out = *in
|
||||
if in.VModule != nil {
|
||||
in, out := &in.VModule, &out.VModule
|
||||
*out = make(VModuleConfiguration, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.Options.DeepCopyInto(&out.Options)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoggingConfiguration.
|
||||
func (in *LoggingConfiguration) DeepCopy() *LoggingConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LoggingConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in VModuleConfiguration) DeepCopyInto(out *VModuleConfiguration) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(VModuleConfiguration, len(*in))
|
||||
copy(*out, *in)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VModuleConfiguration.
|
||||
func (in VModuleConfiguration) DeepCopy() VModuleConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VModuleConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VModuleItem) DeepCopyInto(out *VModuleItem) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VModuleItem.
|
||||
func (in *VModuleItem) DeepCopy() *VModuleItem {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VModuleItem)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
92
vendor/k8s.io/component-base/config/zz_generated.deepcopy.go
generated
vendored
92
vendor/k8s.io/component-base/config/zz_generated.deepcopy.go
generated
vendored
@ -53,40 +53,6 @@ func (in *DebuggingConfiguration) DeepCopy() *DebuggingConfiguration {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FormatOptions) DeepCopyInto(out *FormatOptions) {
|
||||
*out = *in
|
||||
in.JSON.DeepCopyInto(&out.JSON)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FormatOptions.
|
||||
func (in *FormatOptions) DeepCopy() *FormatOptions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FormatOptions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *JSONOptions) DeepCopyInto(out *JSONOptions) {
|
||||
*out = *in
|
||||
in.InfoBufferSize.DeepCopyInto(&out.InfoBufferSize)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONOptions.
|
||||
func (in *JSONOptions) DeepCopy() *JSONOptions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(JSONOptions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LeaderElectionConfiguration) DeepCopyInto(out *LeaderElectionConfiguration) {
|
||||
*out = *in
|
||||
@ -105,61 +71,3 @@ func (in *LeaderElectionConfiguration) DeepCopy() *LeaderElectionConfiguration {
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LoggingConfiguration) DeepCopyInto(out *LoggingConfiguration) {
|
||||
*out = *in
|
||||
if in.VModule != nil {
|
||||
in, out := &in.VModule, &out.VModule
|
||||
*out = make(VModuleConfiguration, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.Options.DeepCopyInto(&out.Options)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoggingConfiguration.
|
||||
func (in *LoggingConfiguration) DeepCopy() *LoggingConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LoggingConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in VModuleConfiguration) DeepCopyInto(out *VModuleConfiguration) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(VModuleConfiguration, len(*in))
|
||||
copy(*out, *in)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VModuleConfiguration.
|
||||
func (in VModuleConfiguration) DeepCopy() VModuleConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VModuleConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VModuleItem) DeepCopyInto(out *VModuleItem) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VModuleItem.
|
||||
func (in *VModuleItem) DeepCopy() *VModuleItem {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VModuleItem)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
32
vendor/k8s.io/component-base/logs/api/v1/doc.go
generated
vendored
Normal file
32
vendor/k8s.io/component-base/logs/api/v1/doc.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright 2022 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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// Package v1 contains the configuration API for logging.
|
||||
//
|
||||
// The intention is to only have a single version of this API, potentially with
|
||||
// new fields added over time in a backwards-compatible manner. Fields for
|
||||
// alpha or beta features are allowed as long as they are defined so that not
|
||||
// changing the defaults leaves those features disabled.
|
||||
//
|
||||
// The "v1" package name is just a reminder that API compatibility rules apply,
|
||||
// not an indication of the stability of all features covered by it.
|
||||
|
||||
// The LoggingAlphaOptions and LoggingBetaOptions feature gates control whether
|
||||
// these unstable features can get enabled. This can be used to ensure that
|
||||
// command invocations do not accidentally rely on unstable features.
|
||||
package v1 // import "k8s.io/component-base/logs/api/v1"
|
70
vendor/k8s.io/component-base/logs/api/v1/kube_features.go
generated
vendored
Normal file
70
vendor/k8s.io/component-base/logs/api/v1/kube_features.go
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright 2022 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 v1
|
||||
|
||||
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
|
||||
|
||||
// Allow fine-tuning of experimental, alpha-quality logging options.
|
||||
//
|
||||
// Per https://groups.google.com/g/kubernetes-sig-architecture/c/Nxsc7pfe5rw/m/vF2djJh0BAAJ
|
||||
// we want to avoid a proliferation of feature gates. This feature gate:
|
||||
// - will guard *a group* of logging options whose quality level is alpha.
|
||||
// - will never graduate to beta or stable.
|
||||
LoggingAlphaOptions featuregate.Feature = "LoggingAlphaOptions"
|
||||
|
||||
// Allow fine-tuning of experimental, beta-quality logging options.
|
||||
//
|
||||
// Per https://groups.google.com/g/kubernetes-sig-architecture/c/Nxsc7pfe5rw/m/vF2djJh0BAAJ
|
||||
// we want to avoid a proliferation of feature gates. This feature gate:
|
||||
// - will guard *a group* of logging options whose quality level is beta.
|
||||
// - is thus *introduced* as beta
|
||||
// - will never graduate to stable.
|
||||
LoggingBetaOptions featuregate.Feature = "LoggingBetaOptions"
|
||||
|
||||
// Stable logging options. Always enabled.
|
||||
LoggingStableOptions featuregate.Feature = "LoggingStableOptions"
|
||||
)
|
||||
|
||||
func featureGates() map[featuregate.Feature]featuregate.FeatureSpec {
|
||||
return map[featuregate.Feature]featuregate.FeatureSpec{
|
||||
ContextualLogging: {Default: contextualLoggingDefault, PreRelease: featuregate.Alpha},
|
||||
|
||||
LoggingAlphaOptions: {Default: false, PreRelease: featuregate.Alpha},
|
||||
LoggingBetaOptions: {Default: true, PreRelease: featuregate.Beta},
|
||||
}
|
||||
}
|
||||
|
||||
// AddFeatureGates adds all feature gates used by this package.
|
||||
func AddFeatureGates(mutableFeatureGate featuregate.MutableFeatureGate) error {
|
||||
return mutableFeatureGate.Add(featureGates())
|
||||
}
|
282
vendor/k8s.io/component-base/logs/api/v1/options.go
generated
vendored
Normal file
282
vendor/k8s.io/component-base/logs/api/v1/options.go
generated
vendored
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
"k8s.io/component-base/featuregate"
|
||||
)
|
||||
|
||||
const (
|
||||
// LogFlushFreqDefault is the default for the corresponding command line
|
||||
// parameter.
|
||||
LogFlushFreqDefault = 5 * time.Second
|
||||
)
|
||||
|
||||
const (
|
||||
// LogFlushFreqFlagName is the name of the command line parameter.
|
||||
// Depending on how flags get added, it is either a stand-alone
|
||||
// value (logs.AddFlags) or part of LoggingConfiguration.
|
||||
LogFlushFreqFlagName = "log-flush-frequency"
|
||||
)
|
||||
|
||||
// NewLoggingConfiguration returns a struct holding the default logging configuration.
|
||||
func NewLoggingConfiguration() *LoggingConfiguration {
|
||||
c := LoggingConfiguration{}
|
||||
SetRecommendedLoggingConfiguration(&c)
|
||||
return &c
|
||||
}
|
||||
|
||||
// ValidateAndApply combines validation and application of the logging configuration.
|
||||
// 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.
|
||||
//
|
||||
// The optional FeatureGate controls logging features. If nil, the default for
|
||||
// these features is used.
|
||||
func ValidateAndApply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error {
|
||||
return ValidateAndApplyAsField(c, featureGate, nil)
|
||||
}
|
||||
|
||||
// ValidateAndApplyAsField is a variant of ValidateAndApply that should be used
|
||||
// when the LoggingConfiguration is embedded in some larger configuration
|
||||
// structure.
|
||||
func ValidateAndApplyAsField(c *LoggingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) error {
|
||||
errs := Validate(c, featureGate, fldPath)
|
||||
if len(errs) > 0 {
|
||||
return errs.ToAggregate()
|
||||
}
|
||||
return apply(c, featureGate)
|
||||
}
|
||||
|
||||
// Validate can be used to check for invalid settings without applying them.
|
||||
// Most binaries should validate and apply the logging configuration as soon
|
||||
// as possible via ValidateAndApply. The field path is optional: nil
|
||||
// can be passed when the struct is not embedded in some larger struct.
|
||||
func Validate(c *LoggingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) field.ErrorList {
|
||||
errs := field.ErrorList{}
|
||||
if c.Format != DefaultLogFormat {
|
||||
// WordSepNormalizeFunc is just a guess. Commands should use it,
|
||||
// but we cannot know for sure.
|
||||
allFlags := unsupportedLoggingFlags(cliflag.WordSepNormalizeFunc)
|
||||
for _, f := range allFlags {
|
||||
if f.DefValue != f.Value.String() {
|
||||
errs = append(errs, field.Invalid(fldPath.Child("format"), c.Format, fmt.Sprintf("Non-default format doesn't honor flag: %s", f.Name)))
|
||||
}
|
||||
}
|
||||
}
|
||||
format, err := logRegistry.get(c.Format)
|
||||
if err != nil {
|
||||
errs = append(errs, field.Invalid(fldPath.Child("format"), c.Format, "Unsupported log format"))
|
||||
} else if format != nil {
|
||||
if format.feature != LoggingStableOptions {
|
||||
enabled := featureGates()[format.feature].Default
|
||||
if featureGate != nil {
|
||||
enabled = featureGate.Enabled(format.feature)
|
||||
}
|
||||
if !enabled {
|
||||
errs = append(errs, field.Forbidden(fldPath.Child("format"), fmt.Sprintf("Log format %s is disabled, see %s feature", c.Format, format.feature)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The type in our struct is uint32, but klog only accepts positive int32.
|
||||
if c.Verbosity > math.MaxInt32 {
|
||||
errs = append(errs, field.Invalid(fldPath.Child("verbosity"), c.Verbosity, fmt.Sprintf("Must be <= %d", math.MaxInt32)))
|
||||
}
|
||||
vmoduleFldPath := fldPath.Child("vmodule")
|
||||
if len(c.VModule) > 0 && c.Format != "" && c.Format != "text" {
|
||||
errs = append(errs, field.Forbidden(vmoduleFldPath, "Only supported for text log format"))
|
||||
}
|
||||
for i, item := range c.VModule {
|
||||
if item.FilePattern == "" {
|
||||
errs = append(errs, field.Required(vmoduleFldPath.Index(i), "File pattern must not be empty"))
|
||||
}
|
||||
if strings.ContainsAny(item.FilePattern, "=,") {
|
||||
errs = append(errs, field.Invalid(vmoduleFldPath.Index(i), item.FilePattern, "File pattern must not contain equal sign or comma"))
|
||||
}
|
||||
if item.Verbosity > math.MaxInt32 {
|
||||
errs = append(errs, field.Invalid(vmoduleFldPath.Index(i), item.Verbosity, fmt.Sprintf("Must be <= %d", math.MaxInt32)))
|
||||
}
|
||||
}
|
||||
|
||||
errs = append(errs, validateFormatOptions(c, featureGate, fldPath.Child("options"))...)
|
||||
return errs
|
||||
}
|
||||
|
||||
func validateFormatOptions(c *LoggingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) field.ErrorList {
|
||||
errs := field.ErrorList{}
|
||||
errs = append(errs, validateJSONOptions(c, featureGate, fldPath.Child("json"))...)
|
||||
return errs
|
||||
}
|
||||
|
||||
func validateJSONOptions(c *LoggingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) field.ErrorList {
|
||||
errs := field.ErrorList{}
|
||||
if gate := LoggingAlphaOptions; c.Options.JSON.SplitStream && !featureEnabled(featureGate, gate) {
|
||||
errs = append(errs, field.Forbidden(fldPath.Child("splitStream"), fmt.Sprintf("Feature %s is disabled", gate)))
|
||||
}
|
||||
if gate := LoggingAlphaOptions; c.Options.JSON.InfoBufferSize.Value() != 0 && !featureEnabled(featureGate, gate) {
|
||||
errs = append(errs, field.Forbidden(fldPath.Child("infoBufferSize"), fmt.Sprintf("Feature %s is disabled", gate)))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func featureEnabled(featureGate featuregate.FeatureGate, feature featuregate.Feature) bool {
|
||||
enabled := false
|
||||
if featureGate != nil {
|
||||
enabled = featureGate.Enabled(feature)
|
||||
}
|
||||
return enabled
|
||||
}
|
||||
|
||||
func apply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error {
|
||||
contextualLoggingEnabled := contextualLoggingDefault
|
||||
if featureGate != nil {
|
||||
contextualLoggingEnabled = featureGate.Enabled(ContextualLogging)
|
||||
}
|
||||
|
||||
// if log format not exists, use nil loggr
|
||||
format, _ := logRegistry.get(c.Format)
|
||||
if format.factory == nil {
|
||||
klog.ClearLogger()
|
||||
} else {
|
||||
log, flush := format.factory.Create(*c)
|
||||
klog.SetLoggerWithOptions(log, klog.ContextualLogger(contextualLoggingEnabled), klog.FlushLogger(flush))
|
||||
}
|
||||
if err := loggingFlags.Lookup("v").Value.Set(VerbosityLevelPflag(&c.Verbosity).String()); err != nil {
|
||||
return fmt.Errorf("internal error while setting klog verbosity: %v", err)
|
||||
}
|
||||
if err := loggingFlags.Lookup("vmodule").Value.Set(VModuleConfigurationPflag(&c.VModule).String()); err != nil {
|
||||
return fmt.Errorf("internal error while setting klog vmodule: %v", err)
|
||||
}
|
||||
klog.StartFlushDaemon(c.FlushFrequency)
|
||||
klog.EnableContextualLogging(contextualLoggingEnabled)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddFlags adds command line flags for the configuration.
|
||||
func AddFlags(c *LoggingConfiguration, fs *pflag.FlagSet) {
|
||||
// The help text is generated assuming that flags will eventually use
|
||||
// hyphens, even if currently no normalization function is set for the
|
||||
// flag set yet.
|
||||
unsupportedFlags := strings.Join(unsupportedLoggingFlagNames(cliflag.WordSepNormalizeFunc), ", ")
|
||||
formats := logRegistry.list()
|
||||
fs.StringVar(&c.Format, "logging-format", c.Format, fmt.Sprintf("Sets the log format. Permitted formats: %s.\nNon-default formats don't honor these flags: %s.\nNon-default choices are currently alpha and subject to change without warning.", formats, unsupportedFlags))
|
||||
// No new log formats should be added after generation is of flag options
|
||||
logRegistry.freeze()
|
||||
|
||||
fs.DurationVar(&c.FlushFrequency, LogFlushFreqFlagName, c.FlushFrequency, "Maximum number of seconds between log flushes")
|
||||
fs.VarP(VerbosityLevelPflag(&c.Verbosity), "v", "v", "number for the log level verbosity")
|
||||
fs.Var(VModuleConfigurationPflag(&c.VModule), "vmodule", "comma-separated list of pattern=N settings for file-filtered logging (only works for text log format)")
|
||||
|
||||
// JSON options. We only register them if "json" is a valid format. The
|
||||
// config file API however always has them.
|
||||
if _, err := logRegistry.get("json"); err == nil {
|
||||
fs.BoolVar(&c.Options.JSON.SplitStream, "log-json-split-stream", false, "[Alpha] In JSON format, write error messages to stderr and info messages to stdout. The default is to write a single stream to stdout. Enable the LoggingAlphaOptions feature gate to use this.")
|
||||
fs.Var(&c.Options.JSON.InfoBufferSize, "log-json-info-buffer-size", "[Alpha] In JSON format with split output streams, the info messages can be buffered for a while to increase performance. The default value of zero bytes disables buffering. The size can be specified as number of bytes (512), multiples of 1000 (1K), multiples of 1024 (2Ki), or powers of those (3M, 4G, 5Mi, 6Gi). Enable the LoggingAlphaOptions feature gate to use this.")
|
||||
}
|
||||
}
|
||||
|
||||
// SetRecommendedLoggingConfiguration sets the default logging configuration
|
||||
// for fields that are unset.
|
||||
//
|
||||
// Consumers who embed LoggingConfiguration in their own configuration structs
|
||||
// may set custom defaults and then should call this function to add the
|
||||
// global defaults.
|
||||
func SetRecommendedLoggingConfiguration(c *LoggingConfiguration) {
|
||||
if c.Format == "" {
|
||||
c.Format = "text"
|
||||
}
|
||||
if c.FlushFrequency == 0 {
|
||||
c.FlushFrequency = LogFlushFreqDefault
|
||||
}
|
||||
var empty resource.QuantityValue
|
||||
if c.Options.JSON.InfoBufferSize == empty {
|
||||
c.Options.JSON.InfoBufferSize = resource.QuantityValue{
|
||||
// This is similar, but not quite the same as a default
|
||||
// constructed instance.
|
||||
Quantity: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
}
|
||||
// This sets the unexported Quantity.s which will be compared
|
||||
// by reflect.DeepEqual in some tests.
|
||||
_ = c.Options.JSON.InfoBufferSize.String()
|
||||
}
|
||||
}
|
||||
|
||||
// loggingFlags captures the state of the logging flags, in particular their default value
|
||||
// before flag parsing. It is used by unsupportedLoggingFlags.
|
||||
var loggingFlags pflag.FlagSet
|
||||
|
||||
func init() {
|
||||
var fs flag.FlagSet
|
||||
klog.InitFlags(&fs)
|
||||
loggingFlags.AddGoFlagSet(&fs)
|
||||
}
|
||||
|
||||
// List of logs (k8s.io/klog + k8s.io/component-base/logs) flags supported by all logging formats
|
||||
var supportedLogsFlags = map[string]struct{}{
|
||||
"v": {},
|
||||
// TODO: support vmodule after 1.19 Alpha
|
||||
}
|
||||
|
||||
// unsupportedLoggingFlags lists unsupported logging flags. The normalize
|
||||
// function is optional.
|
||||
func unsupportedLoggingFlags(normalizeFunc func(f *pflag.FlagSet, name string) pflag.NormalizedName) []*pflag.Flag {
|
||||
// k8s.io/component-base/logs and klog flags
|
||||
pfs := &pflag.FlagSet{}
|
||||
loggingFlags.VisitAll(func(flag *pflag.Flag) {
|
||||
if _, found := supportedLogsFlags[flag.Name]; !found {
|
||||
// Normalization changes flag.Name, so make a copy.
|
||||
clone := *flag
|
||||
pfs.AddFlag(&clone)
|
||||
}
|
||||
})
|
||||
|
||||
// Apply normalization.
|
||||
pfs.SetNormalizeFunc(normalizeFunc)
|
||||
|
||||
var allFlags []*pflag.Flag
|
||||
pfs.VisitAll(func(flag *pflag.Flag) {
|
||||
allFlags = append(allFlags, flag)
|
||||
})
|
||||
return allFlags
|
||||
}
|
||||
|
||||
// unsupportedLoggingFlagNames lists unsupported logging flags by name, with
|
||||
// optional normalization and sorted.
|
||||
func unsupportedLoggingFlagNames(normalizeFunc func(f *pflag.FlagSet, name string) pflag.NormalizedName) []string {
|
||||
unsupportedFlags := unsupportedLoggingFlags(normalizeFunc)
|
||||
names := make([]string, 0, len(unsupportedFlags))
|
||||
for _, f := range unsupportedFlags {
|
||||
names = append(names, "--"+f.Name)
|
||||
}
|
||||
sort.Strings(names)
|
||||
return names
|
||||
}
|
104
vendor/k8s.io/component-base/logs/api/v1/pflags.go
generated
vendored
Normal file
104
vendor/k8s.io/component-base/logs/api/v1/pflags.go
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// VModuleConfigurationPflag implements the pflag.Value interface for a
|
||||
// VModuleConfiguration. The value pointer must not be nil.
|
||||
func VModuleConfigurationPflag(value *VModuleConfiguration) pflag.Value {
|
||||
return vmoduleConfigurationPFlag{value}
|
||||
}
|
||||
|
||||
type vmoduleConfigurationPFlag struct {
|
||||
value *VModuleConfiguration
|
||||
}
|
||||
|
||||
// String returns the -vmodule parameter (comma-separated list of pattern=N).
|
||||
func (wrapper vmoduleConfigurationPFlag) String() string {
|
||||
var patterns []string
|
||||
for _, item := range *wrapper.value {
|
||||
patterns = append(patterns, fmt.Sprintf("%s=%d", item.FilePattern, item.Verbosity))
|
||||
}
|
||||
return strings.Join(patterns, ",")
|
||||
}
|
||||
|
||||
// Set parses the -vmodule parameter (comma-separated list of pattern=N).
|
||||
func (wrapper vmoduleConfigurationPFlag) Set(value string) error {
|
||||
// This code mirrors https://github.com/kubernetes/klog/blob/9ad246211af1ed84621ee94a26fcce0038b69cd1/klog.go#L287-L313
|
||||
|
||||
for _, pat := range strings.Split(value, ",") {
|
||||
if len(pat) == 0 {
|
||||
// Empty strings such as from a trailing comma can be ignored.
|
||||
continue
|
||||
}
|
||||
patLev := strings.Split(pat, "=")
|
||||
if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
|
||||
return fmt.Errorf("%q does not have the pattern=N format", pat)
|
||||
}
|
||||
pattern := patLev[0]
|
||||
// 31 instead of 32 to ensure that it also fits into int32.
|
||||
v, err := strconv.ParseUint(patLev[1], 10, 31)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing verbosity in %q: %v", pat, err)
|
||||
}
|
||||
*wrapper.value = append(*wrapper.value, VModuleItem{FilePattern: pattern, Verbosity: VerbosityLevel(v)})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wrapper vmoduleConfigurationPFlag) Type() string {
|
||||
return "pattern=N,..."
|
||||
}
|
||||
|
||||
// VerbosityLevelPflag implements the pflag.Value interface for a verbosity
|
||||
// level value.
|
||||
func VerbosityLevelPflag(value *VerbosityLevel) pflag.Value {
|
||||
return verbosityLevelPflag{value}
|
||||
}
|
||||
|
||||
type verbosityLevelPflag struct {
|
||||
value *VerbosityLevel
|
||||
}
|
||||
|
||||
func (wrapper verbosityLevelPflag) String() string {
|
||||
return strconv.FormatInt(int64(*wrapper.value), 10)
|
||||
}
|
||||
|
||||
func (wrapper verbosityLevelPflag) Get() interface{} {
|
||||
return *wrapper.value
|
||||
}
|
||||
|
||||
func (wrapper verbosityLevelPflag) Set(value string) error {
|
||||
// Limited to int32 for compatibility with klog.
|
||||
v, err := strconv.ParseUint(value, 10, 31)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*wrapper.value = VerbosityLevel(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wrapper verbosityLevelPflag) Type() string {
|
||||
return "Level"
|
||||
}
|
110
vendor/k8s.io/component-base/logs/api/v1/registry.go
generated
vendored
Normal file
110
vendor/k8s.io/component-base/logs/api/v1/registry.go
generated
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
|
||||
"k8s.io/component-base/featuregate"
|
||||
)
|
||||
|
||||
var logRegistry = newLogFormatRegistry()
|
||||
|
||||
// logFormatRegistry stores factories for all supported logging formats.
|
||||
type logFormatRegistry struct {
|
||||
registry map[string]logFormat
|
||||
frozen bool
|
||||
}
|
||||
|
||||
type logFormat struct {
|
||||
factory LogFormatFactory
|
||||
feature featuregate.Feature
|
||||
}
|
||||
|
||||
// LogFormatFactory provides support for a certain additional,
|
||||
// non-default log format.
|
||||
type LogFormatFactory interface {
|
||||
// Create returns a logger with the requested configuration.
|
||||
// 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(c LoggingConfiguration) (log logr.Logger, flush func())
|
||||
}
|
||||
|
||||
// RegisterLogFormat registers support for a new logging format. This must be called
|
||||
// before using any of the methods in LoggingConfiguration. The feature must
|
||||
// be one of those defined in this package (typically LoggingAlphaOptions,
|
||||
// LoggingBetaOptions or LoggingStableOptions).
|
||||
func RegisterLogFormat(name string, factory LogFormatFactory, feature featuregate.Feature) error {
|
||||
return logRegistry.register(name, logFormat{factory, feature})
|
||||
}
|
||||
|
||||
func newLogFormatRegistry() *logFormatRegistry {
|
||||
registry := &logFormatRegistry{
|
||||
registry: make(map[string]logFormat),
|
||||
frozen: false,
|
||||
}
|
||||
registry.register("text", logFormat{feature: LoggingStableOptions})
|
||||
return registry
|
||||
}
|
||||
|
||||
// register adds a new log format. It's an error to modify an existing one.
|
||||
func (lfr *logFormatRegistry) register(name string, format logFormat) error {
|
||||
if lfr.frozen {
|
||||
return fmt.Errorf("log format registry is frozen, unable to register log format %s", name)
|
||||
}
|
||||
if _, ok := lfr.registry[name]; ok {
|
||||
return fmt.Errorf("log format: %s already exists", name)
|
||||
}
|
||||
if _, ok := featureGates()[format.feature]; !ok && format.feature != LoggingStableOptions {
|
||||
return fmt.Errorf("log format %s: unsupported feature gate %s", name, format.feature)
|
||||
}
|
||||
lfr.registry[name] = format
|
||||
return nil
|
||||
}
|
||||
|
||||
// get specified log format factory
|
||||
func (lfr *logFormatRegistry) get(name string) (*logFormat, error) {
|
||||
format, ok := lfr.registry[name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("log format: %s does not exists", name)
|
||||
}
|
||||
return &format, nil
|
||||
}
|
||||
|
||||
// list names of registered log formats, including feature gates (sorted)
|
||||
func (lfr *logFormatRegistry) list() string {
|
||||
formats := make([]string, 0, len(lfr.registry))
|
||||
for name, format := range lfr.registry {
|
||||
item := fmt.Sprintf(`"%s"`, name)
|
||||
if format.feature != LoggingStableOptions {
|
||||
item += fmt.Sprintf(" (gated by %s)", format.feature)
|
||||
}
|
||||
formats = append(formats, item)
|
||||
}
|
||||
sort.Strings(formats)
|
||||
return strings.Join(formats, ", ")
|
||||
}
|
||||
|
||||
// freeze prevents further modifications of the registered log formats.
|
||||
func (lfr *logFormatRegistry) freeze() {
|
||||
lfr.frozen = true
|
||||
}
|
99
vendor/k8s.io/component-base/logs/api/v1/types.go
generated
vendored
Normal file
99
vendor/k8s.io/component-base/logs/api/v1/types.go
generated
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
|
||||
// Supported output formats.
|
||||
const (
|
||||
// DefaultLogFormat is the traditional klog output format.
|
||||
DefaultLogFormat = "text"
|
||||
|
||||
// JSONLogFormat emits each log message as a JSON struct.
|
||||
JSONLogFormat = "json"
|
||||
)
|
||||
|
||||
// The alpha or beta level of structs is the highest stability level of any field
|
||||
// inside it. Feature gates will get checked during LoggingConfiguration.ValidateAndApply.
|
||||
|
||||
// LoggingConfiguration contains logging options.
|
||||
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 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
|
||||
// messages. Higher values enable additional messages. Error messages
|
||||
// are always logged.
|
||||
Verbosity VerbosityLevel `json:"verbosity"`
|
||||
// VModule overrides the verbosity threshold for individual files.
|
||||
// Only supported for "text" log format.
|
||||
VModule VModuleConfiguration `json:"vmodule,omitempty"`
|
||||
// [Alpha] 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.
|
||||
// Only available when the LoggingAlphaOptions feature gate is enabled.
|
||||
Options FormatOptions `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
// FormatOptions contains options for the different logging formats.
|
||||
type FormatOptions struct {
|
||||
// [Alpha] JSON contains options for logging format "json".
|
||||
// Only available when the LoggingAlphaOptions feature gate is enabled.
|
||||
JSON JSONOptions `json:"json,omitempty"`
|
||||
}
|
||||
|
||||
// JSONOptions contains options for logging format "json".
|
||||
type JSONOptions struct {
|
||||
// [Alpha] SplitStream redirects error messages to stderr while
|
||||
// info messages go to stdout, with buffering. The default is to write
|
||||
// both to stdout, without buffering. Only available when
|
||||
// the LoggingAlphaOptions feature gate is enabled.
|
||||
SplitStream bool `json:"splitStream,omitempty"`
|
||||
// [Alpha] InfoBufferSize sets the size of the info stream when
|
||||
// using split streams. The default is zero, which disables buffering.
|
||||
// Only available when the LoggingAlphaOptions feature gate is enabled.
|
||||
InfoBufferSize resource.QuantityValue `json:"infoBufferSize,omitempty"`
|
||||
}
|
||||
|
||||
// VModuleConfiguration is a collection of individual file names or patterns
|
||||
// and the corresponding verbosity threshold.
|
||||
type VModuleConfiguration []VModuleItem
|
||||
|
||||
// VModuleItem defines verbosity for one or more files which match a certain
|
||||
// glob pattern.
|
||||
type VModuleItem struct {
|
||||
// FilePattern is a base file name (i.e. minus the ".go" suffix and
|
||||
// directory) or a "glob" pattern for such a name. It must not contain
|
||||
// comma and equal signs because those are separators for the
|
||||
// corresponding klog command line argument.
|
||||
FilePattern string `json:"filePattern"`
|
||||
// Verbosity is the threshold for log messages emitted inside files
|
||||
// that match the pattern.
|
||||
Verbosity VerbosityLevel `json:"verbosity"`
|
||||
}
|
||||
|
||||
// VerbosityLevel represents a klog or logr verbosity threshold.
|
||||
type VerbosityLevel uint32
|
114
vendor/k8s.io/component-base/logs/api/v1/zz_generated.deepcopy.go
generated
vendored
Normal file
114
vendor/k8s.io/component-base/logs/api/v1/zz_generated.deepcopy.go
generated
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FormatOptions) DeepCopyInto(out *FormatOptions) {
|
||||
*out = *in
|
||||
in.JSON.DeepCopyInto(&out.JSON)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FormatOptions.
|
||||
func (in *FormatOptions) DeepCopy() *FormatOptions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FormatOptions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *JSONOptions) DeepCopyInto(out *JSONOptions) {
|
||||
*out = *in
|
||||
in.InfoBufferSize.DeepCopyInto(&out.InfoBufferSize)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONOptions.
|
||||
func (in *JSONOptions) DeepCopy() *JSONOptions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(JSONOptions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LoggingConfiguration) DeepCopyInto(out *LoggingConfiguration) {
|
||||
*out = *in
|
||||
if in.VModule != nil {
|
||||
in, out := &in.VModule, &out.VModule
|
||||
*out = make(VModuleConfiguration, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.Options.DeepCopyInto(&out.Options)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoggingConfiguration.
|
||||
func (in *LoggingConfiguration) DeepCopy() *LoggingConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LoggingConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in VModuleConfiguration) DeepCopyInto(out *VModuleConfiguration) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(VModuleConfiguration, len(*in))
|
||||
copy(*out, *in)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VModuleConfiguration.
|
||||
func (in VModuleConfiguration) DeepCopy() VModuleConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VModuleConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VModuleItem) DeepCopyInto(out *VModuleItem) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VModuleItem.
|
||||
func (in *VModuleItem) DeepCopy() *VModuleItem {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VModuleItem)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
17
vendor/k8s.io/component-base/metrics/counter.go
generated
vendored
17
vendor/k8s.io/component-base/metrics/counter.go
generated
vendored
@ -18,6 +18,7 @@ package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
@ -106,9 +107,14 @@ type CounterVec struct {
|
||||
originalLabels []string
|
||||
}
|
||||
|
||||
// NewCounterVec returns an object which satisfies the kubeCollector and CounterVecMetric interfaces.
|
||||
var _ kubeCollector = &CounterVec{}
|
||||
|
||||
// TODO: make this true: var _ CounterVecMetric = &CounterVec{}
|
||||
|
||||
// NewCounterVec returns an object which satisfies the kubeCollector and (almost) CounterVecMetric interfaces.
|
||||
// However, the object returned will not measure anything unless the collector is first
|
||||
// registered, since the metric is lazily instantiated.
|
||||
// registered, since the metric is lazily instantiated, and only members extracted after
|
||||
// registration will actually measure anything.
|
||||
func NewCounterVec(opts *CounterOpts, labels []string) *CounterVec {
|
||||
opts.StabilityLevel.setDefaults()
|
||||
|
||||
@ -149,13 +155,16 @@ func (v *CounterVec) initializeDeprecatedMetric() {
|
||||
v.initializeMetric()
|
||||
}
|
||||
|
||||
// Default Prometheus behavior actually results in the creation of a new metric
|
||||
// if a metric with the unique label values is not found in the underlying stored metricMap.
|
||||
// Default Prometheus Vec behavior is that member extraction results in creation of a new element
|
||||
// if one with the unique label values is not found in the underlying stored metricMap.
|
||||
// This means that if this function is called but the underlying metric is not registered
|
||||
// (which means it will never be exposed externally nor consumed), the metric will exist in memory
|
||||
// for perpetuity (i.e. throughout application lifecycle).
|
||||
//
|
||||
// For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/counter.go#L179-L197
|
||||
//
|
||||
// In contrast, the Vec behavior in this package is that member extraction before registration
|
||||
// returns a permanent noop object.
|
||||
|
||||
// WithLabelValues returns the Counter for the given slice of label
|
||||
// values (same order as the VariableLabels in Desc). If that combination of
|
||||
|
4
vendor/k8s.io/component-base/metrics/desc.go
generated
vendored
4
vendor/k8s.io/component-base/metrics/desc.go
generated
vendored
@ -218,8 +218,8 @@ func (d *Desc) initializeDeprecatedDesc() {
|
||||
// GetRawDesc will returns a new *Desc with original parameters provided to NewDesc().
|
||||
//
|
||||
// It will be useful in testing scenario that the same Desc be registered to different registry.
|
||||
// 1. Desc `D` is registered to registry 'A' in TestA (Note: `D` maybe created)
|
||||
// 2. Desc `D` is registered to registry 'B' in TestB (Note: since 'D' has been created once, thus will be ignored by registry 'B')
|
||||
// 1. Desc `D` is registered to registry 'A' in TestA (Note: `D` maybe created)
|
||||
// 2. Desc `D` is registered to registry 'B' in TestB (Note: since 'D' has been created once, thus will be ignored by registry 'B')
|
||||
func (d *Desc) GetRawDesc() *Desc {
|
||||
return NewDesc(d.fqName, d.help, d.variableLabels, d.constLabels, d.stabilityLevel, d.deprecatedVersion)
|
||||
}
|
||||
|
69
vendor/k8s.io/component-base/metrics/gauge.go
generated
vendored
69
vendor/k8s.io/component-base/metrics/gauge.go
generated
vendored
@ -18,6 +18,7 @@ package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
@ -33,7 +34,11 @@ type Gauge struct {
|
||||
selfCollector
|
||||
}
|
||||
|
||||
// NewGauge returns an object which satisfies the kubeCollector and KubeGauge interfaces.
|
||||
var _ GaugeMetric = &Gauge{}
|
||||
var _ Registerable = &Gauge{}
|
||||
var _ kubeCollector = &Gauge{}
|
||||
|
||||
// NewGauge returns an object which satisfies the kubeCollector, Registerable, and Gauge interfaces.
|
||||
// However, the object returned will not measure anything unless the collector is first
|
||||
// registered, since the metric is lazily instantiated.
|
||||
func NewGauge(opts *GaugeOpts) *Gauge {
|
||||
@ -88,9 +93,14 @@ type GaugeVec struct {
|
||||
originalLabels []string
|
||||
}
|
||||
|
||||
// NewGaugeVec returns an object which satisfies the kubeCollector and KubeGaugeVec interfaces.
|
||||
var _ GaugeVecMetric = &GaugeVec{}
|
||||
var _ Registerable = &GaugeVec{}
|
||||
var _ kubeCollector = &GaugeVec{}
|
||||
|
||||
// NewGaugeVec returns an object which satisfies the kubeCollector, Registerable, and GaugeVecMetric interfaces.
|
||||
// However, the object returned will not measure anything unless the collector is first
|
||||
// registered, since the metric is lazily instantiated.
|
||||
// registered, since the metric is lazily instantiated, and only members extracted after
|
||||
// registration will actually measure anything.
|
||||
func NewGaugeVec(opts *GaugeOpts, labels []string) *GaugeVec {
|
||||
opts.StabilityLevel.setDefaults()
|
||||
|
||||
@ -130,26 +140,55 @@ func (v *GaugeVec) initializeDeprecatedMetric() {
|
||||
v.initializeMetric()
|
||||
}
|
||||
|
||||
// Default Prometheus behavior actually results in the creation of a new metric
|
||||
// if a metric with the unique label values is not found in the underlying stored metricMap.
|
||||
func (v *GaugeVec) WithLabelValuesChecked(lvs ...string) (GaugeMetric, error) {
|
||||
if !v.IsCreated() {
|
||||
if v.IsHidden() {
|
||||
return noop, nil
|
||||
}
|
||||
return noop, errNotRegistered // return no-op gauge
|
||||
}
|
||||
if v.LabelValueAllowLists != nil {
|
||||
v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs)
|
||||
}
|
||||
elt, err := v.GaugeVec.GetMetricWithLabelValues(lvs...)
|
||||
return elt, err
|
||||
}
|
||||
|
||||
// Default Prometheus Vec behavior is that member extraction results in creation of a new element
|
||||
// if one with the unique label values is not found in the underlying stored metricMap.
|
||||
// This means that if this function is called but the underlying metric is not registered
|
||||
// (which means it will never be exposed externally nor consumed), the metric will exist in memory
|
||||
// for perpetuity (i.e. throughout application lifecycle).
|
||||
//
|
||||
// For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/gauge.go#L190-L208
|
||||
//
|
||||
// In contrast, the Vec behavior in this package is that member extraction before registration
|
||||
// returns a permanent noop object.
|
||||
|
||||
// WithLabelValues returns the GaugeMetric for the given slice of label
|
||||
// values (same order as the VariableLabels in Desc). If that combination of
|
||||
// label values is accessed for the first time, a new GaugeMetric is created IFF the gaugeVec
|
||||
// has been registered to a metrics registry.
|
||||
func (v *GaugeVec) WithLabelValues(lvs ...string) GaugeMetric {
|
||||
ans, err := v.WithLabelValuesChecked(lvs...)
|
||||
if err == nil || ErrIsNotRegistered(err) {
|
||||
return ans
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
func (v *GaugeVec) WithChecked(labels map[string]string) (GaugeMetric, error) {
|
||||
if !v.IsCreated() {
|
||||
return noop // return no-op gauge
|
||||
if v.IsHidden() {
|
||||
return noop, nil
|
||||
}
|
||||
return noop, errNotRegistered // return no-op gauge
|
||||
}
|
||||
if v.LabelValueAllowLists != nil {
|
||||
v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs)
|
||||
v.LabelValueAllowLists.ConstrainLabelMap(labels)
|
||||
}
|
||||
return v.GaugeVec.WithLabelValues(lvs...)
|
||||
elt, err := v.GaugeVec.GetMetricWith(labels)
|
||||
return elt, err
|
||||
}
|
||||
|
||||
// With returns the GaugeMetric for the given Labels map (the label names
|
||||
@ -157,13 +196,11 @@ func (v *GaugeVec) WithLabelValues(lvs ...string) GaugeMetric {
|
||||
// accessed for the first time, a new GaugeMetric is created IFF the gaugeVec has
|
||||
// been registered to a metrics registry.
|
||||
func (v *GaugeVec) With(labels map[string]string) GaugeMetric {
|
||||
if !v.IsCreated() {
|
||||
return noop // return no-op gauge
|
||||
ans, err := v.WithChecked(labels)
|
||||
if err == nil || ErrIsNotRegistered(err) {
|
||||
return ans
|
||||
}
|
||||
if v.LabelValueAllowLists != nil {
|
||||
v.LabelValueAllowLists.ConstrainLabelMap(labels)
|
||||
}
|
||||
return v.GaugeVec.With(labels)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Delete deletes the metric where the variable labels are the same as those
|
||||
@ -219,6 +256,10 @@ func (v *GaugeVec) WithContext(ctx context.Context) *GaugeVecWithContext {
|
||||
}
|
||||
}
|
||||
|
||||
func (v *GaugeVec) InterfaceWithContext(ctx context.Context) GaugeVecMetric {
|
||||
return v.WithContext(ctx)
|
||||
}
|
||||
|
||||
// GaugeVecWithContext is the wrapper of GaugeVec with context.
|
||||
type GaugeVecWithContext struct {
|
||||
*GaugeVec
|
||||
|
13
vendor/k8s.io/component-base/metrics/histogram.go
generated
vendored
13
vendor/k8s.io/component-base/metrics/histogram.go
generated
vendored
@ -18,6 +18,7 @@ package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
@ -100,7 +101,10 @@ type HistogramVec struct {
|
||||
|
||||
// NewHistogramVec returns an object which satisfies kubeCollector and wraps the
|
||||
// prometheus.HistogramVec object. However, the object returned will not measure
|
||||
// anything unless the collector is first registered, since the metric is lazily instantiated.
|
||||
// anything unless the collector is first registered, since the metric is lazily instantiated,
|
||||
// and only members extracted after
|
||||
// registration will actually measure anything.
|
||||
|
||||
func NewHistogramVec(opts *HistogramOpts, labels []string) *HistogramVec {
|
||||
opts.StabilityLevel.setDefaults()
|
||||
|
||||
@ -136,13 +140,16 @@ func (v *HistogramVec) initializeDeprecatedMetric() {
|
||||
v.initializeMetric()
|
||||
}
|
||||
|
||||
// Default Prometheus behavior actually results in the creation of a new metric
|
||||
// if a metric with the unique label values is not found in the underlying stored metricMap.
|
||||
// Default Prometheus Vec behavior is that member extraction results in creation of a new element
|
||||
// if one with the unique label values is not found in the underlying stored metricMap.
|
||||
// This means that if this function is called but the underlying metric is not registered
|
||||
// (which means it will never be exposed externally nor consumed), the metric will exist in memory
|
||||
// for perpetuity (i.e. throughout application lifecycle).
|
||||
//
|
||||
// For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/histogram.go#L460-L470
|
||||
//
|
||||
// In contrast, the Vec behavior in this package is that member extraction before registration
|
||||
// returns a permanent noop object.
|
||||
|
||||
// WithLabelValues returns the ObserverMetric for the given slice of label
|
||||
// values (same order as the VariableLabels in Desc). If that combination of
|
||||
|
36
vendor/k8s.io/component-base/metrics/metric.go
generated
vendored
36
vendor/k8s.io/component-base/metrics/metric.go
generated
vendored
@ -22,6 +22,7 @@ import (
|
||||
"github.com/blang/semver/v4"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
promext "k8s.io/component-base/metrics/prometheusextension"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
@ -90,13 +91,14 @@ func (r *lazyMetric) lazyInit(self kubeCollector, fqName string) {
|
||||
// preprocessMetric figures out whether the lazy metric should be hidden or not.
|
||||
// This method takes a Version argument which should be the version of the binary in which
|
||||
// this code is currently being executed. A metric can be hidden under two conditions:
|
||||
// 1. if the metric is deprecated and is outside the grace period (i.e. has been
|
||||
// deprecated for more than one release
|
||||
// 2. if the metric is manually disabled via a CLI flag.
|
||||
// 1. if the metric is deprecated and is outside the grace period (i.e. has been
|
||||
// deprecated for more than one release
|
||||
// 2. if the metric is manually disabled via a CLI flag.
|
||||
//
|
||||
// Disclaimer: disabling a metric via a CLI flag has higher precedence than
|
||||
// deprecation and will override show-hidden-metrics for the explicitly
|
||||
// disabled metric.
|
||||
//
|
||||
// deprecation and will override show-hidden-metrics for the explicitly
|
||||
// disabled metric.
|
||||
func (r *lazyMetric) preprocessMetric(version semver.Version) {
|
||||
disabledMetricsLock.RLock()
|
||||
defer disabledMetricsLock.RUnlock()
|
||||
@ -203,6 +205,7 @@ func (c *selfCollector) Collect(ch chan<- prometheus.Metric) {
|
||||
// no-op vecs for convenience
|
||||
var noopCounterVec = &prometheus.CounterVec{}
|
||||
var noopHistogramVec = &prometheus.HistogramVec{}
|
||||
var noopTimingHistogramVec = &promext.TimingHistogramVec{}
|
||||
var noopGaugeVec = &prometheus.GaugeVec{}
|
||||
var noopObserverVec = &noopObserverVector{}
|
||||
|
||||
@ -211,17 +214,18 @@ var noop = &noopMetric{}
|
||||
|
||||
type noopMetric struct{}
|
||||
|
||||
func (noopMetric) Inc() {}
|
||||
func (noopMetric) Add(float64) {}
|
||||
func (noopMetric) Dec() {}
|
||||
func (noopMetric) Set(float64) {}
|
||||
func (noopMetric) Sub(float64) {}
|
||||
func (noopMetric) Observe(float64) {}
|
||||
func (noopMetric) SetToCurrentTime() {}
|
||||
func (noopMetric) Desc() *prometheus.Desc { return nil }
|
||||
func (noopMetric) Write(*dto.Metric) error { return nil }
|
||||
func (noopMetric) Describe(chan<- *prometheus.Desc) {}
|
||||
func (noopMetric) Collect(chan<- prometheus.Metric) {}
|
||||
func (noopMetric) Inc() {}
|
||||
func (noopMetric) Add(float64) {}
|
||||
func (noopMetric) Dec() {}
|
||||
func (noopMetric) Set(float64) {}
|
||||
func (noopMetric) Sub(float64) {}
|
||||
func (noopMetric) Observe(float64) {}
|
||||
func (noopMetric) ObserveWithWeight(float64, uint64) {}
|
||||
func (noopMetric) SetToCurrentTime() {}
|
||||
func (noopMetric) Desc() *prometheus.Desc { return nil }
|
||||
func (noopMetric) Write(*dto.Metric) error { return nil }
|
||||
func (noopMetric) Describe(chan<- *prometheus.Desc) {}
|
||||
func (noopMetric) Collect(chan<- prometheus.Metric) {}
|
||||
|
||||
type noopObserverVector struct{}
|
||||
|
||||
|
49
vendor/k8s.io/component-base/metrics/opts.go
generated
vendored
49
vendor/k8s.io/component-base/metrics/opts.go
generated
vendored
@ -24,6 +24,7 @@ import (
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
promext "k8s.io/component-base/metrics/prometheusextension"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -189,6 +190,54 @@ func (o *HistogramOpts) toPromHistogramOpts() prometheus.HistogramOpts {
|
||||
}
|
||||
}
|
||||
|
||||
// TimingHistogramOpts bundles the options for creating a TimingHistogram metric. It is
|
||||
// mandatory to set Name to a non-empty string. All other fields are optional
|
||||
// and can safely be left at their zero value, although it is strongly
|
||||
// encouraged to set a Help string.
|
||||
type TimingHistogramOpts struct {
|
||||
Namespace string
|
||||
Subsystem string
|
||||
Name string
|
||||
Help string
|
||||
ConstLabels map[string]string
|
||||
Buckets []float64
|
||||
InitialValue float64
|
||||
DeprecatedVersion string
|
||||
deprecateOnce sync.Once
|
||||
annotateOnce sync.Once
|
||||
StabilityLevel StabilityLevel
|
||||
LabelValueAllowLists *MetricLabelAllowList
|
||||
}
|
||||
|
||||
// Modify help description on the metric description.
|
||||
func (o *TimingHistogramOpts) markDeprecated() {
|
||||
o.deprecateOnce.Do(func() {
|
||||
o.Help = fmt.Sprintf("(Deprecated since %v) %v", o.DeprecatedVersion, o.Help)
|
||||
})
|
||||
}
|
||||
|
||||
// annotateStabilityLevel annotates help description on the metric description with the stability level
|
||||
// of the metric
|
||||
func (o *TimingHistogramOpts) annotateStabilityLevel() {
|
||||
o.annotateOnce.Do(func() {
|
||||
o.Help = fmt.Sprintf("[%v] %v", o.StabilityLevel, o.Help)
|
||||
})
|
||||
}
|
||||
|
||||
// convenience function to allow easy transformation to the prometheus
|
||||
// counterpart. This will do more once we have a proper label abstraction
|
||||
func (o *TimingHistogramOpts) toPromHistogramOpts() promext.TimingHistogramOpts {
|
||||
return promext.TimingHistogramOpts{
|
||||
Namespace: o.Namespace,
|
||||
Subsystem: o.Subsystem,
|
||||
Name: o.Name,
|
||||
Help: o.Help,
|
||||
ConstLabels: o.ConstLabels,
|
||||
Buckets: o.Buckets,
|
||||
InitialValue: o.InitialValue,
|
||||
}
|
||||
}
|
||||
|
||||
// SummaryOpts bundles the options for creating a Summary metric. It is
|
||||
// mandatory to set Name to a non-empty string. While all other fields are
|
||||
// optional and can safely be left at their zero value, it is recommended to set
|
||||
|
189
vendor/k8s.io/component-base/metrics/prometheusextension/timing_histogram.go
generated
vendored
Normal file
189
vendor/k8s.io/component-base/metrics/prometheusextension/timing_histogram.go
generated
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
Copyright 2022 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 prometheusextension
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
)
|
||||
|
||||
// GaugeOps is the part of `prometheus.Gauge` that is relevant to
|
||||
// instrumented code.
|
||||
// This factoring should be in prometheus, analogous to the way
|
||||
// it already factors out the Observer interface for histograms and summaries.
|
||||
type GaugeOps interface {
|
||||
// Set is the same as Gauge.Set
|
||||
Set(float64)
|
||||
// Inc is the same as Gauge.inc
|
||||
Inc()
|
||||
// Dec is the same as Gauge.Dec
|
||||
Dec()
|
||||
// Add is the same as Gauge.Add
|
||||
Add(float64)
|
||||
// Sub is the same as Gauge.Sub
|
||||
Sub(float64)
|
||||
|
||||
// SetToCurrentTime the same as Gauge.SetToCurrentTime
|
||||
SetToCurrentTime()
|
||||
}
|
||||
|
||||
// A TimingHistogram tracks how long a `float64` variable spends in
|
||||
// ranges defined by buckets. Time is counted in nanoseconds. The
|
||||
// histogram's sum is the integral over time (in nanoseconds, from
|
||||
// creation of the histogram) of the variable's value.
|
||||
type TimingHistogram interface {
|
||||
prometheus.Metric
|
||||
prometheus.Collector
|
||||
GaugeOps
|
||||
}
|
||||
|
||||
// TimingHistogramOpts is the parameters of the TimingHistogram constructor
|
||||
type TimingHistogramOpts struct {
|
||||
Namespace string
|
||||
Subsystem string
|
||||
Name string
|
||||
Help string
|
||||
ConstLabels prometheus.Labels
|
||||
|
||||
// Buckets defines the buckets into which observations are
|
||||
// accumulated. Each element in the slice is the upper
|
||||
// inclusive bound of a bucket. The values must be sorted in
|
||||
// strictly increasing order. There is no need to add a
|
||||
// highest bucket with +Inf bound. The default value is
|
||||
// prometheus.DefBuckets.
|
||||
Buckets []float64
|
||||
|
||||
// The initial value of the variable.
|
||||
InitialValue float64
|
||||
}
|
||||
|
||||
// NewTimingHistogram creates a new TimingHistogram
|
||||
func NewTimingHistogram(opts TimingHistogramOpts) (TimingHistogram, error) {
|
||||
return NewTestableTimingHistogram(time.Now, opts)
|
||||
}
|
||||
|
||||
// NewTestableTimingHistogram creates a TimingHistogram that uses a mockable clock
|
||||
func NewTestableTimingHistogram(nowFunc func() time.Time, opts TimingHistogramOpts) (TimingHistogram, error) {
|
||||
desc := prometheus.NewDesc(
|
||||
prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
||||
wrapTimingHelp(opts.Help),
|
||||
nil,
|
||||
opts.ConstLabels,
|
||||
)
|
||||
return newTimingHistogram(nowFunc, desc, opts)
|
||||
}
|
||||
|
||||
func wrapTimingHelp(given string) string {
|
||||
return "EXPERIMENTAL: " + given
|
||||
}
|
||||
|
||||
func newTimingHistogram(nowFunc func() time.Time, desc *prometheus.Desc, opts TimingHistogramOpts, variableLabelValues ...string) (TimingHistogram, error) {
|
||||
allLabelsM := prometheus.Labels{}
|
||||
allLabelsS := prometheus.MakeLabelPairs(desc, variableLabelValues)
|
||||
for _, pair := range allLabelsS {
|
||||
if pair == nil || pair.Name == nil || pair.Value == nil {
|
||||
return nil, errors.New("prometheus.MakeLabelPairs returned a nil")
|
||||
}
|
||||
allLabelsM[*pair.Name] = *pair.Value
|
||||
}
|
||||
weighted, err := newWeightedHistogram(desc, WeightedHistogramOpts{
|
||||
Namespace: opts.Namespace,
|
||||
Subsystem: opts.Subsystem,
|
||||
Name: opts.Name,
|
||||
Help: opts.Help,
|
||||
ConstLabels: allLabelsM,
|
||||
Buckets: opts.Buckets,
|
||||
}, variableLabelValues...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &timingHistogram{
|
||||
nowFunc: nowFunc,
|
||||
weighted: weighted,
|
||||
lastSetTime: nowFunc(),
|
||||
value: opts.InitialValue,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type timingHistogram struct {
|
||||
nowFunc func() time.Time
|
||||
weighted *weightedHistogram
|
||||
|
||||
// The following fields must only be accessed with weighted's lock held
|
||||
|
||||
lastSetTime time.Time // identifies when value was last set
|
||||
value float64
|
||||
}
|
||||
|
||||
var _ TimingHistogram = &timingHistogram{}
|
||||
|
||||
func (th *timingHistogram) Set(newValue float64) {
|
||||
th.update(func(float64) float64 { return newValue })
|
||||
}
|
||||
|
||||
func (th *timingHistogram) Inc() {
|
||||
th.update(func(oldValue float64) float64 { return oldValue + 1 })
|
||||
}
|
||||
|
||||
func (th *timingHistogram) Dec() {
|
||||
th.update(func(oldValue float64) float64 { return oldValue - 1 })
|
||||
}
|
||||
|
||||
func (th *timingHistogram) Add(delta float64) {
|
||||
th.update(func(oldValue float64) float64 { return oldValue + delta })
|
||||
}
|
||||
|
||||
func (th *timingHistogram) Sub(delta float64) {
|
||||
th.update(func(oldValue float64) float64 { return oldValue - delta })
|
||||
}
|
||||
|
||||
func (th *timingHistogram) SetToCurrentTime() {
|
||||
th.update(func(oldValue float64) float64 { return th.nowFunc().Sub(time.Unix(0, 0)).Seconds() })
|
||||
}
|
||||
|
||||
func (th *timingHistogram) update(updateFn func(float64) float64) {
|
||||
th.weighted.lock.Lock()
|
||||
defer th.weighted.lock.Unlock()
|
||||
now := th.nowFunc()
|
||||
delta := now.Sub(th.lastSetTime)
|
||||
value := th.value
|
||||
if delta > 0 {
|
||||
th.weighted.observeWithWeightLocked(value, uint64(delta))
|
||||
th.lastSetTime = now
|
||||
}
|
||||
th.value = updateFn(value)
|
||||
}
|
||||
|
||||
func (th *timingHistogram) Desc() *prometheus.Desc {
|
||||
return th.weighted.Desc()
|
||||
}
|
||||
|
||||
func (th *timingHistogram) Write(dest *dto.Metric) error {
|
||||
th.Add(0) // account for time since last update
|
||||
return th.weighted.Write(dest)
|
||||
}
|
||||
|
||||
func (th *timingHistogram) Describe(ch chan<- *prometheus.Desc) {
|
||||
ch <- th.weighted.Desc()
|
||||
}
|
||||
|
||||
func (th *timingHistogram) Collect(ch chan<- prometheus.Metric) {
|
||||
ch <- th
|
||||
}
|
111
vendor/k8s.io/component-base/metrics/prometheusextension/timing_histogram_vec.go
generated
vendored
Normal file
111
vendor/k8s.io/component-base/metrics/prometheusextension/timing_histogram_vec.go
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
Copyright 2022 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 prometheusextension
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// GaugeVecOps is a bunch of Gauge that have the same
|
||||
// Desc and are distinguished by the values for their variable labels.
|
||||
type GaugeVecOps interface {
|
||||
GetMetricWith(prometheus.Labels) (GaugeOps, error)
|
||||
GetMetricWithLabelValues(lvs ...string) (GaugeOps, error)
|
||||
With(prometheus.Labels) GaugeOps
|
||||
WithLabelValues(...string) GaugeOps
|
||||
CurryWith(prometheus.Labels) (GaugeVecOps, error)
|
||||
MustCurryWith(prometheus.Labels) GaugeVecOps
|
||||
}
|
||||
|
||||
type TimingHistogramVec struct {
|
||||
*prometheus.MetricVec
|
||||
}
|
||||
|
||||
var _ GaugeVecOps = &TimingHistogramVec{}
|
||||
var _ prometheus.Collector = &TimingHistogramVec{}
|
||||
|
||||
func NewTimingHistogramVec(opts TimingHistogramOpts, labelNames ...string) *TimingHistogramVec {
|
||||
return NewTestableTimingHistogramVec(time.Now, opts, labelNames...)
|
||||
}
|
||||
|
||||
func NewTestableTimingHistogramVec(nowFunc func() time.Time, opts TimingHistogramOpts, labelNames ...string) *TimingHistogramVec {
|
||||
desc := prometheus.NewDesc(
|
||||
prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
||||
wrapTimingHelp(opts.Help),
|
||||
labelNames,
|
||||
opts.ConstLabels,
|
||||
)
|
||||
return &TimingHistogramVec{
|
||||
MetricVec: prometheus.NewMetricVec(desc, func(lvs ...string) prometheus.Metric {
|
||||
metric, err := newTimingHistogram(nowFunc, desc, opts, lvs...)
|
||||
if err != nil {
|
||||
panic(err) // like in prometheus.newHistogram
|
||||
}
|
||||
return metric
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
func (hv *TimingHistogramVec) GetMetricWith(labels prometheus.Labels) (GaugeOps, error) {
|
||||
metric, err := hv.MetricVec.GetMetricWith(labels)
|
||||
if metric != nil {
|
||||
return metric.(GaugeOps), err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (hv *TimingHistogramVec) GetMetricWithLabelValues(lvs ...string) (GaugeOps, error) {
|
||||
metric, err := hv.MetricVec.GetMetricWithLabelValues(lvs...)
|
||||
if metric != nil {
|
||||
return metric.(GaugeOps), err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (hv *TimingHistogramVec) With(labels prometheus.Labels) GaugeOps {
|
||||
h, err := hv.GetMetricWith(labels)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func (hv *TimingHistogramVec) WithLabelValues(lvs ...string) GaugeOps {
|
||||
h, err := hv.GetMetricWithLabelValues(lvs...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func (hv *TimingHistogramVec) CurryWith(labels prometheus.Labels) (GaugeVecOps, error) {
|
||||
vec, err := hv.MetricVec.CurryWith(labels)
|
||||
if vec != nil {
|
||||
return &TimingHistogramVec{MetricVec: vec}, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (hv *TimingHistogramVec) MustCurryWith(labels prometheus.Labels) GaugeVecOps {
|
||||
vec, err := hv.CurryWith(labels)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return vec
|
||||
}
|
203
vendor/k8s.io/component-base/metrics/prometheusextension/weighted_histogram.go
generated
vendored
Normal file
203
vendor/k8s.io/component-base/metrics/prometheusextension/weighted_histogram.go
generated
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright 2022 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 prometheusextension
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
)
|
||||
|
||||
// WeightedHistogram generalizes Histogram: each observation has
|
||||
// an associated _weight_. For a given `x` and `N`,
|
||||
// `1` call on `ObserveWithWeight(x, N)` has the same meaning as
|
||||
// `N` calls on `ObserveWithWeight(x, 1)`.
|
||||
// The weighted sum might differ slightly due to the use of
|
||||
// floating point, although the implementation takes some steps
|
||||
// to mitigate that.
|
||||
// If every weight were 1,
|
||||
// this would be the same as the existing Histogram abstraction.
|
||||
type WeightedHistogram interface {
|
||||
prometheus.Metric
|
||||
prometheus.Collector
|
||||
WeightedObserver
|
||||
}
|
||||
|
||||
// WeightedObserver generalizes the Observer interface.
|
||||
type WeightedObserver interface {
|
||||
// Set the variable to the given value with the given weight.
|
||||
ObserveWithWeight(value float64, weight uint64)
|
||||
}
|
||||
|
||||
// WeightedHistogramOpts is the same as for an ordinary Histogram
|
||||
type WeightedHistogramOpts = prometheus.HistogramOpts
|
||||
|
||||
// NewWeightedHistogram creates a new WeightedHistogram
|
||||
func NewWeightedHistogram(opts WeightedHistogramOpts) (WeightedHistogram, error) {
|
||||
desc := prometheus.NewDesc(
|
||||
prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
||||
wrapWeightedHelp(opts.Help),
|
||||
nil,
|
||||
opts.ConstLabels,
|
||||
)
|
||||
return newWeightedHistogram(desc, opts)
|
||||
}
|
||||
|
||||
func wrapWeightedHelp(given string) string {
|
||||
return "EXPERIMENTAL: " + given
|
||||
}
|
||||
|
||||
func newWeightedHistogram(desc *prometheus.Desc, opts WeightedHistogramOpts, variableLabelValues ...string) (*weightedHistogram, error) {
|
||||
if len(opts.Buckets) == 0 {
|
||||
opts.Buckets = prometheus.DefBuckets
|
||||
}
|
||||
|
||||
for i, upperBound := range opts.Buckets {
|
||||
if i < len(opts.Buckets)-1 {
|
||||
if upperBound >= opts.Buckets[i+1] {
|
||||
return nil, fmt.Errorf(
|
||||
"histogram buckets must be in increasing order: %f >= %f",
|
||||
upperBound, opts.Buckets[i+1],
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if math.IsInf(upperBound, +1) {
|
||||
// The +Inf bucket is implicit. Remove it here.
|
||||
opts.Buckets = opts.Buckets[:i]
|
||||
}
|
||||
}
|
||||
}
|
||||
upperBounds := make([]float64, len(opts.Buckets))
|
||||
copy(upperBounds, opts.Buckets)
|
||||
|
||||
return &weightedHistogram{
|
||||
desc: desc,
|
||||
variableLabelValues: variableLabelValues,
|
||||
upperBounds: upperBounds,
|
||||
buckets: make([]uint64, len(upperBounds)+1),
|
||||
hotCount: initialHotCount,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type weightedHistogram struct {
|
||||
desc *prometheus.Desc
|
||||
variableLabelValues []string
|
||||
upperBounds []float64 // exclusive of +Inf
|
||||
|
||||
lock sync.Mutex // applies to all the following
|
||||
|
||||
// buckets is longer by one than upperBounds.
|
||||
// For 0 <= idx < len(upperBounds), buckets[idx] holds the
|
||||
// accumulated time.Duration that value has been <=
|
||||
// upperBounds[idx] but not <= upperBounds[idx-1].
|
||||
// buckets[len(upperBounds)] holds the accumulated
|
||||
// time.Duration when value fit in no other bucket.
|
||||
buckets []uint64
|
||||
|
||||
// sumHot + sumCold is the weighted sum of value.
|
||||
// Rather than risk loss of precision in one
|
||||
// float64, we do this sum hierarchically. Many successive
|
||||
// increments are added into sumHot; once in a while
|
||||
// the magnitude of sumHot is compared to the magnitude
|
||||
// of sumCold and, if the ratio is high enough,
|
||||
// sumHot is transferred into sumCold.
|
||||
sumHot float64
|
||||
sumCold float64
|
||||
|
||||
transferThreshold float64 // = math.Abs(sumCold) / 2^26 (that's about half of the bits of precision in a float64)
|
||||
|
||||
// hotCount is used to decide when to consider dumping sumHot into sumCold.
|
||||
// hotCount counts upward from initialHotCount to zero.
|
||||
hotCount int
|
||||
}
|
||||
|
||||
// initialHotCount is the negative of the number of terms
|
||||
// that are summed into sumHot before considering whether
|
||||
// to transfer to sumCold. This only has to be big enough
|
||||
// to make the extra floating point operations occur in a
|
||||
// distinct minority of cases.
|
||||
const initialHotCount = -15
|
||||
|
||||
var _ WeightedHistogram = &weightedHistogram{}
|
||||
var _ prometheus.Metric = &weightedHistogram{}
|
||||
var _ prometheus.Collector = &weightedHistogram{}
|
||||
|
||||
func (sh *weightedHistogram) ObserveWithWeight(value float64, weight uint64) {
|
||||
idx := sort.SearchFloat64s(sh.upperBounds, value)
|
||||
sh.lock.Lock()
|
||||
defer sh.lock.Unlock()
|
||||
sh.updateLocked(idx, value, weight)
|
||||
}
|
||||
|
||||
func (sh *weightedHistogram) observeWithWeightLocked(value float64, weight uint64) {
|
||||
idx := sort.SearchFloat64s(sh.upperBounds, value)
|
||||
sh.updateLocked(idx, value, weight)
|
||||
}
|
||||
|
||||
func (sh *weightedHistogram) updateLocked(idx int, value float64, weight uint64) {
|
||||
sh.buckets[idx] += weight
|
||||
newSumHot := sh.sumHot + float64(weight)*value
|
||||
sh.hotCount++
|
||||
if sh.hotCount >= 0 {
|
||||
sh.hotCount = initialHotCount
|
||||
if math.Abs(newSumHot) > sh.transferThreshold {
|
||||
newSumCold := sh.sumCold + newSumHot
|
||||
sh.sumCold = newSumCold
|
||||
sh.transferThreshold = math.Abs(newSumCold / 67108864)
|
||||
sh.sumHot = 0
|
||||
return
|
||||
}
|
||||
}
|
||||
sh.sumHot = newSumHot
|
||||
}
|
||||
|
||||
func (sh *weightedHistogram) Desc() *prometheus.Desc {
|
||||
return sh.desc
|
||||
}
|
||||
|
||||
func (sh *weightedHistogram) Write(dest *dto.Metric) error {
|
||||
count, sum, buckets := func() (uint64, float64, map[float64]uint64) {
|
||||
sh.lock.Lock()
|
||||
defer sh.lock.Unlock()
|
||||
nBounds := len(sh.upperBounds)
|
||||
buckets := make(map[float64]uint64, nBounds)
|
||||
var count uint64
|
||||
for idx, upperBound := range sh.upperBounds {
|
||||
count += sh.buckets[idx]
|
||||
buckets[upperBound] = count
|
||||
}
|
||||
count += sh.buckets[nBounds]
|
||||
return count, sh.sumHot + sh.sumCold, buckets
|
||||
}()
|
||||
metric, err := prometheus.NewConstHistogram(sh.desc, count, sum, buckets, sh.variableLabelValues...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return metric.Write(dest)
|
||||
}
|
||||
|
||||
func (sh *weightedHistogram) Describe(ch chan<- *prometheus.Desc) {
|
||||
ch <- sh.desc
|
||||
}
|
||||
|
||||
func (sh *weightedHistogram) Collect(ch chan<- prometheus.Metric) {
|
||||
ch <- sh
|
||||
}
|
106
vendor/k8s.io/component-base/metrics/prometheusextension/weighted_histogram_vec.go
generated
vendored
Normal file
106
vendor/k8s.io/component-base/metrics/prometheusextension/weighted_histogram_vec.go
generated
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
Copyright 2022 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 prometheusextension
|
||||
|
||||
import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// WeightedObserverVec is a bunch of WeightedObservers that have the same
|
||||
// Desc and are distinguished by the values for their variable labels.
|
||||
type WeightedObserverVec interface {
|
||||
GetMetricWith(prometheus.Labels) (WeightedObserver, error)
|
||||
GetMetricWithLabelValues(lvs ...string) (WeightedObserver, error)
|
||||
With(prometheus.Labels) WeightedObserver
|
||||
WithLabelValues(...string) WeightedObserver
|
||||
CurryWith(prometheus.Labels) (WeightedObserverVec, error)
|
||||
MustCurryWith(prometheus.Labels) WeightedObserverVec
|
||||
}
|
||||
|
||||
// WeightedHistogramVec implements WeightedObserverVec
|
||||
type WeightedHistogramVec struct {
|
||||
*prometheus.MetricVec
|
||||
}
|
||||
|
||||
var _ WeightedObserverVec = &WeightedHistogramVec{}
|
||||
var _ prometheus.Collector = &WeightedHistogramVec{}
|
||||
|
||||
func NewWeightedHistogramVec(opts WeightedHistogramOpts, labelNames ...string) *WeightedHistogramVec {
|
||||
desc := prometheus.NewDesc(
|
||||
prometheus.BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
|
||||
wrapWeightedHelp(opts.Help),
|
||||
labelNames,
|
||||
opts.ConstLabels,
|
||||
)
|
||||
return &WeightedHistogramVec{
|
||||
MetricVec: prometheus.NewMetricVec(desc, func(lvs ...string) prometheus.Metric {
|
||||
metric, err := newWeightedHistogram(desc, opts, lvs...)
|
||||
if err != nil {
|
||||
panic(err) // like in prometheus.newHistogram
|
||||
}
|
||||
return metric
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
func (hv *WeightedHistogramVec) GetMetricWith(labels prometheus.Labels) (WeightedObserver, error) {
|
||||
metric, err := hv.MetricVec.GetMetricWith(labels)
|
||||
if metric != nil {
|
||||
return metric.(WeightedObserver), err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (hv *WeightedHistogramVec) GetMetricWithLabelValues(lvs ...string) (WeightedObserver, error) {
|
||||
metric, err := hv.MetricVec.GetMetricWithLabelValues(lvs...)
|
||||
if metric != nil {
|
||||
return metric.(WeightedObserver), err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (hv *WeightedHistogramVec) With(labels prometheus.Labels) WeightedObserver {
|
||||
h, err := hv.GetMetricWith(labels)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func (hv *WeightedHistogramVec) WithLabelValues(lvs ...string) WeightedObserver {
|
||||
h, err := hv.GetMetricWithLabelValues(lvs...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func (hv *WeightedHistogramVec) CurryWith(labels prometheus.Labels) (WeightedObserverVec, error) {
|
||||
vec, err := hv.MetricVec.CurryWith(labels)
|
||||
if vec != nil {
|
||||
return &WeightedHistogramVec{MetricVec: vec}, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (hv *WeightedHistogramVec) MustCurryWith(labels prometheus.Labels) WeightedObserverVec {
|
||||
vec, err := hv.CurryWith(labels)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return vec
|
||||
}
|
20
vendor/k8s.io/component-base/metrics/summary.go
generated
vendored
20
vendor/k8s.io/component-base/metrics/summary.go
generated
vendored
@ -18,10 +18,17 @@ package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
DefAgeBuckets = prometheus.DefAgeBuckets
|
||||
DefBufCap = prometheus.DefBufCap
|
||||
DefMaxAge = prometheus.DefMaxAge
|
||||
)
|
||||
|
||||
// Summary is our internal representation for our wrapping struct around prometheus
|
||||
// summaries. Summary implements both kubeCollector and ObserverMetric
|
||||
//
|
||||
@ -93,7 +100,9 @@ type SummaryVec struct {
|
||||
|
||||
// NewSummaryVec returns an object which satisfies kubeCollector and wraps the
|
||||
// prometheus.SummaryVec object. However, the object returned will not measure
|
||||
// anything unless the collector is first registered, since the metric is lazily instantiated.
|
||||
// anything unless the collector is first registered, since the metric is lazily instantiated,
|
||||
// and only members extracted after
|
||||
// registration will actually measure anything.
|
||||
//
|
||||
// DEPRECATED: as per the metrics overhaul KEP
|
||||
func NewSummaryVec(opts *SummaryOpts, labels []string) *SummaryVec {
|
||||
@ -130,13 +139,16 @@ func (v *SummaryVec) initializeDeprecatedMetric() {
|
||||
v.initializeMetric()
|
||||
}
|
||||
|
||||
// Default Prometheus behavior actually results in the creation of a new metric
|
||||
// if a metric with the unique label values is not found in the underlying stored metricMap.
|
||||
// Default Prometheus Vec behavior is that member extraction results in creation of a new element
|
||||
// if one with the unique label values is not found in the underlying stored metricMap.
|
||||
// This means that if this function is called but the underlying metric is not registered
|
||||
// (which means it will never be exposed externally nor consumed), the metric will exist in memory
|
||||
// for perpetuity (i.e. throughout application lifecycle).
|
||||
//
|
||||
// For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/summary.go#L485-L495
|
||||
// For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/histogram.go#L460-L470
|
||||
//
|
||||
// In contrast, the Vec behavior in this package is that member extraction before registration
|
||||
// returns a permanent noop object.
|
||||
|
||||
// WithLabelValues returns the ObserverMetric for the given slice of label
|
||||
// values (same order as the VariableLabels in Desc). If that combination of
|
||||
|
267
vendor/k8s.io/component-base/metrics/timing_histogram.go
generated
vendored
Normal file
267
vendor/k8s.io/component-base/metrics/timing_histogram.go
generated
vendored
Normal file
@ -0,0 +1,267 @@
|
||||
/*
|
||||
Copyright 2019 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 metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
promext "k8s.io/component-base/metrics/prometheusextension"
|
||||
)
|
||||
|
||||
// PrometheusTimingHistogram is the abstraction of the underlying histogram
|
||||
// that we want to promote from the wrapper.
|
||||
type PrometheusTimingHistogram interface {
|
||||
GaugeMetric
|
||||
}
|
||||
|
||||
// TimingHistogram is our internal representation for our wrapping struct around
|
||||
// timing histograms. It implements both kubeCollector and GaugeMetric
|
||||
type TimingHistogram struct {
|
||||
PrometheusTimingHistogram
|
||||
*TimingHistogramOpts
|
||||
nowFunc func() time.Time
|
||||
lazyMetric
|
||||
selfCollector
|
||||
}
|
||||
|
||||
var _ GaugeMetric = &TimingHistogram{}
|
||||
var _ Registerable = &TimingHistogram{}
|
||||
var _ kubeCollector = &TimingHistogram{}
|
||||
|
||||
// NewTimingHistogram returns an object which is TimingHistogram-like. However, nothing
|
||||
// will be measured until the histogram is registered somewhere.
|
||||
func NewTimingHistogram(opts *TimingHistogramOpts) *TimingHistogram {
|
||||
return NewTestableTimingHistogram(time.Now, opts)
|
||||
}
|
||||
|
||||
// NewTestableTimingHistogram adds injection of the clock
|
||||
func NewTestableTimingHistogram(nowFunc func() time.Time, opts *TimingHistogramOpts) *TimingHistogram {
|
||||
opts.StabilityLevel.setDefaults()
|
||||
|
||||
h := &TimingHistogram{
|
||||
TimingHistogramOpts: opts,
|
||||
nowFunc: nowFunc,
|
||||
lazyMetric: lazyMetric{},
|
||||
}
|
||||
h.setPrometheusHistogram(noopMetric{})
|
||||
h.lazyInit(h, BuildFQName(opts.Namespace, opts.Subsystem, opts.Name))
|
||||
return h
|
||||
}
|
||||
|
||||
// setPrometheusHistogram sets the underlying KubeGauge object, i.e. the thing that does the measurement.
|
||||
func (h *TimingHistogram) setPrometheusHistogram(histogram promext.TimingHistogram) {
|
||||
h.PrometheusTimingHistogram = histogram
|
||||
h.initSelfCollection(histogram)
|
||||
}
|
||||
|
||||
// DeprecatedVersion returns a pointer to the Version or nil
|
||||
func (h *TimingHistogram) DeprecatedVersion() *semver.Version {
|
||||
return parseSemver(h.TimingHistogramOpts.DeprecatedVersion)
|
||||
}
|
||||
|
||||
// initializeMetric invokes the actual prometheus.Histogram object instantiation
|
||||
// and stores a reference to it
|
||||
func (h *TimingHistogram) initializeMetric() {
|
||||
h.TimingHistogramOpts.annotateStabilityLevel()
|
||||
// this actually creates the underlying prometheus gauge.
|
||||
histogram, err := promext.NewTestableTimingHistogram(h.nowFunc, h.TimingHistogramOpts.toPromHistogramOpts())
|
||||
if err != nil {
|
||||
panic(err) // handle as for regular histograms
|
||||
}
|
||||
h.setPrometheusHistogram(histogram)
|
||||
}
|
||||
|
||||
// initializeDeprecatedMetric invokes the actual prometheus.Histogram object instantiation
|
||||
// but modifies the Help description prior to object instantiation.
|
||||
func (h *TimingHistogram) initializeDeprecatedMetric() {
|
||||
h.TimingHistogramOpts.markDeprecated()
|
||||
h.initializeMetric()
|
||||
}
|
||||
|
||||
// WithContext allows the normal TimingHistogram metric to pass in context. The context is no-op now.
|
||||
func (h *TimingHistogram) WithContext(ctx context.Context) GaugeMetric {
|
||||
return h.PrometheusTimingHistogram
|
||||
}
|
||||
|
||||
// TimingHistogramVec is the internal representation of our wrapping struct around prometheus
|
||||
// TimingHistogramVecs.
|
||||
type TimingHistogramVec struct {
|
||||
*promext.TimingHistogramVec
|
||||
*TimingHistogramOpts
|
||||
nowFunc func() time.Time
|
||||
lazyMetric
|
||||
originalLabels []string
|
||||
}
|
||||
|
||||
var _ GaugeVecMetric = &TimingHistogramVec{}
|
||||
var _ Registerable = &TimingHistogramVec{}
|
||||
var _ kubeCollector = &TimingHistogramVec{}
|
||||
|
||||
// NewTimingHistogramVec returns an object which satisfies the kubeCollector, Registerable, and GaugeVecMetric interfaces
|
||||
// and wraps an underlying promext.TimingHistogramVec object. Note well the way that
|
||||
// behavior depends on registration and whether this is hidden.
|
||||
func NewTimingHistogramVec(opts *TimingHistogramOpts, labels []string) *TimingHistogramVec {
|
||||
return NewTestableTimingHistogramVec(time.Now, opts, labels)
|
||||
}
|
||||
|
||||
// NewTestableTimingHistogramVec adds injection of the clock.
|
||||
func NewTestableTimingHistogramVec(nowFunc func() time.Time, opts *TimingHistogramOpts, labels []string) *TimingHistogramVec {
|
||||
opts.StabilityLevel.setDefaults()
|
||||
|
||||
fqName := BuildFQName(opts.Namespace, opts.Subsystem, opts.Name)
|
||||
allowListLock.RLock()
|
||||
if allowList, ok := labelValueAllowLists[fqName]; ok {
|
||||
opts.LabelValueAllowLists = allowList
|
||||
}
|
||||
allowListLock.RUnlock()
|
||||
|
||||
v := &TimingHistogramVec{
|
||||
TimingHistogramVec: noopTimingHistogramVec,
|
||||
TimingHistogramOpts: opts,
|
||||
nowFunc: nowFunc,
|
||||
originalLabels: labels,
|
||||
lazyMetric: lazyMetric{},
|
||||
}
|
||||
v.lazyInit(v, fqName)
|
||||
return v
|
||||
}
|
||||
|
||||
// DeprecatedVersion returns a pointer to the Version or nil
|
||||
func (v *TimingHistogramVec) DeprecatedVersion() *semver.Version {
|
||||
return parseSemver(v.TimingHistogramOpts.DeprecatedVersion)
|
||||
}
|
||||
|
||||
func (v *TimingHistogramVec) initializeMetric() {
|
||||
v.TimingHistogramOpts.annotateStabilityLevel()
|
||||
v.TimingHistogramVec = promext.NewTestableTimingHistogramVec(v.nowFunc, v.TimingHistogramOpts.toPromHistogramOpts(), v.originalLabels...)
|
||||
}
|
||||
|
||||
func (v *TimingHistogramVec) initializeDeprecatedMetric() {
|
||||
v.TimingHistogramOpts.markDeprecated()
|
||||
v.initializeMetric()
|
||||
}
|
||||
|
||||
// WithLabelValuesChecked, if called before this vector has been registered in
|
||||
// at least one registry, will return a noop gauge and
|
||||
// an error that passes ErrIsNotRegistered.
|
||||
// If called on a hidden vector,
|
||||
// will return a noop gauge and a nil error.
|
||||
// If called with a syntactic problem in the labels, will
|
||||
// return a noop gauge and an error about the labels.
|
||||
// If none of the above apply, this method will return
|
||||
// the appropriate vector member and a nil error.
|
||||
func (v *TimingHistogramVec) WithLabelValuesChecked(lvs ...string) (GaugeMetric, error) {
|
||||
if !v.IsCreated() {
|
||||
if v.IsHidden() {
|
||||
return noop, nil
|
||||
}
|
||||
return noop, errNotRegistered
|
||||
}
|
||||
if v.LabelValueAllowLists != nil {
|
||||
v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs)
|
||||
}
|
||||
ops, err := v.TimingHistogramVec.GetMetricWithLabelValues(lvs...)
|
||||
return ops.(GaugeMetric), err
|
||||
}
|
||||
|
||||
// WithLabelValues calls WithLabelValuesChecked
|
||||
// and handles errors as follows.
|
||||
// An error that passes ErrIsNotRegistered is ignored
|
||||
// and the noop gauge is returned;
|
||||
// all other errors cause a panic.
|
||||
func (v *TimingHistogramVec) WithLabelValues(lvs ...string) GaugeMetric {
|
||||
ans, err := v.WithLabelValuesChecked(lvs...)
|
||||
if err == nil || ErrIsNotRegistered(err) {
|
||||
return ans
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// WithChecked, if called before this vector has been registered in
|
||||
// at least one registry, will return a noop gauge and
|
||||
// an error that passes ErrIsNotRegistered.
|
||||
// If called on a hidden vector,
|
||||
// will return a noop gauge and a nil error.
|
||||
// If called with a syntactic problem in the labels, will
|
||||
// return a noop gauge and an error about the labels.
|
||||
// If none of the above apply, this method will return
|
||||
// the appropriate vector member and a nil error.
|
||||
func (v *TimingHistogramVec) WithChecked(labels map[string]string) (GaugeMetric, error) {
|
||||
if !v.IsCreated() {
|
||||
if v.IsHidden() {
|
||||
return noop, nil
|
||||
}
|
||||
return noop, errNotRegistered
|
||||
}
|
||||
if v.LabelValueAllowLists != nil {
|
||||
v.LabelValueAllowLists.ConstrainLabelMap(labels)
|
||||
}
|
||||
ops, err := v.TimingHistogramVec.GetMetricWith(labels)
|
||||
return ops.(GaugeMetric), err
|
||||
}
|
||||
|
||||
// With calls WithChecked and handles errors as follows.
|
||||
// An error that passes ErrIsNotRegistered is ignored
|
||||
// and the noop gauge is returned;
|
||||
// all other errors cause a panic.
|
||||
func (v *TimingHistogramVec) With(labels map[string]string) GaugeMetric {
|
||||
ans, err := v.WithChecked(labels)
|
||||
if err == nil || ErrIsNotRegistered(err) {
|
||||
return ans
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Delete deletes the metric where the variable labels are the same as those
|
||||
// passed in as labels. It returns true if a metric was deleted.
|
||||
//
|
||||
// It is not an error if the number and names of the Labels are inconsistent
|
||||
// with those of the VariableLabels in Desc. However, such inconsistent Labels
|
||||
// can never match an actual metric, so the method will always return false in
|
||||
// that case.
|
||||
func (v *TimingHistogramVec) Delete(labels map[string]string) bool {
|
||||
if !v.IsCreated() {
|
||||
return false // since we haven't created the metric, we haven't deleted a metric with the passed in values
|
||||
}
|
||||
return v.TimingHistogramVec.Delete(labels)
|
||||
}
|
||||
|
||||
// Reset deletes all metrics in this vector.
|
||||
func (v *TimingHistogramVec) Reset() {
|
||||
if !v.IsCreated() {
|
||||
return
|
||||
}
|
||||
|
||||
v.TimingHistogramVec.Reset()
|
||||
}
|
||||
|
||||
// WithContext returns wrapped TimingHistogramVec with context
|
||||
func (v *TimingHistogramVec) InterfaceWithContext(ctx context.Context) GaugeVecMetric {
|
||||
return &TimingHistogramVecWithContext{
|
||||
ctx: ctx,
|
||||
TimingHistogramVec: v,
|
||||
}
|
||||
}
|
||||
|
||||
// TimingHistogramVecWithContext is the wrapper of TimingHistogramVec with context.
|
||||
// Currently the context is ignored.
|
||||
type TimingHistogramVecWithContext struct {
|
||||
*TimingHistogramVec
|
||||
ctx context.Context
|
||||
}
|
3
vendor/k8s.io/component-base/metrics/value.go
generated
vendored
3
vendor/k8s.io/component-base/metrics/value.go
generated
vendored
@ -50,7 +50,8 @@ func NewLazyConstMetric(desc *Desc, valueType ValueType, value float64, labelVal
|
||||
// NewLazyMetricWithTimestamp is a helper of NewMetricWithTimestamp.
|
||||
//
|
||||
// Warning: the Metric 'm' must be the one created by NewLazyConstMetric(),
|
||||
// otherwise, no stability guarantees would be offered.
|
||||
//
|
||||
// otherwise, no stability guarantees would be offered.
|
||||
func NewLazyMetricWithTimestamp(t time.Time, m Metric) Metric {
|
||||
if m == nil {
|
||||
return nil
|
||||
|
66
vendor/k8s.io/component-base/metrics/wrappers.go
generated
vendored
66
vendor/k8s.io/component-base/metrics/wrappers.go
generated
vendored
@ -17,6 +17,8 @@ limitations under the License.
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
)
|
||||
@ -65,6 +67,64 @@ type GaugeMetric interface {
|
||||
SetToCurrentTime()
|
||||
}
|
||||
|
||||
// GaugeVecMetric is a collection of Gauges that differ only in label values.
|
||||
type GaugeVecMetric interface {
|
||||
// Default Prometheus Vec behavior is that member extraction results in creation of a new element
|
||||
// if one with the unique label values is not found in the underlying stored metricMap.
|
||||
// This means that if this function is called but the underlying metric is not registered
|
||||
// (which means it will never be exposed externally nor consumed), the metric would exist in memory
|
||||
// for perpetuity (i.e. throughout application lifecycle).
|
||||
//
|
||||
// For reference: https://github.com/prometheus/client_golang/blob/v0.9.2/prometheus/gauge.go#L190-L208
|
||||
//
|
||||
// In contrast, the Vec behavior in this package is that member extraction before registration
|
||||
// returns a permanent noop object.
|
||||
|
||||
// WithLabelValuesChecked, if called before this vector has been registered in
|
||||
// at least one registry, will return a noop gauge and
|
||||
// an error that passes ErrIsNotRegistered.
|
||||
// If called on a hidden vector,
|
||||
// will return a noop gauge and a nil error.
|
||||
// If called with a syntactic problem in the labels, will
|
||||
// return a noop gauge and an error about the labels.
|
||||
// If none of the above apply, this method will return
|
||||
// the appropriate vector member and a nil error.
|
||||
WithLabelValuesChecked(labelValues ...string) (GaugeMetric, error)
|
||||
|
||||
// WithLabelValues calls WithLabelValuesChecked
|
||||
// and handles errors as follows.
|
||||
// An error that passes ErrIsNotRegistered is ignored
|
||||
// and the noop gauge is returned;
|
||||
// all other errors cause a panic.
|
||||
WithLabelValues(labelValues ...string) GaugeMetric
|
||||
|
||||
// WithChecked, if called before this vector has been registered in
|
||||
// at least one registry, will return a noop gauge and
|
||||
// an error that passes ErrIsNotRegistered.
|
||||
// If called on a hidden vector,
|
||||
// will return a noop gauge and a nil error.
|
||||
// If called with a syntactic problem in the labels, will
|
||||
// return a noop gauge and an error about the labels.
|
||||
// If none of the above apply, this method will return
|
||||
// the appropriate vector member and a nil error.
|
||||
WithChecked(labels map[string]string) (GaugeMetric, error)
|
||||
|
||||
// With calls WithChecked and handles errors as follows.
|
||||
// An error that passes ErrIsNotRegistered is ignored
|
||||
// and the noop gauge is returned;
|
||||
// all other errors cause a panic.
|
||||
With(labels map[string]string) GaugeMetric
|
||||
|
||||
// Delete asserts that the vec should have no member for the given label set.
|
||||
// The returned bool indicates whether there was a change.
|
||||
// The return will certainly be `false` if the given label set has the wrong
|
||||
// set of label names.
|
||||
Delete(map[string]string) bool
|
||||
|
||||
// Reset removes all the members
|
||||
Reset()
|
||||
}
|
||||
|
||||
// ObserverMetric captures individual observations.
|
||||
type ObserverMetric interface {
|
||||
Observe(float64)
|
||||
@ -93,3 +153,9 @@ type GaugeFunc interface {
|
||||
Metric
|
||||
Collector
|
||||
}
|
||||
|
||||
func ErrIsNotRegistered(err error) bool {
|
||||
return err == errNotRegistered
|
||||
}
|
||||
|
||||
var errNotRegistered = errors.New("metric vec is not registered yet")
|
||||
|
80
vendor/k8s.io/component-base/traces/utils.go
generated
vendored
80
vendor/k8s.io/component-base/traces/utils.go
generated
vendored
@ -1,80 +0,0 @@
|
||||
/*
|
||||
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 traces
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"go.opentelemetry.io/otel/exporters/otlp"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlpgrpc"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"k8s.io/client-go/transport"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// NewProvider initializes tracing in the component, and enforces recommended tracing behavior.
|
||||
func NewProvider(ctx context.Context, baseSampler sdktrace.Sampler, resourceOpts []resource.Option, opts ...otlpgrpc.Option) trace.TracerProvider {
|
||||
opts = append(opts, otlpgrpc.WithInsecure())
|
||||
driver := otlpgrpc.NewDriver(opts...)
|
||||
exporter, err := otlp.NewExporter(ctx, driver)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to create OTLP exporter: %v", err)
|
||||
}
|
||||
|
||||
res, err := resource.New(ctx, resourceOpts...)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to create resource: %v", err)
|
||||
}
|
||||
|
||||
bsp := sdktrace.NewBatchSpanProcessor(exporter)
|
||||
|
||||
return sdktrace.NewTracerProvider(
|
||||
sdktrace.WithSampler(sdktrace.ParentBased(baseSampler)),
|
||||
sdktrace.WithSpanProcessor(bsp),
|
||||
sdktrace.WithResource(res),
|
||||
)
|
||||
}
|
||||
|
||||
// WrapperFor can be used to add tracing to a *rest.Config. Example usage:
|
||||
// tp := traces.NewProvider(...)
|
||||
// config, _ := rest.InClusterConfig()
|
||||
// config.Wrap(traces.WrapperFor(&tp))
|
||||
// kubeclient, _ := clientset.NewForConfig(config)
|
||||
func WrapperFor(tp *trace.TracerProvider) transport.WrapperFunc {
|
||||
return func(rt http.RoundTripper) http.RoundTripper {
|
||||
opts := []otelhttp.Option{
|
||||
otelhttp.WithPropagators(Propagators()),
|
||||
}
|
||||
if tp != nil {
|
||||
opts = append(opts, otelhttp.WithTracerProvider(*tp))
|
||||
}
|
||||
// Even if there is no TracerProvider, the otelhttp still handles context propagation.
|
||||
// See https://github.com/open-telemetry/opentelemetry-go/tree/main/example/passthrough
|
||||
return otelhttp.NewTransport(rt, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// Propagators returns the recommended set of propagators.
|
||||
func Propagators() propagation.TextMapPropagator {
|
||||
return propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})
|
||||
}
|
88
vendor/k8s.io/component-base/tracing/api/v1/config.go
generated
vendored
Normal file
88
vendor/k8s.io/component-base/tracing/api/v1/config.go
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/component-base/featuregate"
|
||||
)
|
||||
|
||||
var (
|
||||
maxSamplingRatePerMillion = int32(1000000)
|
||||
)
|
||||
|
||||
// ValidateTracingConfiguration validates the tracing configuration
|
||||
func ValidateTracingConfiguration(traceConfig *TracingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if traceConfig == nil {
|
||||
return allErrs
|
||||
}
|
||||
if traceConfig.SamplingRatePerMillion != nil {
|
||||
allErrs = append(allErrs, validateSamplingRate(*traceConfig.SamplingRatePerMillion, fldPath.Child("samplingRatePerMillion"))...)
|
||||
}
|
||||
if traceConfig.Endpoint != nil {
|
||||
allErrs = append(allErrs, validateEndpoint(*traceConfig.Endpoint, fldPath.Child("endpoint"))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateSamplingRate(rate int32, fldPath *field.Path) field.ErrorList {
|
||||
errs := field.ErrorList{}
|
||||
if rate < 0 {
|
||||
errs = append(errs, field.Invalid(
|
||||
fldPath, rate,
|
||||
"sampling rate must be positive",
|
||||
))
|
||||
}
|
||||
if rate > maxSamplingRatePerMillion {
|
||||
errs = append(errs, field.Invalid(
|
||||
fldPath, rate,
|
||||
"sampling rate per million must be less than or equal to one million",
|
||||
))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func validateEndpoint(endpoint string, fldPath *field.Path) field.ErrorList {
|
||||
errs := field.ErrorList{}
|
||||
if !strings.Contains(endpoint, "//") {
|
||||
endpoint = "dns://" + endpoint
|
||||
}
|
||||
url, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
errs = append(errs, field.Invalid(
|
||||
fldPath, endpoint,
|
||||
err.Error(),
|
||||
))
|
||||
return errs
|
||||
}
|
||||
switch url.Scheme {
|
||||
case "dns":
|
||||
case "unix":
|
||||
case "unix-abstract":
|
||||
default:
|
||||
errs = append(errs, field.Invalid(
|
||||
fldPath, endpoint,
|
||||
fmt.Sprintf("unsupported scheme: %v. Options are none, dns, unix, or unix-abstract. See https://github.com/grpc/grpc/blob/master/doc/naming.md", url.Scheme),
|
||||
))
|
||||
}
|
||||
return errs
|
||||
}
|
29
vendor/k8s.io/component-base/tracing/api/v1/doc.go
generated
vendored
Normal file
29
vendor/k8s.io/component-base/tracing/api/v1/doc.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2022 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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// Package v1 contains the configuration API for tracing.
|
||||
//
|
||||
// The intention is to only have a single version of this API, potentially with
|
||||
// new fields added over time in a backwards-compatible manner. Fields for
|
||||
// alpha or beta features are allowed as long as they are defined so that not
|
||||
// changing the defaults leaves those features disabled.
|
||||
//
|
||||
// The "v1" package name is just a reminder that API compatibility rules apply,
|
||||
// not an indication of the stability of all features covered by it.
|
||||
|
||||
package v1 // import "k8s.io/component-base/tracing/api/v1"
|
32
vendor/k8s.io/component-base/tracing/api/v1/types.go
generated
vendored
Normal file
32
vendor/k8s.io/component-base/tracing/api/v1/types.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright 2022 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 v1
|
||||
|
||||
// TracingConfiguration provides versioned configuration for OpenTelemetry tracing clients.
|
||||
type TracingConfiguration struct {
|
||||
// Endpoint of the collector this component will report traces to.
|
||||
// The connection is insecure, and does not currently support TLS.
|
||||
// Recommended is unset, and endpoint is the otlp grpc default, localhost:4317.
|
||||
// +optional
|
||||
Endpoint *string `json:"endpoint,omitempty"`
|
||||
|
||||
// SamplingRatePerMillion is the number of samples to collect per million spans.
|
||||
// Recommended is unset. If unset, sampler respects its parent span's sampling
|
||||
// rate, but otherwise never samples.
|
||||
// +optional
|
||||
SamplingRatePerMillion *int32 `json:"samplingRatePerMillion,omitempty"`
|
||||
}
|
48
vendor/k8s.io/component-base/tracing/api/v1/zz_generated.deepcopy.go
generated
vendored
Normal file
48
vendor/k8s.io/component-base/tracing/api/v1/zz_generated.deepcopy.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TracingConfiguration) DeepCopyInto(out *TracingConfiguration) {
|
||||
*out = *in
|
||||
if in.Endpoint != nil {
|
||||
in, out := &in.Endpoint, &out.Endpoint
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.SamplingRatePerMillion != nil {
|
||||
in, out := &in.SamplingRatePerMillion, &out.SamplingRatePerMillion
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TracingConfiguration.
|
||||
func (in *TracingConfiguration) DeepCopy() *TracingConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(TracingConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
108
vendor/k8s.io/component-base/tracing/utils.go
generated
vendored
Normal file
108
vendor/k8s.io/component-base/tracing/utils.go
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
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 tracing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"go.opentelemetry.io/otel/exporters/otlp"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlpgrpc"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
oteltrace "go.opentelemetry.io/otel/trace"
|
||||
|
||||
"k8s.io/client-go/transport"
|
||||
"k8s.io/component-base/tracing/api/v1"
|
||||
)
|
||||
|
||||
// NewProvider creates a TracerProvider in a component, and enforces recommended tracing behavior
|
||||
func NewProvider(ctx context.Context,
|
||||
tracingConfig *v1.TracingConfiguration,
|
||||
addedOpts []otlpgrpc.Option,
|
||||
resourceOpts []resource.Option,
|
||||
) (oteltrace.TracerProvider, error) {
|
||||
if tracingConfig == nil {
|
||||
return oteltrace.NewNoopTracerProvider(), nil
|
||||
}
|
||||
opts := append([]otlpgrpc.Option{}, addedOpts...)
|
||||
if tracingConfig.Endpoint != nil {
|
||||
opts = append(opts, otlpgrpc.WithEndpoint(*tracingConfig.Endpoint))
|
||||
}
|
||||
opts = append(opts, otlpgrpc.WithInsecure())
|
||||
driver := otlpgrpc.NewDriver(opts...)
|
||||
exporter, err := otlp.NewExporter(ctx, driver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, err := resource.New(ctx, resourceOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// sampler respects parent span's sampling rate or
|
||||
// otherwise never samples.
|
||||
sampler := sdktrace.NeverSample()
|
||||
// Or, emit spans for a fraction of transactions
|
||||
if tracingConfig.SamplingRatePerMillion != nil && *tracingConfig.SamplingRatePerMillion > 0 {
|
||||
sampler = sdktrace.TraceIDRatioBased(float64(*tracingConfig.SamplingRatePerMillion) / float64(1000000))
|
||||
}
|
||||
// batch span processor to aggregate spans before export.
|
||||
bsp := sdktrace.NewBatchSpanProcessor(exporter)
|
||||
tp := sdktrace.NewTracerProvider(
|
||||
sdktrace.WithSampler(sdktrace.ParentBased(sampler)),
|
||||
sdktrace.WithSpanProcessor(bsp),
|
||||
sdktrace.WithResource(res),
|
||||
)
|
||||
return tp, nil
|
||||
}
|
||||
|
||||
// WithTracing adds tracing to requests if the incoming request is sampled
|
||||
func WithTracing(handler http.Handler, tp oteltrace.TracerProvider, serviceName string) http.Handler {
|
||||
opts := []otelhttp.Option{
|
||||
otelhttp.WithPropagators(Propagators()),
|
||||
otelhttp.WithTracerProvider(tp),
|
||||
}
|
||||
// With Noop TracerProvider, the otelhttp still handles context propagation.
|
||||
// See https://github.com/open-telemetry/opentelemetry-go/tree/main/example/passthrough
|
||||
return otelhttp.NewHandler(handler, serviceName, opts...)
|
||||
}
|
||||
|
||||
// WrapperFor can be used to add tracing to a *rest.Config.
|
||||
// Example usage:
|
||||
// tp := NewProvider(...)
|
||||
// config, _ := rest.InClusterConfig()
|
||||
// config.Wrap(WrapperFor(&tp))
|
||||
// kubeclient, _ := clientset.NewForConfig(config)
|
||||
func WrapperFor(tp oteltrace.TracerProvider) transport.WrapperFunc {
|
||||
return func(rt http.RoundTripper) http.RoundTripper {
|
||||
opts := []otelhttp.Option{
|
||||
otelhttp.WithPropagators(Propagators()),
|
||||
otelhttp.WithTracerProvider(tp),
|
||||
}
|
||||
// With Noop TracerProvider, the otelhttp still handles context propagation.
|
||||
// See https://github.com/open-telemetry/opentelemetry-go/tree/main/example/passthrough
|
||||
return otelhttp.NewTransport(rt, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// Propagators returns the recommended set of propagators.
|
||||
func Propagators() propagation.TextMapPropagator {
|
||||
return propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})
|
||||
}
|
Reference in New Issue
Block a user