mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Merge pull request #113014 from logicalhan/stability-v2
add support for parsing gauge func
This commit is contained in:
commit
c8c955c4cb
@ -24,6 +24,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"k8s.io/component-base/metrics"
|
"k8s.io/component-base/metrics"
|
||||||
)
|
)
|
||||||
@ -70,7 +71,7 @@ func (c *metricDecoder) decodeNewMetricCall(fc *ast.CallExpr) (*metric, error) {
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
switch functionName {
|
switch functionName {
|
||||||
case "NewCounter", "NewGauge", "NewHistogram", "NewSummary", "NewTimingHistogram":
|
case "NewCounter", "NewGauge", "NewHistogram", "NewSummary", "NewTimingHistogram", "NewGaugeFunc":
|
||||||
m, err = c.decodeMetric(fc)
|
m, err = c.decodeMetric(fc)
|
||||||
case "NewCounterVec", "NewGaugeVec", "NewHistogramVec", "NewSummaryVec", "NewTimingHistogramVec":
|
case "NewCounterVec", "NewGaugeVec", "NewHistogramVec", "NewSummaryVec", "NewTimingHistogramVec":
|
||||||
m, err = c.decodeMetricVec(fc)
|
m, err = c.decodeMetricVec(fc)
|
||||||
@ -90,7 +91,7 @@ func getMetricType(functionName string) string {
|
|||||||
switch functionName {
|
switch functionName {
|
||||||
case "NewCounter", "NewCounterVec":
|
case "NewCounter", "NewCounterVec":
|
||||||
return counterMetricType
|
return counterMetricType
|
||||||
case "NewGauge", "NewGaugeVec":
|
case "NewGauge", "NewGaugeVec", "NewGaugeFunc":
|
||||||
return gaugeMetricType
|
return gaugeMetricType
|
||||||
case "NewHistogram", "NewHistogramVec":
|
case "NewHistogram", "NewHistogramVec":
|
||||||
return histogramMetricType
|
return histogramMetricType
|
||||||
@ -104,7 +105,7 @@ func getMetricType(functionName string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *metricDecoder) decodeMetric(call *ast.CallExpr) (metric, error) {
|
func (c *metricDecoder) decodeMetric(call *ast.CallExpr) (metric, error) {
|
||||||
if len(call.Args) != 1 {
|
if len(call.Args) > 2 {
|
||||||
return metric{}, newDecodeErrorf(call, errInvalidNewMetricCall)
|
return metric{}, newDecodeErrorf(call, errInvalidNewMetricCall)
|
||||||
}
|
}
|
||||||
return c.decodeOpts(call.Args[0])
|
return c.decodeOpts(call.Args[0])
|
||||||
@ -326,7 +327,6 @@ func (c *metricDecoder) decodeOpts(expr ast.Expr) (metric, error) {
|
|||||||
case "MaxAge":
|
case "MaxAge":
|
||||||
int64Val, err := c.decodeInt64(kv.Value)
|
int64Val, err := c.decodeInt64(kv.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
print(key)
|
|
||||||
return m, err
|
return m, err
|
||||||
}
|
}
|
||||||
m.MaxAge = int64Val
|
m.MaxAge = int64Val
|
||||||
@ -462,16 +462,64 @@ func (c *metricDecoder) decodeInt64(expr ast.Expr) (int64, error) {
|
|||||||
return 1000 * 1000 * 1000 * 60 * 10, nil
|
return 1000 * 1000 * 1000 * 60 * 10, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case *ast.Ident:
|
||||||
|
variableExpr, found := c.variables[v.Name]
|
||||||
|
if found {
|
||||||
|
be, ok := variableExpr.(*ast.BinaryExpr)
|
||||||
|
if ok {
|
||||||
|
i, err2, done := c.extractTimeExpression(be)
|
||||||
|
if done {
|
||||||
|
return i, err2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
case *ast.CallExpr:
|
case *ast.CallExpr:
|
||||||
_, ok := v.Fun.(*ast.SelectorExpr)
|
_, ok := v.Fun.(*ast.SelectorExpr)
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, newDecodeErrorf(v, errDecodeInt64)
|
return 0, newDecodeErrorf(v, errDecodeInt64)
|
||||||
}
|
}
|
||||||
return 0, nil
|
return 0, nil
|
||||||
|
case *ast.BinaryExpr:
|
||||||
|
i, err2, done := c.extractTimeExpression(v)
|
||||||
|
if done {
|
||||||
|
return i, err2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0, newDecodeErrorf(expr, errDecodeInt64)
|
return 0, newDecodeErrorf(expr, errDecodeInt64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *metricDecoder) extractTimeExpression(v *ast.BinaryExpr) (int64, error, bool) {
|
||||||
|
x := v.X.(*ast.BasicLit)
|
||||||
|
if x.Kind != token.FLOAT && x.Kind != token.INT {
|
||||||
|
print(x.Kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
xValue, err := strconv.ParseInt(x.Value, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err, true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch y := v.Y.(type) {
|
||||||
|
case *ast.SelectorExpr:
|
||||||
|
variableName := y.Sel.String()
|
||||||
|
importName, ok := y.X.(*ast.Ident)
|
||||||
|
if ok && importName.String() == "time" {
|
||||||
|
if variableName == "Hour" {
|
||||||
|
return xValue * int64(time.Hour), nil, true
|
||||||
|
}
|
||||||
|
if variableName == "Minute" {
|
||||||
|
return xValue * int64(time.Minute), nil, true
|
||||||
|
}
|
||||||
|
if variableName == "Second" {
|
||||||
|
return xValue * int64(time.Second), nil, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, nil, false
|
||||||
|
}
|
||||||
|
|
||||||
func decodeFloatMap(exprs []ast.Expr) (map[float64]float64, error) {
|
func decodeFloatMap(exprs []ast.Expr) (map[float64]float64, error) {
|
||||||
buckets := map[float64]float64{}
|
buckets := map[float64]float64{}
|
||||||
for _, elt := range exprs {
|
for _, elt := range exprs {
|
||||||
|
@ -29,6 +29,7 @@ var metricsOptionStructuresNames = []string{
|
|||||||
"GaugeOpts",
|
"GaugeOpts",
|
||||||
"HistogramOpts",
|
"HistogramOpts",
|
||||||
"SummaryOpts",
|
"SummaryOpts",
|
||||||
|
"TimingHistogramOpts",
|
||||||
}
|
}
|
||||||
|
|
||||||
func findStableMetricDeclaration(tree ast.Node, metricsImportName string) ([]*ast.CallExpr, []error) {
|
func findStableMetricDeclaration(tree ast.Node, metricsImportName string) ([]*ast.CallExpr, []error) {
|
||||||
@ -98,7 +99,7 @@ func (f *stableMetricFinder) Visit(node ast.Node) (w ast.Visitor) {
|
|||||||
func isMetricOps(name string) bool {
|
func isMetricOps(name string) bool {
|
||||||
var found = false
|
var found = false
|
||||||
for _, optsName := range metricsOptionStructuresNames {
|
for _, optsName := range metricsOptionStructuresNames {
|
||||||
if name != optsName {
|
if name == optsName {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,8 @@ var (
|
|||||||
defObjectives = map[float64]float64{0.5: 0.5, 0.75: 0.75}
|
defObjectives = map[float64]float64{0.5: 0.5, 0.75: 0.75}
|
||||||
testBuckets = []float64{0, 0.5, 1.0}
|
testBuckets = []float64{0, 0.5, 1.0}
|
||||||
testLabels = []string{"a", "b", "c"}
|
testLabels = []string{"a", "b", "c"}
|
||||||
|
maxAge = 2 * time.Minute
|
||||||
|
|
||||||
// NodeName is a Gauge that tracks the ode's name. The count is always 1.
|
// NodeName is a Gauge that tracks the ode's name. The count is always 1.
|
||||||
NodeName = metrics.NewGaugeVec(
|
NodeName = metrics.NewGaugeVec(
|
||||||
&metrics.GaugeOpts{
|
&metrics.GaugeOpts{
|
||||||
@ -109,6 +111,29 @@ var (
|
|||||||
},
|
},
|
||||||
testLabels,
|
testLabels,
|
||||||
)
|
)
|
||||||
|
// PodWorkerDuration is a Histogram that tracks the duration (in seconds) in takes to sync a single pod.
|
||||||
|
// Broken down by the operation type.
|
||||||
|
SummaryMaxAge = metrics.NewSummary(
|
||||||
|
&metrics.SummaryOpts{
|
||||||
|
Subsystem: KubeletSubsystem,
|
||||||
|
Name: "max_age",
|
||||||
|
Help: "Duration in seconds to sync a single pod. Broken down by operation type: create, update, or sync",
|
||||||
|
StabilityLevel: metrics.BETA,
|
||||||
|
MaxAge: 2 * time.Hour,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// PodWorkerDuration is a Histogram that tracks the duration (in seconds) in takes to sync a single pod.
|
||||||
|
// Broken down by the operation type.
|
||||||
|
SummaryMaxAgeConst = metrics.NewSummary(
|
||||||
|
&metrics.SummaryOpts{
|
||||||
|
Subsystem: KubeletSubsystem,
|
||||||
|
Name: "max_age_const",
|
||||||
|
Help: "Duration in seconds to sync a single pod. Broken down by operation type: create, update, or sync",
|
||||||
|
StabilityLevel: metrics.BETA,
|
||||||
|
MaxAge: maxAge,
|
||||||
|
},
|
||||||
|
)
|
||||||
// PodStartDuration is a Histogram that tracks the duration (in seconds) it takes for a single pod to go from pending to running.
|
// PodStartDuration is a Histogram that tracks the duration (in seconds) it takes for a single pod to go from pending to running.
|
||||||
PodStartDuration = metrics.NewHistogram(
|
PodStartDuration = metrics.NewHistogram(
|
||||||
&metrics.HistogramOpts{
|
&metrics.HistogramOpts{
|
||||||
@ -481,6 +506,26 @@ func Register(collectors ...metrics.StableCollector) {
|
|||||||
for _, collector := range collectors {
|
for _, collector := range collectors {
|
||||||
legacyregistry.CustomMustRegister(collector)
|
legacyregistry.CustomMustRegister(collector)
|
||||||
}
|
}
|
||||||
|
legacyregistry.RawMustRegister(metrics.NewGaugeFunc(
|
||||||
|
&metrics.GaugeOpts{
|
||||||
|
Subsystem: "kubelet",
|
||||||
|
Name: "certificate_manager_client_ttl_seconds",
|
||||||
|
Help: "Gauge of the TTL (time-to-live) of the Kubelet's client certificate. " +
|
||||||
|
"The value is in seconds until certificate expiry (negative if already expired). " +
|
||||||
|
"If client certificate is invalid or unused, the value will be +INF.",
|
||||||
|
StabilityLevel: metrics.BETA,
|
||||||
|
},
|
||||||
|
func() float64 {
|
||||||
|
return 0
|
||||||
|
},
|
||||||
|
))
|
||||||
|
_ = metrics.Labels{
|
||||||
|
"probe_type": "1",
|
||||||
|
"container": "2",
|
||||||
|
"pod": "podName",
|
||||||
|
"namespace": "space",
|
||||||
|
"pod_uid": "123",
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
- name: certificate_manager_client_ttl_seconds
|
||||||
|
subsystem: kubelet
|
||||||
|
help: Gauge of the TTL (time-to-live) of the Kubelet's client certificate. The value
|
||||||
|
is in seconds until certificate expiry (negative if already expired). If client
|
||||||
|
certificate is invalid or unused, the value will be +INF.
|
||||||
|
type: Gauge
|
||||||
|
stabilityLevel: BETA
|
||||||
- name: device_plugin_alloc_duration_seconds
|
- name: device_plugin_alloc_duration_seconds
|
||||||
subsystem: kubelet
|
subsystem: kubelet
|
||||||
help: Duration in seconds to serve a device plugin Allocation request. Broken down
|
help: Duration in seconds to serve a device plugin Allocation request. Broken down
|
||||||
@ -18,6 +25,20 @@
|
|||||||
- 2.5
|
- 2.5
|
||||||
- 5
|
- 5
|
||||||
- 10
|
- 10
|
||||||
|
- name: max_age
|
||||||
|
subsystem: kubelet
|
||||||
|
help: 'Duration in seconds to sync a single pod. Broken down by operation type:
|
||||||
|
create, update, or sync'
|
||||||
|
type: Summary
|
||||||
|
stabilityLevel: BETA
|
||||||
|
maxAge: 7200000000000
|
||||||
|
- name: max_age_const
|
||||||
|
subsystem: kubelet
|
||||||
|
help: 'Duration in seconds to sync a single pod. Broken down by operation type:
|
||||||
|
create, update, or sync'
|
||||||
|
type: Summary
|
||||||
|
stabilityLevel: BETA
|
||||||
|
maxAge: 120000000000
|
||||||
- name: multiline
|
- name: multiline
|
||||||
subsystem: kubelet
|
subsystem: kubelet
|
||||||
help: Cumulative number of pod preemptions by preemption resource asdf asdf asdf
|
help: Cumulative number of pod preemptions by preemption resource asdf asdf asdf
|
||||||
|
Loading…
Reference in New Issue
Block a user