rebase: update kubernetes to 1.26.1

update kubernetes and its dependencies
to v1.26.1

Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
Madhu Rajanna
2023-02-01 18:06:36 +01:00
committed by mergify[bot]
parent e9e33fb851
commit 9c8de9471e
937 changed files with 75539 additions and 33050 deletions

View File

@ -17,6 +17,7 @@ limitations under the License.
package featuregate
import (
"context"
"fmt"
"sort"
"strconv"
@ -27,6 +28,7 @@ import (
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/util/naming"
featuremetrics "k8s.io/component-base/metrics/prometheus/feature"
"k8s.io/klog/v2"
)
@ -111,6 +113,8 @@ type MutableFeatureGate interface {
Add(features map[Feature]FeatureSpec) error
// GetAll returns a copy of the map of known feature names to feature specs.
GetAll() map[Feature]FeatureSpec
// AddMetrics adds feature enablement metrics
AddMetrics()
}
// featureGate implements FeatureGate as well as pflag.Value for flag parsing.
@ -329,6 +333,12 @@ func (f *featureGate) AddFlag(fs *pflag.FlagSet) {
"Options are:\n"+strings.Join(known, "\n"))
}
func (f *featureGate) AddMetrics() {
for feature, featureSpec := range f.GetAll() {
featuremetrics.RecordFeatureInfo(context.Background(), string(feature), string(featureSpec.PreRelease), f.Enabled(feature))
}
}
// KnownFeatures returns a slice of strings describing the FeatureGate's known features.
// Deprecated and GA features are hidden from the list.
func (f *featureGate) KnownFeatures() []string {

View File

@ -22,7 +22,7 @@ import (
const (
// owner: @pohly
// kep: http://kep.k8s.io/3077
// kep: https://kep.k8s.io/3077
// alpha: v1.24
//
// Enables looking up a logger from a context.Context instead of using

View File

@ -20,7 +20,6 @@ import (
"flag"
"fmt"
"math"
"sort"
"strings"
"time"
@ -32,6 +31,7 @@ import (
"k8s.io/apimachinery/pkg/util/validation/field"
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/component-base/featuregate"
"k8s.io/component-base/logs/klogflags"
)
const (
@ -183,12 +183,8 @@ func apply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error {
// 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))
fs.StringVar(&c.Format, "logging-format", c.Format, fmt.Sprintf("Sets the log format. Permitted formats: %s.", formats))
// No new log formats should be added after generation is of flag options
logRegistry.freeze()
@ -236,14 +232,13 @@ var loggingFlags pflag.FlagSet
func init() {
var fs flag.FlagSet
klog.InitFlags(&fs)
klogflags.Init(&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
@ -268,15 +263,3 @@ func unsupportedLoggingFlags(normalizeFunc func(f *pflag.FlagSet, name string) p
})
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
}

View File

@ -0,0 +1,41 @@
/*
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 klogflags
import (
"flag"
"k8s.io/klog/v2"
)
// Init is a replacement for klog.InitFlags which only adds those flags
// that are still supported for Kubernetes components (i.e. -v and -vmodule).
// See
// https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/2845-deprecate-klog-specific-flags-in-k8s-components.
func Init(fs *flag.FlagSet) {
var allFlags flag.FlagSet
klog.InitFlags(&allFlags)
if fs == nil {
fs = flag.CommandLine
}
allFlags.VisitAll(func(f *flag.Flag) {
switch f.Name {
case "v", "vmodule":
fs.Var(f.Value, f.Name, f.Usage)
}
})
}

43
vendor/k8s.io/component-base/metrics/buckets.go generated vendored Normal file
View File

@ -0,0 +1,43 @@
/*
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 metrics
import (
"github.com/prometheus/client_golang/prometheus"
)
// DefBuckets is a wrapper for prometheus.DefBuckets
var DefBuckets = prometheus.DefBuckets
// LinearBuckets is a wrapper for prometheus.LinearBuckets.
func LinearBuckets(start, width float64, count int) []float64 {
return prometheus.LinearBuckets(start, width, count)
}
// ExponentialBuckets is a wrapper for prometheus.ExponentialBuckets.
func ExponentialBuckets(start, factor float64, count int) []float64 {
return prometheus.ExponentialBuckets(start, factor, count)
}
// MergeBuckets merges buckets together
func MergeBuckets(buckets ...[]float64) []float64 {
result := make([]float64, 1)
for _, s := range buckets {
result = append(result, s...)
}
return result
}

View File

@ -45,9 +45,9 @@ type StableCollector interface {
HiddenMetrics() []string
}
// BaseStableCollector which implements almost all of the methods defined by StableCollector
// BaseStableCollector which implements almost all methods defined by StableCollector
// is a convenient assistant for custom collectors.
// It is recommend that inherit BaseStableCollector when implementing custom collectors.
// It is recommended to inherit BaseStableCollector when implementing custom collectors.
type BaseStableCollector struct {
descriptors map[string]*Desc // stores all descriptors by pair<fqName, Desc>, these are collected from DescribeWithStability().
registerable map[string]*Desc // stores registerable descriptors by pair<fqName, Desc>, is a subset of descriptors.
@ -62,7 +62,7 @@ func (bsc *BaseStableCollector) DescribeWithStability(ch chan<- *Desc) {
}
// Describe sends all descriptors to the provided channel.
// It intend to be called by prometheus registry.
// It intended to be called by prometheus registry.
func (bsc *BaseStableCollector) Describe(ch chan<- *prometheus.Desc) {
for _, d := range bsc.registerable {
ch <- d.toPrometheusDesc()

View File

@ -44,7 +44,7 @@ func NewCounter(opts *CounterOpts) *Counter {
kc := &Counter{
CounterOpts: opts,
lazyMetric: lazyMetric{},
lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel},
}
kc.setPrometheusCounter(noop)
kc.lazyInit(kc, BuildFQName(opts.Namespace, opts.Subsystem, opts.Name))
@ -129,7 +129,7 @@ func NewCounterVec(opts *CounterOpts, labels []string) *CounterVec {
CounterVec: noopCounterVec,
CounterOpts: opts,
originalLabels: labels,
lazyMetric: lazyMetric{},
lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel},
}
cv.lazyInit(cv, fqName)
return cv

View File

@ -46,7 +46,7 @@ func NewGauge(opts *GaugeOpts) *Gauge {
kc := &Gauge{
GaugeOpts: opts,
lazyMetric: lazyMetric{},
lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel},
}
kc.setPrometheusGauge(noop)
kc.lazyInit(kc, BuildFQName(opts.Namespace, opts.Subsystem, opts.Name))
@ -115,7 +115,7 @@ func NewGaugeVec(opts *GaugeOpts, labels []string) *GaugeVec {
GaugeVec: noopGaugeVec,
GaugeOpts: opts,
originalLabels: labels,
lazyMetric: lazyMetric{},
lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel},
}
cv.lazyInit(cv, fqName)
return cv

View File

@ -23,19 +23,6 @@ import (
"github.com/prometheus/client_golang/prometheus"
)
// DefBuckets is a wrapper for prometheus.DefBuckets
var DefBuckets = prometheus.DefBuckets
// LinearBuckets is a wrapper for prometheus.LinearBuckets.
func LinearBuckets(start, width float64, count int) []float64 {
return prometheus.LinearBuckets(start, width, count)
}
// ExponentialBuckets is a wrapper for prometheus.ExponentialBuckets.
func ExponentialBuckets(start, factor float64, count int) []float64 {
return prometheus.ExponentialBuckets(start, factor, count)
}
// Histogram is our internal representation for our wrapping struct around prometheus
// histograms. Summary implements both kubeCollector and ObserverMetric
type Histogram struct {
@ -52,7 +39,7 @@ func NewHistogram(opts *HistogramOpts) *Histogram {
h := &Histogram{
HistogramOpts: opts,
lazyMetric: lazyMetric{},
lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel},
}
h.setPrometheusHistogram(noopMetric{})
h.lazyInit(h, BuildFQName(opts.Namespace, opts.Subsystem, opts.Name))
@ -119,7 +106,7 @@ func NewHistogramVec(opts *HistogramOpts, labels []string) *HistogramVec {
HistogramVec: noopHistogramVec,
HistogramOpts: opts,
originalLabels: labels,
lazyMetric: lazyMetric{},
lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel},
}
v.lazyInit(v, fqName)
return v

View File

@ -20,6 +20,7 @@ import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
"github.com/prometheus/client_golang/prometheus/promhttp"
"k8s.io/component-base/metrics"
@ -44,10 +45,9 @@ var (
)
func init() {
//nolint:staticcheck // SA1019 - replacement function still calls prometheus.NewProcessCollector().
RawMustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}))
//nolint:staticcheck // SA1019 - replacement function still calls prometheus.NewGoCollector().
RawMustRegister(prometheus.NewGoCollector())
RawMustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}))
RawMustRegister(collectors.NewGoCollector(collectors.WithGoCollectorRuntimeMetrics(collectors.MetricsAll)))
defaultRegistry.RegisterMetaMetrics()
}
// Handler returns an HTTP handler for the DefaultGatherer. It is

View File

@ -72,6 +72,7 @@ type lazyMetric struct {
markDeprecationOnce sync.Once
createOnce sync.Once
self kubeCollector
stabilityLevel StabilityLevel
}
func (r *lazyMetric) IsCreated() bool {
@ -149,6 +150,7 @@ func (r *lazyMetric) Create(version *semver.Version) bool {
if r.IsHidden() {
return false
}
r.createOnce.Do(func() {
r.createLock.Lock()
defer r.createLock.Unlock()
@ -159,6 +161,13 @@ func (r *lazyMetric) Create(version *semver.Version) bool {
r.self.initializeMetric()
}
})
sl := r.stabilityLevel
deprecatedV := r.self.DeprecatedVersion()
dv := ""
if deprecatedV != nil {
dv = deprecatedV.String()
}
registeredMetrics.WithLabelValues(string(sl), dv).Inc()
return r.IsCreated()
}

View File

@ -66,9 +66,15 @@ func BuildFQName(namespace, subsystem, name string) string {
type StabilityLevel string
const (
// INTERNAL metrics have no stability guarantees, as such, labels may
// be arbitrarily added/removed and the metric may be deleted at any time.
INTERNAL StabilityLevel = "INTERNAL"
// ALPHA metrics have no stability guarantees, as such, labels may
// be arbitrarily added/removed and the metric may be deleted at any time.
ALPHA StabilityLevel = "ALPHA"
// BETA metrics are governed by the deprecation policy outlined in by
// the control plane metrics stability KEP.
BETA StabilityLevel = "BETA"
// STABLE metrics are guaranteed not be mutated and removal is governed by
// the deprecation policy outlined in by the control plane metrics stability KEP.
STABLE StabilityLevel = "STABLE"

View File

@ -0,0 +1,53 @@
/*
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 feature
import (
"context"
k8smetrics "k8s.io/component-base/metrics"
"k8s.io/component-base/metrics/legacyregistry"
)
var (
// featureInfo is a Prometheus Gauge metrics used for recording the enablement of a k8s feature.
featureInfo = k8smetrics.NewGaugeVec(
&k8smetrics.GaugeOpts{
Namespace: "kubernetes",
Name: "feature_enabled",
Help: "This metric records the data about the stage and enablement of a k8s feature.",
StabilityLevel: k8smetrics.ALPHA,
},
[]string{"name", "stage"},
)
)
func init() {
legacyregistry.MustRegister(featureInfo)
}
func ResetFeatureInfoMetric() {
featureInfo.Reset()
}
func RecordFeatureInfo(ctx context.Context, name string, stage string, enabled bool) {
value := 0.0
if enabled {
value = 1.0
}
featureInfo.WithContext(ctx).WithLabelValues(name, stage).Set(value)
}

View File

@ -32,10 +32,35 @@ import (
var (
showHiddenOnce sync.Once
disabledMetricsLock sync.RWMutex
showHidden atomic.Value
showHidden atomic.Bool
registries []*kubeRegistry // stores all registries created by NewKubeRegistry()
registriesLock sync.RWMutex
disabledMetrics = map[string]struct{}{}
registeredMetrics = NewCounterVec(
&CounterOpts{
Name: "registered_metric_total",
Help: "The count of registered metrics broken by stability level and deprecation version.",
StabilityLevel: ALPHA,
},
[]string{"stability_level", "deprecated_version"},
)
disabledMetricsTotal = NewCounter(
&CounterOpts{
Name: "disabled_metric_total",
Help: "The count of disabled metrics.",
StabilityLevel: ALPHA,
},
)
hiddenMetricsTotal = NewCounter(
&CounterOpts{
Name: "hidden_metric_total",
Help: "The count of hidden metrics.",
StabilityLevel: ALPHA,
},
)
)
// shouldHide be used to check if a specific metric with deprecated version should be hidden
@ -67,6 +92,7 @@ func SetDisabledMetric(name string) {
disabledMetricsLock.Lock()
defer disabledMetricsLock.Unlock()
disabledMetrics[name] = struct{}{}
disabledMetricsTotal.Inc()
}
// SetShowHidden will enable showing hidden metrics. This will no-opt
@ -87,7 +113,7 @@ func SetShowHidden() {
// is enabled. While the primary usecase for this is internal (to determine
// registration behavior) this can also be used to introspect
func ShouldShowHidden() bool {
return showHidden.Load() != nil && showHidden.Load().(bool)
return showHidden.Load()
}
// Registerable is an interface for a collector metric which we
@ -129,6 +155,12 @@ type KubeRegistry interface {
// Reset invokes the Reset() function on all items in the registry
// which are added as resettables.
Reset()
// RegisterMetaMetrics registers metrics about the number of registered metrics.
RegisterMetaMetrics()
// Registerer exposes the underlying prometheus registerer
Registerer() prometheus.Registerer
// Gatherer exposes the underlying prometheus gatherer
Gatherer() prometheus.Gatherer
}
// kubeRegistry is a wrapper around a prometheus registry-type object. Upon initialization
@ -160,6 +192,16 @@ func (kr *kubeRegistry) Register(c Registerable) error {
return nil
}
// Registerer exposes the underlying prometheus.Registerer
func (kr *kubeRegistry) Registerer() prometheus.Registerer {
return kr.PromRegistry
}
// Gatherer exposes the underlying prometheus.Gatherer
func (kr *kubeRegistry) Gatherer() prometheus.Gatherer {
return kr.PromRegistry
}
// MustRegister works like Register but registers any number of
// Collectors and panics upon the first registration that causes an
// error.
@ -250,6 +292,7 @@ func (kr *kubeRegistry) trackHiddenCollector(c Registerable) {
defer kr.hiddenCollectorsLock.Unlock()
kr.hiddenCollectors[c.FQName()] = c
hiddenMetricsTotal.Inc()
}
// trackStableCollectors stores all custom collectors.
@ -329,9 +372,14 @@ func newKubeRegistry(v apimachineryversion.Info) *kubeRegistry {
return r
}
// NewKubeRegistry creates a new vanilla Registry without any Collectors
// pre-registered.
// NewKubeRegistry creates a new vanilla Registry
func NewKubeRegistry() KubeRegistry {
r := newKubeRegistry(BuildVersion())
return r
}
func (r *kubeRegistry) RegisterMetaMetrics() {
r.MustRegister(registeredMetrics)
r.MustRegister(disabledMetricsTotal)
r.MustRegister(hiddenMetricsTotal)
}

View File

@ -49,7 +49,7 @@ func NewSummary(opts *SummaryOpts) *Summary {
s := &Summary{
SummaryOpts: opts,
lazyMetric: lazyMetric{},
lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel},
}
s.setPrometheusSummary(noopMetric{})
s.lazyInit(s, BuildFQName(opts.Namespace, opts.Subsystem, opts.Name))
@ -118,7 +118,7 @@ func NewSummaryVec(opts *SummaryOpts, labels []string) *SummaryVec {
v := &SummaryVec{
SummaryOpts: opts,
originalLabels: labels,
lazyMetric: lazyMetric{},
lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel},
}
v.lazyInit(v, fqName)
return v

View File

@ -57,7 +57,7 @@ func NewTestableTimingHistogram(nowFunc func() time.Time, opts *TimingHistogramO
h := &TimingHistogram{
TimingHistogramOpts: opts,
nowFunc: nowFunc,
lazyMetric: lazyMetric{},
lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel},
}
h.setPrometheusHistogram(noopMetric{})
h.lazyInit(h, BuildFQName(opts.Namespace, opts.Subsystem, opts.Name))
@ -136,7 +136,7 @@ func NewTestableTimingHistogramVec(nowFunc func() time.Time, opts *TimingHistogr
TimingHistogramOpts: opts,
nowFunc: nowFunc,
originalLabels: labels,
lazyMetric: lazyMetric{},
lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel},
}
v.lazyInit(v, fqName)
return v
@ -177,6 +177,9 @@ func (v *TimingHistogramVec) WithLabelValuesChecked(lvs ...string) (GaugeMetric,
v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs)
}
ops, err := v.TimingHistogramVec.GetMetricWithLabelValues(lvs...)
if err != nil {
return noop, err
}
return ops.(GaugeMetric), err
}

View File

@ -47,6 +47,16 @@ func NewLazyConstMetric(desc *Desc, valueType ValueType, value float64, labelVal
return prometheus.MustNewConstMetric(desc.toPrometheusDesc(), valueType.toPromValueType(), value, labelValues...)
}
// NewConstMetric is a helper of NewConstMetric.
//
// Note: If the metrics described by the desc is hidden, the metrics will not be created.
func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) {
if desc.IsHidden() {
return nil, nil
}
return prometheus.NewConstMetric(desc.toPrometheusDesc(), valueType.toPromValueType(), value, labelValues...)
}
// NewLazyMetricWithTimestamp is a helper of NewMetricWithTimestamp.
//
// Warning: the Metric 'm' must be the one created by NewLazyConstMetric(),

View File

@ -145,6 +145,12 @@ type Gatherer interface {
prometheus.Gatherer
}
// Registerer is the interface for the part of a registry in charge of registering
// the collected metrics.
type Registerer interface {
prometheus.Registerer
}
// GaugeFunc is a Gauge whose value is determined at collect time by calling a
// provided function.
//

92
vendor/k8s.io/component-base/tracing/tracing.go generated vendored Normal file
View File

@ -0,0 +1,92 @@
/*
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 tracing
import (
"context"
"time"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
utiltrace "k8s.io/utils/trace"
)
const instrumentationScope = "k8s.io/component-base/tracing"
// Start creates spans using both OpenTelemetry, and the k8s.io/utils/trace package.
// It only creates an OpenTelemetry span if the incoming context already includes a span.
func Start(ctx context.Context, name string, attributes ...attribute.KeyValue) (context.Context, *Span) {
// If the incoming context already includes an OpenTelemetry span, create a child span with the provided name and attributes.
// If the caller is not using OpenTelemetry, or has tracing disabled (e.g. with a component-specific feature flag), this is a noop.
ctx, otelSpan := trace.SpanFromContext(ctx).TracerProvider().Tracer(instrumentationScope).Start(ctx, name, trace.WithAttributes(attributes...))
// If there is already a utiltrace span in the context, use that as our parent span.
utilSpan := utiltrace.FromContext(ctx).Nest(name, attributesToFields(attributes)...)
// Set the trace as active in the context so that subsequent Start calls create nested spans.
return utiltrace.ContextWithTrace(ctx, utilSpan), &Span{
otelSpan: otelSpan,
utilSpan: utilSpan,
}
}
// Span is a component part of a trace. It represents a single named
// and timed operation of a workflow being observed.
// This Span is a combination of an OpenTelemetry and k8s.io/utils/trace span
// to facilitate the migration to OpenTelemetry.
type Span struct {
otelSpan trace.Span
utilSpan *utiltrace.Trace
}
// AddEvent adds a point-in-time event with a name and attributes.
func (s *Span) AddEvent(name string, attributes ...attribute.KeyValue) {
s.otelSpan.AddEvent(name, trace.WithAttributes(attributes...))
if s.utilSpan != nil {
s.utilSpan.Step(name, attributesToFields(attributes)...)
}
}
// End ends the span, and logs if the span duration is greater than the logThreshold.
func (s *Span) End(logThreshold time.Duration) {
s.otelSpan.End()
if s.utilSpan != nil {
s.utilSpan.LogIfLong(logThreshold)
}
}
func attributesToFields(attributes []attribute.KeyValue) []utiltrace.Field {
fields := make([]utiltrace.Field, len(attributes))
for i := range attributes {
attr := attributes[i]
fields[i] = utiltrace.Field{Key: string(attr.Key), Value: attr.Value.AsInterface()}
}
return fields
}
// SpanFromContext returns the *Span from the current context. It is composed of the active
// OpenTelemetry and k8s.io/utils/trace spans.
func SpanFromContext(ctx context.Context) *Span {
return &Span{
otelSpan: trace.SpanFromContext(ctx),
utilSpan: utiltrace.FromContext(ctx),
}
}
// ContextWithSpan returns a context with the Span included in the context.
func ContextWithSpan(ctx context.Context, s *Span) context.Context {
return trace.ContextWithSpan(utiltrace.ContextWithTrace(ctx, s.utilSpan), s.otelSpan)
}

View File

@ -21,8 +21,7 @@ import (
"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/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
@ -32,22 +31,39 @@ import (
"k8s.io/component-base/tracing/api/v1"
)
// TracerProvider is an OpenTelemetry TracerProvider which can be shut down
type TracerProvider interface {
oteltrace.TracerProvider
Shutdown(context.Context) error
}
type noopTracerProvider struct {
oteltrace.TracerProvider
}
func (n *noopTracerProvider) Shutdown(context.Context) error {
return nil
}
func NewNoopTracerProvider() TracerProvider {
return &noopTracerProvider{TracerProvider: oteltrace.NewNoopTracerProvider()}
}
// NewProvider creates a TracerProvider in a component, and enforces recommended tracing behavior
func NewProvider(ctx context.Context,
tracingConfig *v1.TracingConfiguration,
addedOpts []otlpgrpc.Option,
addedOpts []otlptracegrpc.Option,
resourceOpts []resource.Option,
) (oteltrace.TracerProvider, error) {
) (TracerProvider, error) {
if tracingConfig == nil {
return oteltrace.NewNoopTracerProvider(), nil
return NewNoopTracerProvider(), nil
}
opts := append([]otlpgrpc.Option{}, addedOpts...)
opts := append([]otlptracegrpc.Option{}, addedOpts...)
if tracingConfig.Endpoint != nil {
opts = append(opts, otlpgrpc.WithEndpoint(*tracingConfig.Endpoint))
opts = append(opts, otlptracegrpc.WithEndpoint(*tracingConfig.Endpoint))
}
opts = append(opts, otlpgrpc.WithInsecure())
driver := otlpgrpc.NewDriver(opts...)
exporter, err := otlp.NewExporter(ctx, driver)
opts = append(opts, otlptracegrpc.WithInsecure())
exporter, err := otlptracegrpc.New(ctx, opts...)
if err != nil {
return nil, err
}
@ -88,7 +104,7 @@ func WithTracing(handler http.Handler, tp oteltrace.TracerProvider, serviceName
// Example usage:
// tp := NewProvider(...)
// config, _ := rest.InClusterConfig()
// config.Wrap(WrapperFor(&tp))
// config.Wrap(WrapperFor(tp))
// kubeclient, _ := clientset.NewForConfig(config)
func WrapperFor(tp oteltrace.TracerProvider) transport.WrapperFunc {
return func(rt http.RoundTripper) http.RoundTripper {