Skip to content

Commit 25a4fc2

Browse files
committed
feat: expire stale advanced metrics after not being updated for some time
Signed-off-by: Matthew McKeen <[email protected]>
1 parent 18da0e9 commit 25a4fc2

22 files changed

+378
-58
lines changed

crd/api/v1alpha1/metricsconfiguration_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ type MetricsContextOptions struct {
4141
// +optional
4242
// +listType=set
4343
AdditionalLabels []string `json:"additionalLabels,omitempty"`
44+
// TTL represents the time-to-live of the metrics collected
45+
// Metrics which have not been updated within the TTL will be removed from export
46+
// +optional
47+
TTL string `json:"ttl,omitempty"`
4448
}
4549

4650
// MetricsNamespaces indicates the namespaces to include or exclude in metric collection

crd/api/v1alpha1/validations/validate_metricconfiguration.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package validations
77

88
import (
99
"fmt"
10+
"time"
1011

1112
"github.com/microsoft/retina/crd/api/v1alpha1"
1213
"github.com/microsoft/retina/pkg/utils"
@@ -40,6 +41,15 @@ func MetricsSpec(metricsSpec v1alpha1.MetricsSpec) error {
4041
if !utils.IsAdvancedMetric(contextOption.MetricName) {
4142
return fmt.Errorf("%s is not a valid metric", contextOption.MetricName)
4243
}
44+
if contextOption.TTL != "" {
45+
ttl, err := time.ParseDuration(contextOption.TTL)
46+
if err != nil {
47+
return fmt.Errorf("invalid TTL format for metric %s: %v", contextOption.MetricName, err)
48+
}
49+
if ttl < 0 {
50+
return fmt.Errorf("TTL cannot be negative for metric %s", contextOption.MetricName)
51+
}
52+
}
4353
}
4454

4555
err := MetricsNamespaces(metricsSpec.Namespaces)
@@ -152,10 +162,13 @@ func MetricsContextOptionsCompare(old, new []v1alpha1.MetricsContextOptions) boo
152162
return false
153163
}
154164

155-
if !utils.CompareStringSlice(oldContextOption.AdditionalLabels, newContextOption.AdditionalLabels) {
165+
if oldContextOption.TTL != newContextOption.TTL {
156166
return false
157167
}
158168

169+
if !utils.CompareStringSlice(oldContextOption.AdditionalLabels, newContextOption.AdditionalLabels) {
170+
return false
171+
}
159172
}
160173

161174
return true

crd/api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deploy/standard/manifests/controller/helm/retina/crds/retina.sh_captures.yaml

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
33
kind: CustomResourceDefinition
44
metadata:
55
annotations:
6-
controller-gen.kubebuilder.io/version: v0.15.0
6+
controller-gen.kubebuilder.io/version: v0.16.5
77
name: captures.retina.sh
88
spec:
99
group: retina.sh
@@ -53,6 +53,14 @@ spec:
5353
should continue for.
5454
pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
5555
type: string
56+
interfaces:
57+
description: |-
58+
Interfaces specifies the network interfaces on which to capture packets.
59+
If specified, captures only on the listed interfaces.
60+
If empty, captures on all interfaces by default.
61+
items:
62+
type: string
63+
type: array
5664
maxCaptureSize:
5765
default: 100
5866
description: MaxCaptureSize limits the capture file to MB
@@ -290,10 +298,14 @@ spec:
290298
description: SecretName is the name of secret which stores
291299
S3 compliant storage access key and secret key.
292300
type: string
301+
required:
302+
- bucket
303+
- secretName
293304
type: object
294305
type: object
295306
required:
296307
- captureConfiguration
308+
- outputConfiguration
297309
type: object
298310
status:
299311
description: CaptureStatus describes the status of the capture.
@@ -310,16 +322,8 @@ spec:
310322
type: string
311323
conditions:
312324
items:
313-
description: "Condition contains details for one aspect of the current
314-
state of this API Resource.\n---\nThis struct is intended for
315-
direct use as an array at the field path .status.conditions. For
316-
example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
317-
observations of a foo's current state.\n\t // Known .status.conditions.type
318-
are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
319-
+patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
320-
\ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
321-
patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
322-
\ // other fields\n\t}"
325+
description: Condition contains details for one aspect of the current
326+
state of this API Resource.
323327
properties:
324328
lastTransitionTime:
325329
description: |-
@@ -360,12 +364,7 @@ spec:
360364
- Unknown
361365
type: string
362366
type:
363-
description: |-
364-
type of condition in CamelCase or in foo.example.com/CamelCase.
365-
---
366-
Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
367-
useful (see .node.status.conditions), the ability to deconflict is important.
368-
The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
367+
description: type of condition in CamelCase or in foo.example.com/CamelCase.
369368
maxLength: 316
370369
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
371370
type: string

deploy/standard/manifests/controller/helm/retina/crds/retina.sh_metricsconfigurations.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
33
kind: CustomResourceDefinition
44
metadata:
55
annotations:
6-
controller-gen.kubebuilder.io/version: v0.15.0
6+
controller-gen.kubebuilder.io/version: v0.16.5
77
name: metricsconfigurations.retina.sh
88
spec:
99
group: retina.sh
@@ -75,6 +75,11 @@ spec:
7575
type: string
7676
type: array
7777
x-kubernetes-list-type: set
78+
ttl:
79+
description: |-
80+
TTL represents the time-to-live of the metrics collected
81+
Metrics which have not been updated within the TTL will be removed from export
82+
type: string
7883
required:
7984
- metricName
8085
type: object
@@ -136,6 +141,11 @@ spec:
136141
type: string
137142
type: array
138143
x-kubernetes-list-type: set
144+
ttl:
145+
description: |-
146+
TTL represents the time-to-live of the metrics collected
147+
Metrics which have not been updated within the TTL will be removed from export
148+
type: string
139149
required:
140150
- metricName
141151
type: object

deploy/standard/manifests/controller/helm/retina/crds/retina.sh_retinaendpoints.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
33
kind: CustomResourceDefinition
44
metadata:
55
annotations:
6-
controller-gen.kubebuilder.io/version: v0.15.0
6+
controller-gen.kubebuilder.io/version: v0.16.5
77
name: retinaendpoints.retina.sh
88
spec:
99
group: retina.sh

deploy/standard/manifests/controller/helm/retina/crds/retina.sh_tracesconfigurations.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
33
kind: CustomResourceDefinition
44
metadata:
55
annotations:
6-
controller-gen.kubebuilder.io/version: v0.15.0
6+
controller-gen.kubebuilder.io/version: v0.16.5
77
name: tracesconfigurations.retina.sh
88
spec:
99
group: retina.sh

pkg/metrics/interfaces.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@ import (
99

1010
//go:generate go run go.uber.org/mock/[email protected] -source=interfaces.go -destination=mock_types.go -package=metrics
1111

12+
type MetricVec interface {
13+
DeleteLabelValues(lvs ...string) bool
14+
}
15+
1216
type CounterVec interface {
17+
MetricVec
1318
WithLabelValues(lvs ...string) prometheus.Counter
1419
GetMetricWithLabelValues(lvs ...string) (prometheus.Counter, error)
1520
}
1621

1722
type GaugeVec interface {
23+
MetricVec
1824
WithLabelValues(lvs ...string) prometheus.Gauge
1925
GetMetricWithLabelValues(lvs ...string) (prometheus.Gauge, error)
2026
}

pkg/metrics/metrics.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,13 @@ func InitializeMetrics() {
194194
parsedPacketsCounterDescription,
195195
)
196196

197+
MetricsExpiredCounter = exporter.CreatePrometheusCounterVecForControlPlaneMetric(
198+
exporter.DefaultRegistry,
199+
expiredMetricsCounterName,
200+
expiredMetricsCounterDescription,
201+
utils.Metric,
202+
)
203+
197204
isInitialized = true
198205
metricsLogger.Info("Metrics initialized")
199206
}

pkg/metrics/mock_types.go

Lines changed: 77 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)